Power Pages で挿入フォームと編集フォームを動的に切り替える
はじめに
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
フォームの切り替えはできませんが、以下の設定でクエリパラメータを使わずにログインユーザが関連付けられたレコードを特定し表示することができるかもしれません。
関連付け名には、挿入時にログインユーザを関連付けた列を指定しています。
コメントありがとうございます。参考になります。その方法だと Power Automate などと連携して空のデータを作ってあげればフォームの切り替えをしなくてもよくなりそうですね。