【UiPath】フォーム アクティビティ を使いこなす

## この記事の内容は？
本稿では UiPath フォーム アクティビティ パッケージを使用してフォームを開発する上でのヒントをいくつかご紹介します。

UiPath フォーム アクティビティ パッケージは UiPath Studio 上の GUI 操作で簡単に、デザイン性に優れかつ高度なデータ入力フォームを作成することができる非常に便利なコンポーネントです。

https://docs.uipath.com/ja/activities/other/latest/workflow/about-the-form-activities-pack

UiPath フォーム アクティビティ パッケージは V23.4.3 で大きな変更が行われ、当該バージョン以降では「新しいフォーム エクスペリエンス」を備えたものとなっています。
本稿の内容は UiPath.Form.Activities V23.10.5 で検証しており、「新しいフォーム エクスペリエンス」を前提とします。

すでに公式ドキュメントに様々なユースケースを実現する方法がまとめられているため、本稿の内容はこれらを補完する内容となります。
https://docs.uipath.com/ja/activities/other/latest/workflow/form-how-to-guides

---

本アクティビティのコア部分は form.io というJavaScriptライブラリをカスタムしたものであるため、デバッグにはフロントエンド（JavaScript, HTML, CSS）の知識が必要になります。

https://form.io/

また、UiPath の公式ドキュメントに記載がない部分については form.io 側のドキュメントあるいは実装を辿ることも助けになることがあります。

https://github.com/formio/formio.js/

## デバッグ

### 開発者ツール

フォームを表示した後にフォーム内を右クリックして表示されるメニューから、[開発者ツール]を開くことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331558/19b848c5-e939-ef3e-dbf7-a56498a13347.png)

この機能の使い方の例が次の公式ドキュメントに記載されています。

https://docs.uipath.com/ja/activities/other/latest/workflow/using-dev-tools-with-forms

### 開発者ツール > コンソール
[開発者ツール] > [コンソール]画面でできることについて補足します。

#### JavaScript 要素の操作
次のように formio と入力すると上位に formio, Formio, FormioUtils という候補が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331558/1b0f014f-e9b0-710f-0c36-396f8fdfda3e.png)
それぞれ次のようなものになります。

| 名前 | 説明 |
|:-:|:-:|
| formio | FormIoHostControllerクラスのインスタンス |
| Formio  | formio.full.min.jsで定義されているクラス  |
| FormioUtils  | FormIoUtil.jsで定義されているクラス  |

必要に応じ、上記に対して『フォームのスクリプトを実行』アクティビティを使用して操作を行うことができます。

https://docs.uipath.com/ja/activities/other/latest/workflow/execute-script-activity

##### formio

デバッグやJavaScriptからの操作でアクセスする対象は主に次のようなformioの子孫のオブジェクトです。

| 名前 | 説明 |
|:-:|:-:|
| formio  | フォームのインスタンス  |
| formio.activeForm.data  | GUI でフォームを編集する際に JavaScript コードからアクセスする data 変数 |
| formio.activeForm.components  |  フォームのコンポーネントが格納されている |
|  formio.form | 『フォームを表示』アクティビティが表示するウィンドウのデータ（例: top, leftなど）  |

##### Formio
通常は Formio を直接使用することはないため、紹介は割愛します。

##### FormioUtils
formio を便利に扱うためのユーティリリティクラスです。
このクラスを使用することで、例えば次のように指定したラベルを持つコンポーネントを検索するなどの処理が簡単に行なえます。

```js
FormioUtils.searchComponents(formio.activeForm.components, {label: 'Close'})
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331558/56a2bd02-7f3e-0381-228a-101a3f3e020c.png)

このクラスが提供する関数の詳細については次のガイドを参照してください。

https://help.form.io/developers/javascript-development/javascript-utilities


#### エラーの出力
フォーム アクティビティ内で生じたエラーは通常[開発者ツール] > [コンソール]画面に出力されます。

例えば次のようにコンポーネントの [条件] > [高度な条件] にJavaScriptコードを記述したとします。
このとき、data.targetFileが存在しなければ当然エラーが発生しますが、GUI 上や Studio のログにはエラーの出力は行われません。このようなエラーは [開発者ツール] の [コンソール] で確認する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331558/b7aac675-7003-85f7-bbbc-91341b713931.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331558/029a7ccb-551f-f377-c587-877d026cf029.png)

ちなみにこのエラーは次のように formio.activeForm.data.targetFile が undefined であることを確かめられるので、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331558/b3dd839a-120f-d8ef-96fc-c73a3bb2d61b.png)

コンポーネントの構成を確認して、targetFile は containerの下に存在するようだ、などと確かめられます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331558/749cb221-ece6-1054-a498-c2dd9af5139a.png)

## 論理 > 高度な論理 > トリガー を発火させる方法
次のような設定を行ったとき、closeLogicTrigger を発火させたいとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331558/29a0a345-44a2-eb4e-686f-12d9c84d5f12.png)

ボタン コンポーネントの[ボタン イベント]として設定することでボタンのクリック時にイベントを発火させることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331558/78c92b5c-1164-9fea-06a2-69c666573c1d.png)

イベントは JavaScript からも発生させることができます。

```js
formio.activeForm.events.emit("formio.closeLogicTrigger")
```

この方法でもトリガーを発火できますが、公式ドキュメントに明確に記述されている方法ではないため、将来または過去のバージョンでも同様に動作するかは断言ができません。



あるコンポーネントがどのようなトリガーに反応するかは次のように調べることができます。

```js
FormioUtils.searchComponents(formio.activeForm.components, {label: 'Close'})[0].events.eventNames()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331558/0b40e682-dc58-7852-40f0-f541a4a3bb3c.png)

## [HTML 要素]コンポーネント内の要素をコントロールする
[HTML 要素]コンポーネント内には任意の要素を配置することがあります。（デフォルトでは安全な要素のみ）
[HTML 要素]コンポーネント内に配置した要素の値はワークフロー側とは連携されません。
例えば[HTML 要素]コンポーネント内にInput要素を配置し、そのInput要素に入力された値をワークフローから取得することは想定されていません。この動作は仕様であり、ガイドの次の箇所に記載があります。

> コンポーネントを使用すると、情報をフォームに表示専用で追加できます。コンポーネントの値はワークフローに返されません。
https://docs.uipath.com/ja/activities/other/latest/workflow/forms-advanced-components#content

既存のコンポーネントと同様にこの「[HTML 要素]コンポーネント内のInput要素」の値を `data` として扱いたい場合、次のように『フォームのスクリプトを実行』アクティビティを使って設定を行うことで実現できます。

```js
document.getElementById('inputField').addEventListener('change', (event) => 
{
  formio.activeForm.data.inputFieldValue = event.target.value; 
});
```
この例では対象のInput要素のIdが `inputField`、データの格納先が `data.inputFieldValue` です。
この要素の値が変更されるたびに、変更後の値が `data.inputFieldValue` に保存されます。


## おわりに

本稿の内容がUiPath フォーム アクティビティ パッケージを使いこなす上での一助となりましたら幸いです。