💻

Power Pages で挿入フォームと編集フォームを動的に切り替える

2023/03/23に公開
2

はじめに

Power Pages で親テーブルに対して 1 対 1 のリレーションをしたい場合があります。たとえばログイン ユーザーに対して複数のデータを登録させたくないなどのシナリオが該当します。この場合は、データがなければ挿入フォームを表示し、データがあれば編集フォームを表示する、という方法で実現できるように思えるのですが、ノーコードでは設定できず、カスタマイズで実現することになります。

実装方法

ログイン ユーザー (取引先担当者) に 1 対 1 で紐づく取引先担当者プロフィールという自己紹介列を含むテーブルを作成し、ログイン ユーザーが自己紹介を記入できるように、動的に挿入フォームと編集フォームを切り替えるようにしたいと思います。

Dataverse

テーブル

取引先担当者の子テーブルとなる 取引先担当者プロフィール を作成します。

自己紹介 列を追加します。

取引先担当者 列を追加します。これは取引先担当者とリレーションを設定します。

フォーム

Power Pages で表示するためのフォームを追加します。

Power Pages

挿入フォーム

挿入フォームを作成します。

保存時にログイン ユーザーと関連付けをするように設定します。

編集フォーム

編集フォームを作成します。クエリ文字列として id を受け取るようにします。

テーブルのアクセス許可

取引先担当者プロフィール に対するアクセス許可を追加します。アクセス許可の種類 を「取引先担当者アクセス」に設定します。これによって自分のレコードのみ参照できるようになります。

ページ

適当なページ (今回は ホーム を編集します) を選択し コードの編集 をクリックします。Visual Studio Code で HTML ファイルを選択します。

{% assign id = request.params["id"] %}
{% if id.size > 0 %}
  {% if id == "00000000-0000-0000-0000-000000000000" %}
    <div class="row sectionBlockLayout text-left" style="display: flex; flex-wrap: wrap; margin: 0px; min-height: auto; padding: 8px;">
      <div class="container" style="padding: 0px; display: flex; flex-wrap: wrap;">
        <div class="col-md-12 columnBlockLayout" style="flex-grow: 1; display: flex; flex-direction: column; min-width: 300px;">
          {% entityform name: '取引先担当者のプロフィール挿入フォーム' %}
        </div>
      </div>
    </div>
  {% else %}
    <div class="row sectionBlockLayout text-left" style="display: flex; flex-wrap: wrap; margin: 0px; min-height: auto; padding: 8px;">
      <div class="container" style="padding: 0px; display: flex; flex-wrap: wrap;">
        <div class="col-md-12 columnBlockLayout" style="flex-grow: 1; display: flex; flex-direction: column; min-width: 300px;">
          {% entityform name: '取引先担当者のプロフィール編集フォーム' %}
        </div>
      </div>
    </div>
  {% endif %}
{% else %}
  {% fetchxml query %}
    <fetch mapping="logical">
      <entity name="cr818_contactprofile">
        <attribute name="cr818_contactprofileid"></attribute>
        <link-entity name="contact" to="cr818_contact">
          <filter type="and">
            <condition attribute="contactid" operator="eq" value="{{ user.id }}"></condition>
          </filter>
        </link-entity>
      </entity>
    </fetch>
  {% endfetchxml %}
  {% if query.results.entities.size > 0 %}
    {% assign result = query.results.entities[0] %}
      <script type="text/javascript">
        window.location = window.location + "?id={{ result.cr818_contactprofileid }}";
      </script>
  {% else %}
      <script type="text/javascript">
        window.location = window.location + "?id=00000000-0000-0000-0000-000000000000";
      </script>
  {% endif %}
{% endif %}

やっているのは以下のような感じです。

  • id パラメーターがない場合、FetchXML を使用して現在のログイン ユーザーに紐づけられているレコードを取得します。ある場合はその ID を、ない場合は 00000000-0000-0000-0000-000000000000 を指定してリダイレクトします。
  • id パラメーターがある場合、00000000-0000-0000-0000-000000000000 であれば挿入フォームを、それ以外は編集フォームを表示します。

実行結果

データがない状態で表示したときは id=00000000-0000-0000-0000-000000000000 にリダイレクトされ挿入フォームが表示されます。

この状態で保存し再度表示すると id={{contact-profile-id}} にリダイレクトされ保存した値が表示され編集することができます。

おわりに

Liquid テンプレートの entityform が ID を受け取れれば困らないのですがクエリ文字列しか受け取る方法しかないようなのでこんな実装になりました。 もちろん entityform を使わないという方法もありますし、Liquid テンプレートではなく Web API でやるという方法もあります。開発者のスキルにしたがって簡単に実装できる方法を選択していただければと思います。

Discussion

NaNokaNaNoka

フォームの切り替えはできませんが、以下の設定でクエリパラメータを使わずにログインユーザが関連付けられたレコードを特定し表示することができるかもしれません。
関連付け名には、挿入時にログインユーザを関連付けた列を指定しています。

karamem0karamem0

コメントありがとうございます。参考になります。その方法だと Power Automate などと連携して空のデータを作ってあげればフォームの切り替えをしなくてもよくなりそうですね。