【OutSystems】DatePickerを部品化する

OutSystemsUI（OutSystems11）のDatePickerだがアップデートが実施されてからClientActionが追加されたりと大きく利用方法が変わっている（選択した日付を初期化するときは専用のクライアントアクションを呼んだりなど）必要なユースケースのアクションを一つにWebBlockへまとめて部品化したほうが良いと考えサンプルを作成した。

## 1.DatePciker部品のイメージ
利用側と部品側の関係は以下のイメージで作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/37a6a873-527e-0ca3-dd45-a33e05075700.png)

WebBlock側のDatePickerで持っているInputFiledへの値の反映や初期化を部品として実装させることで利用画面（親画面側）は必要なパラメータのみをWebブロックに渡して利用できるイメージとなります。

## 2.WebBlock側の実装
### 2-1.ウィジェット構成
各部品とウィジェットツリーの配置は以下のイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/96f5b816-53c6-4799-56f1-fec00dfd2d4c.png)
・部品構成としてラベル、日付フィールド、カレンダー、初期化（×）ボタンで構成する
・カレンダーアイコンクリック時はカレンダーを表示するイベントを呼び出す
・初期化（×）アイコンクリック時は選択したデータをクリアするイベントを呼び出す
・値のセット状況によってカレンダーアイコンと（×）ボタンの表示を切り替える
・ラベル名とエラー時のスタイルは親画面からの呼び出しパラメータで値を反映させる
<br>
### 2-2.変数・クライアントアクション定義
クライアントアクション・変数の定義は以下を作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/3cb16df1-c6ee-c2e8-450e-1fbe445c8317.png)
<b><変数></b>
InLblName：親画面からのパラメータでラベル名を表示
InDefaultDate：親画面からのパラメータで特定日付を初期表示させたい時に指定
IsError：親画面からのパラメータでエラー時のスタイル表示フラグ
PickedDate：WebBlock側で保持している選択した日付(InputDateフィールドにバインドする)

<b><クライアントアクション></b>
CalendarOnClick：カレンダーアイコンクリック時にDatePickerを表示させる
DateEmptyOnClick：初期化（×）ボタンクリック時の初期化処理（日付クリア）を定義
DatePickerInitialized：DatePickerのInitialize処理を定義（パラメータの受渡や言語設定）
DatePickerOnSelected：カレンダーで日付を選択し時の処理（日付セット）を定義
DateReturn：WebBlock側で定義したイベント処理（日付クリアとセット時に発生させる）
<br>

### 2-3.クライアントアクション呼出しタイミング
DatePickerのinitializeとOnSelected時にDatePickerInitialized, DatePickerOnSelectedを呼出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/ccdd14e1-44f0-4d08-f644-73a0c513ace7.png)

カレンダーアイコンクリック時にCalendarOnClickを呼出します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/64387006-03f1-a073-a90d-13605be89e89.png)

（×）ボタンクリック時にDateEmptyOnClickを呼出します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/fc49ff2a-dfed-77bd-033c-e3e66cff680e.png)
<br>

### 2-4.クライアントアクション実装詳細
<b>CalendarOnClick</b>
カレンダークリック時にDatePickerを開くアクションを定義します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/d981e35a-e453-f8f3-deb0-08eedcf16e3a.png)

<b>DatePickerOnSelected</b>
選択した日付を画面に反映するアクションを定義します。
また選択した日付を親画面に返すためのイベントを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/53eb758c-5938-2759-8925-125b9f5c9485.png)

<b>DateEmptyOnClick</b>
（×）ボタンをクリックした際に日付を初期化するアクションを定義します。
選択した日付（この場合は初期化した日付）を親画面に返すためのイベントを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/566ceba2-3240-183c-6198-df6af9defdb0.png)

<b>DatePickerInitialized</b>
WebBlockの呼出し時の初期処理としてパラメータの受渡処理と言語設定を実施します。
受け取ったパラメータは一旦日付を選択したものとみなして前述のをDatePickerOnSelected呼出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/bfee8111-42f5-2161-61fa-f2f5e3019fa3.png)

<b>DateReturn</b>
イベント処理を定義します。
このイベントはカレンダーで日付を選択（または初期化）した際に起動して、親画面に選択した日付を返します。
前述で記載したようにDatePickerOnSelectedとDateEmptyOnClickでイベントをキックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/33c4d0c7-36b3-8f58-06a3-ff7a16d167e3.png)


## 3.呼び出し側（親画面）実装
### 3-1.親画面の実装
親画面側でWebBlockを組み込み呼び出してあげます。
あらかじめパラメータとしてセットされている
ラベル名、初期日付（現在日）、エラーフラグ
をセットします。
またWebBolck側で定義したイベント（DateReturn）をトリガーとして起動するクライアントアクション（QMDateFieldDateReturn）をセットします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/6c70f542-4726-3913-368c-730a82c7b7bf.png)

QMDateFieldDateReturn側は以下の実装となり、WebBlock側のイベント処理で渡ってきたパラメータ（選択した日付）を受け取り親画面側の変数にセットします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/2c799090-0067-56c9-beb2-b04b898c7b40.png)
<br>
### 3-2.動作確認
実際に起動すると日付の初期化やカレンダー選択時の値反映が動作していますね。
・初期表示画面（今日の日付をセット）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/bc6fabeb-1c42-aaf0-d93e-bb6277886fdd.png)
・カレンダーで×ボタンクリック直後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/552bbff8-a8e5-1f7f-622b-422e85794c1f.png)
・カレンダーで日付選択直後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3785085/f7beeaa6-e5bc-b80d-fbc8-984c005d5a6f.png)
<br>

日付の入力などは色々な機能で共通的に必要となるのでWebBlockで部品化して利用する方が使い勝手はよさそうですね。
他にも部品側で持たせた方がいいような共通処理はありそうだけどあまり汎用的に作りこみ過ぎると利用者側はかえって混乱する可能性もあるからいったんこんなもんだろうか。