Power Pages クライアント API の例

この記事の例では、Power Pages クライアント API を組み合わせて、フォームとリストに一般的なシナリオを実装する方法を示します。 各例は完全なので、JavaScript Web ファイルまたはページの カスタム JavaScript セクションにコピーし、サイトに合わせてフォーム名、列名、テーブル名を変更できます。

すべての例では、 クライアント API の初期化で説明されているコールバック パターンを使用します。これにより、コードを実行する前にクライアント API の準備が完了することが保証されます。 コールバックは、awaitを使用できるように、asyncで宣言されます。 独自のコードでawaitを使用しない場合は、async キーワードを省略します。

例 Description
Dataverse レコードからモーダル参照値を設定する Dataverse レコードを取得し、それを使用してモーダル参照コントロールを設定します。
ルックアップがドロップダウン リストとして表示されるときにルックアップ値を設定する コントロールがドロップダウン リストまたはモーダル参照としてレンダリングされるかどうかに基づいて、参照値を設定します。
複数選択列の値を読み取って設定する 選択した選択肢を読み取り、既存の選択を削除せずにオプションを追加します。
サーバーで読み取り専用または非表示のコントロールを操作する コントロールの動作を変更する前に、コントロールの可用性と読み取り専用の状態を確認します。
別の列の値に基づいて列を必須にする 別のコントロールの値に基づいて、条件付き要件とカスタム検証を適用します。
リスト内の列の表示と非表示を切り替える 最新のリスト列を非表示にし、別の列の見出しとヒントをカスタマイズします。
リスト内のレコードを表示または非表示にする 非アクティブな行を非表示にし、現在のユーザーが編集できないレコードを視覚的に区別します。

Dataverse レコードからモーダル参照値を設定する

次の使用例は、 Web API を使用してアカウント レコードを取得し、それを使用してフォームに モーダル検索 を設定します。 モーダル検索には、ID、名前、および関連レコードのテーブル名を含むオブジェクトが必要です。

Microsoft.PowerPages.onPagesClientApiReady(async function ($pages) {
    // 1. Retrieve the first account record.
    //    $top=1 returns a single record, and $select limits the payload to the
    //    columns that the lookup control needs.
    const queryOptions = '$select=accountid,name&$top=1';
    const response = await $pages.webAPI.retrieveMultipleRecords('accounts', queryOptions);
    const records = response.value;

    if (!records || records.length === 0) {
        console.warn('No account records were returned from Dataverse.');
        return;
    }

    const firstAccount = records[0];
    console.log(`Retrieved account: ${firstAccount.name}`);

    // 2. Get the form. Use the name or the ID of your basic or multistep form.
    const form = $pages.currentPage.forms.getFormByName('Profile Web Form (Enhanced)');

    if (!form) {
        console.error('The target form was not found on the page.');
        return;
    }

    // 3. Get the lookup control by its logical name.
    const lookupControl = form.getControlByLogicalName('new_managingpartnerid');

    if (!lookupControl) {
        console.error('The lookup control was not found on the form.');
        return;
    }

    // 4. Set the lookup value. A modal lookup expects an object that contains
    //    the id, name, and entityType values.
    lookupControl.setValue({
        id: firstAccount.accountid,
        name: firstAccount.name,
        entityType: 'account'
    });

    console.log('The lookup control is populated.');
});

Tip

論理名がわからない場合にコントロールを検索するには、form.controls.find(control => control.getName() === 'Managing Partner')のように、form.controlsを列挙し、getName メソッドを使用します。

ルックアップがドロップダウン リストとして表示されるときにルックアップ値を設定する

ルックアップ列は、フォームの構成方法に応じて、モーダル ダイアログまたはドロップダウン リストとして表示されます。 2 つのコントロールは、 setValue メソッドで異なる値を受け入れるので、値を設定する前に isDropdown プロパティを確認してください。 ドロップダウン検索では、選択するオプションの ID が必要であり、モーダル検索ではオブジェクトが必要です。

重要

ドロップダウン検索には、構成されたビューとフィルターが返すレコードのみが含まれます。 ドロップダウン リストで使用できるレコードの ID に値を設定します。 この例では、検索が提供するレコードのみを返すようにクエリをフィルター処理します。

