dhtmlXGridのonEditイベントでの編集状態について

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

このところDHTMLXに関するエントリーを続けています。とても素晴らしいライブラリなのですが、はまりどころもあるため少しでもお役に立てればと思ってはまったところをまとめています。

さて、今日はdhtmlXGridにdhtmlXComboを設定しているときに入力値をプログラムから設定するときに自分ではまったことです。(つまり、DHTMLXのトラップではなく自分ではまったことです。)

事象について

dhtmlXGridにでdhtmlXComboを利用したコンボボックスセル設定している画面が対象です。

girafa.png (48.9 kB)

コンボボックスにユーザーが値を入力して検索結果を表示するようにするとき、入力値がコンボボックスに未設定の値となったときにエラーを表示してコンボボックスの値を入力前の値に戻すような処理を行いたいと考えました。

girafa2.png (83.5 kB)

このような処理を行うため、dhtmlXGridのonEditCellイベントでコンボボックスの値を変更する処理を実装しました。

if ( stage === 2 ) {

        // 入力されたコンボボックスが中途半端な場合はエラーとする
        if ( cInd === targetCol.someColumnNum ) {
            var combo     = this.cells( rId, cInd ).getCellCombo();
            var inputText = combo.getComboText();
            var option    = combo.getOptionByLabel( inputText );
            if ( option == null ) {

                console.log( "入力値[" + inputText + "]がoptionに存在しません。" );
             // 編集前の値を設定する
                this.cells( rId, cInd ).setValue( oValue);
              // コンボボックスの内容をロードし直す
                combo.load( getGridXmlUrl(), function () {
                    grid.refreshComboColumn( targetCol.someColumnNum );
                } );
                combo.openSelect();
                grid.refreshComboColumn( targetCol.someColumnNum );
                               
                return false;    //  エラーのためfalseを設定する
            }

            ...
        }
...
}

ところが、ユーザーに入力された正しくない値がそのまま表示されてしまいました。

対応方法

原因は単純な認識間違いで、dhtmlXGridのonEditCellイベントの戻り値を間違えて設定していた物でした。

dhtmlXGridのonEditCellイベントでは戻り値には以下の値を設定できます。

mixed true - editing is confirmed, false - editing is canceled; or a new value of the cell

今回の場合、エラー処理として考えていたので私はfalseを指定していました。すると、すでにstageが2の状態のためセルの編集状態は確定されていることからユーザーが入力された値が確定値として設定されてしまっていたのです。^1

そこで、以下の通りdhtmlXGridのonEditCellイベントで戻り値としてtrueを設定すれば想定していた挙動となります。

if ( stage === 2 ) {

        // 入力されたコンボボックスが中途半端な場合はエラーとする
        if ( cInd === targetCol.someColumnNum ) {
            var combo     = this.cells( rId, cInd ).getCellCombo();
            var inputText = combo.getComboText();
            var option    = combo.getOptionByLabel( inputText );
            if ( option == null ) {

                console.log( "入力値[" + inputText + "]がoptionに存在しません。" );
             // 編集前の値を設定する
                this.cells( rId, cInd ).setValue( oValue);
              // コンボボックスの内容をロードし直す
                combo.load( getGridXmlUrl(), function () {
                    grid.refreshComboColumn( targetCol.someColumnNum );
                } );
                combo.openSelect();
                grid.refreshComboColumn( targetCol.someColumnNum );
                               
                return true;    //  <= ここにtrueを設定する
            }

            ...
        }
...
}

まとめ

今回のことは、はまったと言うよりも勘違いしていたということになります。ドキュメントには正しい内容が記載されているのですが、思い込みで変なことをやってしまうこともあります。ちょっと解決までに時間がかかったことなのでまとめてみました。