はじめに
まずはこちらをご覧ください!
できたー
— コルネ (@koruneko32767) August 9, 2020
動的に増え(ているようにみせかけてい)るアダプティブカード!
JSON の作成がただただめんどくさかったぜ#AdaptiveCards pic.twitter.com/tQAa8ohpWa
なんと送信されたアダプティブカードの入力項目をユーザー操作によって動的に増やすことができました!
今回はこのようなオブジェクトを動的に増やすことができるアダプティブカードの作成方法を紹介したいと思います。
ネタばらし
早速ですがネタばらしです。
先ほど紹介したアダプティブカードですが、あくまで動的に項目が増えているようにみせかけているだけです。
下の画像のように予め項目を作成しておき、初期表示時は非表示に設定し、ボタンが押されると表示/非表示が切り替わるように設定しています。
これを実現している機能は「ToggleVisibility」というアクションです。
ToggleVisibility
ToggleVisibility の基本的な利用方法の紹介は、Hiro さんがAdaptive Cards のアクション [ToggleVisibility] と [ShowCard] を使ってみよう - ToggleVisiblity 編でわかりやすく解説してくれています。
ToggleVisibility を利用することにより、対象のオブジェクト表示/非表示を切り替えることができます。
Adaptive Cards Designer 上で「ActionSet」>「Action.ToggleVisibility」を選択することで利用が可能です。
Action.ToggleVisibility のリファレンスをみてみると、このボタンが押されたときに表示/非表示が切り替わる項目は、「targetElements」にて対象の項目のID を指定する必要があるようです。
「ActionSet」及び「Action.ToggleVisibility」のプロパティをみてみましょう。
こちらをみてわかる通り、プロパティペインには「targetElements」を設定する箇所は存在しません。。。
では次にCARD PAYLOAD EDITOR より作成されたJSON をみてみましょう。
{ "type": "ActionSet", "actions": [ { "type": "Action.ToggleVisibility", "title": "Target1" } ], "id": "target1" }
こちらをみても「targetElements」は存在しませんね...
ということで、直接CARD PAYLOAD EDITOR を編集して、「targetElements」を指定します。
以下のようなカードを作成してみます。
それぞれのオブジェクトのID は以下のように設定しました。
Item | ID |
---|---|
Column(上) | col1 |
Text1 | text1 |
Input.Text(上) | textInput1 |
Column(下) | col2 |
Text2 | text2 |
Input.Text(下) | textInput2 |
Target1 | target1 |
Target2 | target2 |
作成が完了できたら、「Action.ToggleVisibility」のJSON を変更してみましょう。
「Action.ToggleVisibility」の要素に「targetElements」を作成します。
{ "type": "ActionSet", "actions": [ { "type": "Action.ToggleVisibility", "title": "Target1", "targetElements":[ "col1" ] } ], "id": "target1" }
上で記載したJSON と比較してわかるかもですが、
"targetElements":[ "col1" ]
という設定を追記しています。
Hiro さんのブログでは、「targetElements」に表示/非表示を行いたい要素をひとつずつ設定していますが、このように親要素となるアイテムを「targetElements」に設定してあげることにより、子要素のアイテムも表示/非表示を切り替えることが可能です。
表示/非表示を行いたい項目が複数に渡り、また共通的な項目の場合は、例のようにColumnSet や Container 内にアイテムを設定してあげると、後々の編集なども容易になるかもしれません。
例のようなカードの作成方法
さて、本題の最初に挙げたような動的に入力項目が増えているように見えるアダプティブカードの作成方法ですが、こちらも「Action.ToggleVisibility」を応用したものになります。
流れとしては、
- 項目追加ボタンを押す。
- 自身の親カラム(Column)を非表示にし、次の入力項目カラムと項目追加/削除カラムを表示する。
となっています。
項目削除はその逆ですね。
アイテムの初期表示は、「Initially visible」により制御可能です。
これらを理解したうえで、今回使用したJSON をみてみましょう!
※長いので一部省略しています。
{ "type": "AdaptiveCard", "$schema": "http://adaptivecards.io/schemas/adaptive-card.json", "version": "1.2", "body": [ { "type": "TextBlock", "text": "日報" }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "stretch", "items": [ { "type": "TextBlock", "text": "始業時間" } ] }, { "type": "Column", "width": "stretch", "items": [ { "type": "Input.Time", "id": "startTime" } ] } ] }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "stretch", "items": [ { "type": "TextBlock", "text": "退勤時間" } ] }, { "type": "Column", "width": "stretch", "items": [ { "type": "Input.Time", "id": "endTime" } ] } ] }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "stretch", "items": [ { "type": "TextBlock", "text": "タスク名" } ] }, { "type": "Column", "width": "stretch", "items": [ { "type": "TextBlock", "text": "進捗率[%]" } ] } ] }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "stretch", "items": [ { "type": "Input.Text", "placeholder": "Placeholder text", "id": "taskName1" } ] }, { "type": "Column", "width": "stretch", "items": [ { "type": "Input.Number", "placeholder": "Placeholder text", "min": 0, "max": 100, "id": " progress1", "errorMessage": "0から100の数値を入力してください。" } ] } ], "id": "inputCol1" }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "stretch", "items": [ { "type": "ActionSet", "actions": [ { "type": "Action.ToggleVisibility", "title": "項目を追加する", "targetElements": [ "inputCol2", "buttonCol1", "buttonCol2" ] } ], "id": "addButton1" } ] }, { "type": "Column", "width": "stretch" } ], "id": "buttonCol1" }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "stretch", "items": [ { "type": "Input.Text", "placeholder": "Placeholder text", "id": "taskName2" } ] }, { "type": "Column", "width": "stretch", "items": [ { "type": "Input.Number", "placeholder": "Placeholder text", "id": " progress2", "errorMessage": "0から100の数値を入力してください。", "min": 0, "max": 100 } ] } ], "isVisible": false, "id": "inputCol2" }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "stretch", "items": [ { "type": "ActionSet", "actions": [ { "type": "Action.ToggleVisibility", "title": "項目を追加する", "targetElements": [ "inputCol3", "buttonCol2", "buttonCol3" ] } ], "id": "addButton2" } ] }, { "type": "Column", "width": "stretch", "items": [ { "type": "ActionSet", "actions": [ { "type": "Action.ToggleVisibility", "title": "項目を削除する", "targetElements": [ "inputCol2", "buttonCol1", "buttonCol2" ] } ], "id": "deletButton2" } ] } ], "id": "buttonCol2", "isVisible": false }, ...(略)... { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "stretch", "items": [ { "type": "Input.Text", "placeholder": "Placeholder text", "id": "taskName9" } ] }, { "type": "Column", "width": "stretch", "items": [ { "type": "Input.Number", "placeholder": "Placeholder text", "id": " progress9", "errorMessage": "0から100の数値を入力してください。", "min": 0, "max": 100 } ] } ], "isVisible": false, "id": "inputCol9" }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "stretch", "items": [ { "type": "ActionSet", "actions": [ { "type": "Action.ToggleVisibility", "title": "項目を追加する", "targetElements": [ "inputCol10", "buttonCol9", "buttonCol10" ] } ], "id": "addButton9" } ] }, { "type": "Column", "width": "stretch", "items": [ { "type": "ActionSet", "actions": [ { "type": "Action.ToggleVisibility", "title": "項目を削除する", "targetElements": [ "inputCol9", "buttonCol8", "buttonCol9" ] } ], "id": "deletButton9" } ] } ], "id": "buttonCol9", "isVisible": false }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "stretch", "items": [ { "type": "Input.Text", "placeholder": "Placeholder text", "id": "taskName10" } ] }, { "type": "Column", "width": "stretch", "items": [ { "type": "Input.Number", "placeholder": "Placeholder text", "id": " progress10", "errorMessage": "0から100の数値を入力してください。", "min": 0, "max": 100 } ] } ], "isVisible": false, "id": "inputCol10" }, { "type": "ColumnSet", "columns": [ { "type": "Column", "width": "stretch", "items": [ { "type": "ActionSet", "id": "addButton10" } ] }, { "type": "Column", "width": "stretch", "items": [ { "type": "ActionSet", "actions": [ { "type": "Action.ToggleVisibility", "title": "項目を削除する", "targetElements": [ "inputCol10", "buttonCol9", "buttonCol10" ] } ], "id": "deletButton10" } ] } ], "id": "buttonCol10", "isVisible": false }, { "type": "ActionSet", "actions": [ { "type": "Action.Submit", "title": "送信", "id": "submit" } ] } ] }
...(略)...と記載されている箇所は、本ブログの説明内容と、前後の記載を参考に自身で埋めてみてください。
もしわからない箇所などあればお気軽にお尋ねくださいー。
コルネ (@koruneko32767) | Twitter
まとめ
このようにアダプティブカードも工夫次第で、少し変わった動きをさせることができます。
ただこの方法で作成したアダプティブカードの結果をPower Automate で取得した場合、ユーザーが非表示にしていた項目も未入力項目として取得されてしまいますので、データの取得の際には未入力項目を弾くなどのなんらかの処理を加えたほうが良いかもしれません。