1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[OutSystems]JavaScriptのValidation APIがClient Actionsから使えない問題のまとめ

Posted at

標準のValidationをJavaScriptで操作するAPIについて、以前以下の記事でまとめた。
JavaScript APIで、List中のInputに対するValidation
一般的な使い方については、上記の記事を参照して欲しい。

このAPIが(ドキュメントには記述が見つからないが)Screen Actionの中では機能しないこと、及びその回避策をメモしておく。

ドキュメント

JavaScriptAPI - Validation
Validationに含まれるAPIが各WidgetのValidationを設定する(エラーメッセージを設定したり、クリアする)機能を提供することが書かれている。

Screen ActionからはValidation APIを呼べる

UI定義

以下のようにInputを画面に配置し、Nameプロパティを「Input_Name」とした。
(Nameプロパティは、後で対象Widgetを特定するのに使う)
image.png

Screen Action定義

Screen ActionのAction FlowにJavaScript要素を配置し、以下のJavaScriptを記述する。

var widget = document.querySelector('[id$=Input_Name]');
if (widget)
    $public.Validation.setWidgetAsInvalid(widget.id,"テストValidationMessage");

 
1行目:InputのNameを使い、ページ内のDOMをidの後方一致で検索している。
 DOM要素に変換されたWidgetのidは、WidgetのNameプロパティの値で終わる。Develop for Testability - Widget Namingというドキュメントに以下の通り記述されている。

... the element’s ID attribute will always terminate with the widget’s name property value.

3行目:Validation APIのsetWidgetAsInvalid関数を使い、定義したUI (Input)にValidation Message「テストValidationMessage」を設定しエラー状態にしている。第1引数は1行目で取ったDOM要素のidを渡す。

動作確認

Screen Action内でJavaScript APIを呼べば、想定通りにValidationを設定できる。
image.png

Screen ActionでないClient ActionからはValidation APIを呼べない

実装変更:Validation API呼び出しをClient Actionに移動する

Screen Actionをコピーして、Client Actionsの下に貼り付けて新しいClient Actionにする。
このActionをClient Actionから呼び出すように変更。
image.png

Validation API呼び出しが、必要なオブジェクトへのアクセスができずにエラー

実装変更した状態でChromeでテストすると、以下の通りエラーが発生する。
「Cannot read properties of null (reading 'widgets')」
image.png

なお、Firefoxでテストすると、エラーメッセージは「this._model is null」。

Chromeの開発者ツールで該当部分のソースを覗くと以下の通り。
2行目が該当する。「this._model」が実際にnullであるためにエラー。
理由はわからないが、Client ActionからValidation APIを呼ぶと、このオブジェクトがないためにエラーになるということらしい。

Validation.prototype.setWidgetAsInvalid = function (widgetId, validationMessage) {
    var validationRecord = this._model.widgets.get(widgetId);
    validationRecord.validAttr = false;
    validationRecord.validationMessageAttr = validationMessage;
};

関連情報(OutSystems Forum)

How to use the mobile javascript API class $public.Validation
Mobileの場合の話題だが、同じ問題に行き着いている。

回避策

一応回避策はある。
$publicという、JavaScriptでOutSystemsのAPIにアクセスするためのオブジェクトをInput Parameterとして渡す方法で、安全性や注意点について詳細な情報が得られないので気軽には使えないが、一応紹介しておく。

Why it is not possible to use $public outsystems react API in Screen Actions?で、Dorine Boudry
さんが紹介している方法。

you could retrieve the $public object at screen level and store it in a local variable of type object in your screen.
Each client action that you want to use on the public api, takes in an input variable of type object.
Pass this into your javascript and use it instead of $public.

というわけで、

  1. Screen ActionでClient Actionを呼ぶ前にJavaScript要素で$publicを取り出す
  2. Client ActionはObject型Input Parameterとして、$publicを受け取る
  3. Validation APIを呼ぶときに、$publicの代わりに受け取った変数を経由して行う

とすればよい。

実装例

Screen Action

Client Actionの呼び出し直前に$publicオブジェクトを取り出すようにした。
JavaScript要素で、Object型のOutput Parameter 「PublicContext」を作り、$publicを編集。
image.png

この値をClient ActionのInput Parameterに渡す。

Client Action

Object型のInput Parameterを持たせる。
image.png

JavaScript要素のInput Parameterにそのまま渡し、渡したObjectを経由してValidation APIを呼ぶ。
image.png

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?