Microsoft.PowerPages.onPagesClientApiReady(async function ($pages) {
    const form = $pages.currentPage.forms.getFormByName('Profile Web Form (Enhanced)');
    const lookupControl = form && form.getControlByLogicalName('new_managingpartnerid');

    if (!lookupControl) {
        console.error('The lookup control was not found on the form.');
        return;
    }

    const response = await $pages.webAPI.retrieveMultipleRecords('accounts', '$select=accountid,name&$top=1');
    const records = response.value;

    if (!records || records.length === 0) {
        return;
    }

    const account = records[0];

    if (lookupControl.isDropdown) {
        // A dropdown lookup expects the ID of the option to select.
        lookupControl.setValue(account.accountid);

        // getValue returns an object that contains the id and name of the selected option.
        const selected = lookupControl.getValue();
        console.log(`Selected option: ${selected && selected.name}`);
    } else {
        // A modal lookup expects an object.
        lookupControl.setValue({
            id: account.accountid,
            name: account.name,
            entityType: 'account'
        });
    }
});

複数選択列の値を読み取って設定する

複数選択候補リスト コントロールには、数値の配列が格納されます。 次の使用例は、既に選択されているオプションを削除せずに、現在の選択範囲にオプションを追加します。

Microsoft.PowerPages.onPagesClientApiReady(async function ($pages) {
    const form = $pages.currentPage.forms.getFormByName('Profile Web Form (Enhanced)');
    const control = form && form.getControlByLogicalName('new_areasofinterest');

    if (!control || control.getType() !== 'MultiSelectPicklist') {
        return;
    }

    // 1. Read the options that are currently selected.
    const selectedValues = control.getValue() || [];
    console.log(`Selected options: ${selectedValues.join(', ')}`);

    // 2. Add an option only when it isn't selected yet.
    //    setValue throws an error when a value isn't one of the available options.
    const newsletterOption = 740740002;

    if (!selectedValues.includes(newsletterOption)) {
        control.setValue([...selectedValues, newsletterOption]);
    }

    // 3. Clear the selection.
    // control.setValue([]);
});

サーバーで読み取り専用または非表示のコントロールを操作する

Power Pagesは、サーバーにフォーム メタデータとテーブルのアクセス許可を適用します。クライアント API はこれらの設定をオーバーライドできません。 コントロールが存在するかどうか、およびコントロールを変更する前に読み取り専用かどうかを確認する防御コードを記述します。

次の動作が適用されます。

  • フォーム上にない列、または他のユーザーが読み取りアクセス許可を持っていない列はレンダリングされません。 getControlByLogicalName メソッドはその列のundefinedを返します。そのため、使用する前に結果を確認してください。
  • 読み取り専用フォームまたはフィールドの 複数選択リスト など、サーバー上でコントロールがロックされている場合、 setDisabled(false) メソッドは無効です。
  • setRequired(false) メソッドでは、サーバーで列が必要な場合は、列を省略可能にすることはできません。
  • setVisible(false) メソッドは、ブラウザーでのみコントロールを非表示にします。 テーブルのアクセス許可と列のセキュリティを使用してデータを保護します。 データをセキュリティで保護するためにコントロールを非表示にしないでください。
Microsoft.PowerPages.onPagesClientApiReady(async function ($pages) {
    const form = $pages.currentPage.forms.getFormByName('Profile Web Form (Enhanced)');

    if (!form) {
        return;
    }

    const creditLimit = form.getControlByLogicalName('creditlimit');

    // The column isn't on the form, or the user can't read it.
    if (!creditLimit) {
        console.log('The credit limit column is not available to this user.');
        return;
    }

    // A control that's locked on the server stays disabled, even after
    // you call setDisabled(false).
    creditLimit.setDisabled(false);

    if (creditLimit.getDisabled()) {
        console.log('The credit limit column is locked on the server.');
    }

    // Hide the control in the browser. This changes only what people see.
    // Use table permissions and column security to protect the data.
    const internalNotes = form.getControlByLogicalName('new_internalnotes');

    if (internalNotes) {
        internalNotes.setVisible(false);
    }
});

