dhtmlxで表示項目の初期化処理onXLEイベント内で行う

こんにちは。beaglesoftの真鍋です。

dhtmlXFormやdhtmlXGridなどdhtmlxのコンポーネントを利用するときに注意するべきこととして、処理を実行するタイミングという物があります。それは何かというと、表示項目を扱うときは表示項目が準備されてから設定を行う必要があるということです。

たとえば、dhtmlXFormで以下の画面を作成し、税込金額は数値であるチェックを追加したいと思います。

blog1.png (9.7 kB)

このとき、税込金額は全角で数値が入力されることもあるため、デフォルトのValidNumericルールを使用することは考えておらず、以下のような検証メソッドを動的に設定することにします。

zeikomiKingakuValidatorCallback(zeikomiKingaku: string) {
    console.log("** zeikomiKingaku:" + zeikomiKingaku);
    return NumericUtils.isNumeric(zeikomiKingaku);
}
namespace Commons {
    export class NumericUtils {

        ...
        /**
         * 引数の文字列が数値文字列かを判定する。
         * @param value 判定対象の文字列
         * @returns {boolean} 数値の場合はtrue
         */
        public static isNumeric(value:string):boolean{

            // note:
            // 数値文字列以外が含まれる場合がtrueとなる正規表現を利用して
            // 数値文字列かを判定する。

            var pattern = /[^0-90-9]/g;
            return pattern.test(value) === false;
        }
    }
}

次に、この処理を画面作成時に以下のように記述します。

/**
* 初期化処理を実行する。
* @returns {boolean}
*/
public initialize(config:ItemFormConfig):boolean {

    this.dhxForm = this.layout.attachForm("form");
    this.dhxForm.enableLiveValidation(config.getEnableLiveValidation());
    this.dhxForm.attachEvent("onButtonClick", this.onButtonClickCallback);

    // 検証関連のコールバック処理
    this.dhxForm.attachEvent("onBeforeValidate", this.onBeforeValidate);
    this.dhxForm.attachEvent("onAfterValidate", config.getAfterValidateCallback());
    
    // フォームの構成を取得してセットアップする
    this.dhxForm.loadStruct(config.getLoadXmlUrl());
    
    // 税込金額のチェック処理を追加
    this.dhxForm.setValidation("zeikomiKingaku", this.zeikomiKingakuValidatorCallback);
    
    return true;
}

さて、このようにすると見事に動作しません。しかもエラーも出ません…。このエラーが出ないのがうれしいような悲しいような。

原因は画面の準備ができていない状態で税込金額のチェック処理を追加しているため、検証処理が設定されていないためです。この辺は、具体的にソースコードを読むとよくわかるのですが、検証処理を追加する対象の項目(この場合は税込金額)が存在しない場合には検証メソッドは設定されません。

正しくは以下の通りonXLEイベント内で検証処理を設定すればOKです。

/**
* 初期化処理を実行する。
* @returns {boolean}
*/
public initialize(config:ItemFormConfig):boolean {

    this.dhxForm = this.layout.attachForm("form");
    this.dhxForm.enableLiveValidation(config.getEnableLiveValidation());
    this.dhxForm.attachEvent("onButtonClick", this.onButtonClickCallback);

    // 検証関連のコールバック処理
    this.dhxForm.attachEvent("onBeforeValidate", this.onBeforeValidate);
    this.dhxForm.attachEvent("onAfterValidate", config.getAfterValidateCallback());
    
    // フォームの構成を取得してセットアップする
    this.dhxForm.loadStruct(config.getLoadXmlUrl());
    
    this.dhxForm.attachEvent("onXLE", () => {
                // 税込金額のチェック処理を追加
        this.dhxForm.setValidation("zeikomiKingaku", this.zeikomiKingakuValidatorCallback);
        });

    return true;
}

補足

dhtmlxではデータのロードが完了するとonXLEイベントが発火します。つまり、このイベントがデータへのアクセス開始を保証しているのです。 onXLE DHTMLX Docs

まとめ

実行時にエラーが出ないことはありがたいと言えばありがたいのですが、エラーが出ないために開発時に問題に気づきづらいのもつらいですね。もし、項目に設定した値が正しく反映されていない/取得できないといったときには、処理のタイミングを常に意識するとよいですね。

開眼!  JavaScript ―言語仕様から学ぶJavaScriptの本質

開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質