[OutSystems]Data GridのValidationを検討する

# 環境情報
Personal Environment(Version 11.18.1 (Build 37884))
Service Studio(Version 11.54.11)
OutSystems Data Grid(Version 2.11.0

# サンプルモジュール
[HousesoftSampleReactive](https://www.outsystems.com/forge/component-overview/7086/housesoftsamplereactive) V1.0.18のDataGridValidation Screen

# 関連記事
[DataGridを使って複数行編集可能なテーブルを実現する](https://qiita.com/jyunji_watanabe/items/61e31ead0acf400f94a8)
[Data Gridを使う画面でWijmoのAPIを呼ぶ方法](https://qiita.com/jyunji_watanabe/items/f952306ba306d72457a4)

# 入力時のValidation
型チェックについては、そもそも型に対応するxxColumn Widgetを配置した時点で、その型に合わない入力はできないようだ。
## 必須チェック
Column WidgetのMandatoryプロパティを設定すると、その列は入力必須になる。
MandatoryプロパティはStructure
- IsMandatory: Trueに設定すれば、その列は必須になる
- ErrorMessage: 未入力のときに表示するエラーメッセージ。空文字列だとデフォルトのエラーメッセージになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/281eaedd-f3fe-e1bb-a47b-08843b74e9b5.png)

以下のようにエラーメッセージが表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/4ca9803f-c920-93e5-6e55-c20f5b320454.png)

## 行を追加した直後にValidationを働かせたいとき
Context Menu「MenuItem_Rows_Add」や、Client Action「AddNewRows」で行を追加した直後は、Validationが働いでいないため、必須項目がエラーになっていない。
行を追加すると同時にValidationを効かせるためには、AddNewRowsのOutput Parameterである行番号を使って「API_Validation/ApplyRowValidations」を使う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/e8c6590f-a25d-db1c-0404-1bf2078621eb.png)

3行目が、AddNewRows -> ApplyRowValidationsと呼び出して追加した行、4行目はContext Menuから追加した行。3行目だけ、Validation結果がUIに反映されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/538c01c6-16a8-52da-d700-c039cff6c610.png)

## Validation結果をActionで設定
セルの値を変更したときに、列に設定された条件をチェックし（Validationし）、問題があればエラーにするには、
1. Column WidgetのOnCellValueChange Eventにハンドラーを設定する
1. ハンドラー内で新しい値に対してValidationを行う
1. 結果をAPI_Validation/SerValidationStatus Actionで設定する

という手順を取る。
各ColumnのEventsの下にあるOnCellValueChange Eventに対し、ハンドラーを設定する（下の例では、NumberColumn Widgetに対して設定している）。
![14F4E32E-E89B-48D3-9A74-9BFDE75C9DF4_1_201_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/0774698c-883f-a798-a521-5327b70abfe0.jpeg)

ハンドラー内では、SetValidationStatus Actionを呼び出す。
GridWidgetId, RowNumber, ColumnWidgetIdには、ハンドラーに渡される値をそのまま設定する。
IsValid: NewValid（今入力した値）に対し、Validationを行う。Trueであれば問題ないことになる
RuntimeErrorMessage: IsValid=Falseの時に表示するメッセージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/542ebfa3-b875-e041-8645-9db6b9ce6bfb.png)

実際にエラーになると以下のように表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/fb438427-b0b2-c681-5191-b630c5f22c22.png)

# Serverに編集したデータを送信する前のValidation
更新処理を行う際には、API_Data/GetChangedData Actionを使う。
そのOutput Parameter ChangedLines.HasInvalidLines (Boolean型）がTrueの時、Grid内にValidationエラーがある。
その時、エラーのある行のデータは、同じくOutput Parameter ChangedLines.InvalidLinesに（JSONフォーマットで）含まれている。

例えば、以下のように
- 2行目: 名前列未入力
- 3行目: 価格列に負の値（SetValidationStatusで設定した）
- 4行目: 追加した行・名前列未入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/d942821a-f0bc-ea8d-643b-87a69d66f5af.png)

というエラーがある状態で、GetChabgedDataを呼ぶと以下の値がInvalidLinesに含まれている。
エラーがある行の生データなので、そんなに使いどころは無さそう。

``` js
[[{"Sample_Product":{"Id":2,"Name":"","Description":"DescriptionB","Price":2,"Stock":12},"__osRowMetadata":{}},{"Sample_Product":{"Id":3,"Name":"C","Description":"DescriptionC","Price":-2,"Stock":13},"__osRowMetadata":{}},{"Sample_Product":{},"__osRowMetadata":{}}]]
```

処理手順としては、更新系のボタンがクリックされたとき、
1. GetChangedDataを呼ぶ
1. HasInvalidLinesをチェックしてFalseなら、Feedbackでも表示して処理終了
1. セル同士の相関チェックなどを行い、エラーがあればSetValidationStatus ActionやFeedbackを使って表示し、処理終了
1. ↑までを終えて、なお問題が無ければ更新本体のServer Actionを呼び出す

という感じか。

# 送信後の（サーバー側の戻り値を使用した）Validation
これは、ValidationはServer Actionで行われるので、その結果を見て、Feedbackを表示したり、SetValidationStatus Actionで設定することになるはず。