別の列の値に基づいて列を必須にする

次の使用例は、他のユーザーが別の列で特定のオプションを選択した場合にのみ列を必須にし、フォームの送信時に実行されるカスタム検証コントロールを追加します。 詳細については、「 addValidator メソッドのパラメーター」を参照してください。

Microsoft.PowerPages.onPagesClientApiReady(async function ($pages) {
    const form = $pages.currentPage.forms.getFormByName('Profile Web Form (Enhanced)');

    if (!form) {
        return;
    }

    const contactMethod = form.getControlByLogicalName('preferredcontactmethodcode');
    const mobilePhone = form.getControlByLogicalName('mobilephone');

    if (!contactMethod || !mobilePhone) {
        return;
    }

    const applyRules = () => {
        // Option 3 is Phone in this example.
        const requiresPhone = contactMethod.getValue() === '3';

        // Make the column required and provide a localized message.
        mobilePhone.setRequired(requiresPhone, 'Enter a mobile phone number.');

        if (requiresPhone) {
            // Add a format check that runs when the form is submitted.
            // Reusing the same ID replaces the earlier validator instead of adding another one.
            mobilePhone.addValidator(
                'mobilePhoneFormat',
                (value) => /^(?=.*\d)[0-9\s+()-]{7,20}$/.test((value || '').trim()),
                'Enter a valid mobile phone number.'
            );
        } else {
            mobilePhone.removeValidator('mobilePhoneFormat');
        }
    };

    // Apply the rules when the page loads and whenever a value on the form changes.
    applyRules();
    form.getHtmlElement().addEventListener('change', applyRules);
});

Note

setRequired(false)を呼び出しても、サーバーで必要な列は必須のままです。

リスト内の列の表示と非表示を切り替える

次の使用例は、モダン リストの列を非表示にし、別の列の名前を変更します。 loaded イベント ハンドラーでリスト データを読み取ります。これは、リストの更新、並べ替え、フィルター、またはページ データのたびにイベントが再び発生するためです。 詳細については、「 イベントの一覧表示」を参照してください。

Microsoft.PowerPages.onPagesClientApiReady(async function ($pages) {
    const list = $pages.currentPage.lists.getListById('list_#1');

    if (!list || !list.isModern) {
        return;
    }

    list.on('loaded', () => {
        // Hide a column that people don't need to see.
        const createdOn = list.getColumn('createdon');

        if (createdOn) {
            createdOn.setVisible(false);
        }

        // Rename a column and add a tooltip that screen readers use as the
        // accessible name of the header. Read the configured display name, and
        // then derive the header so that the code produces the same result
        // each time the event occurs.
        const name = list.getColumn('name');

        if (name) {
            name.setHeader(`${name.getDisplayName()} (primary)`);
            name.setTooltip('The primary name of the account.');
        }
    });
});

リスト内のレコードを表示または非表示にする

次の使用例は、非アクティブなレコードを非表示にし、編集できないレコードを強調表示します。 行を非表示にすると、リストに表示される内容のみが変更されます。サーバーから返されるデータやレコードの数は変更されません。

Microsoft.PowerPages.onPagesClientApiReady(async function ($pages) {
    const list = $pages.currentPage.lists.getListById('list_#1');

    if (!list || !list.isModern) {
        return;
    }

    list.on('loaded', () => {
        list.rows.forEach((row) => {
            const state = row.getState();

            // Hide inactive records, where statecode is 1.
            if (state && state.stateCode === 1) {
                row.setVisible(false);
                return;
            }

            // Highlight the records that this user can't edit.
            const privileges = row.getPrivileges();

            if (privileges && !privileges.canWrite) {
                row.addClassName('read-only-row');

                const nameCell = row.getCell('name');

                if (nameCell) {
                    nameCell.setStyle({ fontStyle: 'italic' });
                }
            }
        });
    });
});

重要

getPrivileges メソッドが返す値を使用して、データの表示方法を変更します。 セキュリティを適用するために使用しないでください。 Power Pagesは、サーバーにテーブルのアクセス許可を適用します。