LoginSignup
7
4

More than 5 years have passed since last update.

【Handsontable】確定ボタンのチェック処理

Last updated at Posted at 2018-12-16

はじめに

これは、Handsontable Advent Calendar 2018の16日目の記事となります。

前回「【Handsontable】最大文字数制限(MaxLength)」では最大文字数制限を行いました、今回は確定ボタンのチェック処理を実装していきます。

確定ボタンのチェック処理

確定ボタンのチェック処理では、複数列セルのバリデーションを順次実行するようにします。そのため非同期処理を操作する Promise を利用しています。エラーは catch で一括チェックするようにしました。
※IE11対応をするため、await は使用しませんでした。

必須チェックをした際、必須項目が入力されていないところは赤くなりました。
validateCells メソッドでは全てのセルのバリデージョンを明示的に実行します。
全てのセルを対象とするため、エラー箇所は全て赤くなります。
全てエラー.png

1箇所でもバリデージョンエラーがあった場合、バリデージョンエラーの位置を getCellMeta(i, j).valid を使用して特定し必須項目または値の不正エラーメッセージを表示します。
必須項目エラー.png

次は主キーである商品コードが重複していないかをチェックします。
重複エラー.png

全てのエラーがなくなった場合、更新の確認メッセージを表示します。
商品マスタ保存.png

// チェック処理
function check() {
    // 全入力項目チェック
    var checkAllItem = function () {
        return new Promise(function (resolve, reject) {
            hot.validateCells(function (valid) {
                if (valid) {
                    resolve();
                } else {
                    result = { msg: 'All', row: 0, col: 0 };
                    reject(result);
                }
            });
        });
    }

    // 重複チェック
    var checkDuplicate = function () {
        const colPrimaryKey = 2;

        return new Promise(function (resolve, reject) {
            var isDuplicate = false;
            result = { msg: 'Duplicate', row: 0, col: colPrimaryKey };

            for (var i = 0; i < hot.countRows(); i++) {
                var key = hot.getDataAtCell(i, colPrimaryKey);
                if (key == 0) continue;
                for (var j = 0; j < hot.countRows(); j++) {
                    if (i != j) {
                        if (key === hot.getDataAtCell(j, colPrimaryKey)) {
                            result.row = j;
                            isDuplicate = true;
                            break;
                        }
                    }
                }
                if (isDuplicate) break;
            }

            if (!isDuplicate) {
                resolve();
            } else {
                reject(result);
            }
        });
    }

    // 非同期チェック処理
    var promise = Promise.resolve();

    promise
        .then(checkAllItem)
        .then(checkDuplicate)
        .then(function () {
            var result = window.confirm('商品マスタを更新します。よろしいですか?');

            if (result) {
                console.log('保存処理');
            }
            else {
                console.log('キャンセル');
            }
            return

        }).catch(function (result) {
            var isValid = true;
            var errorMsg = '';

            switch (result.msg) {
                case 'All':
                    setError(result);
                    errorMsg = result.msg;
                    break;
                case 'Duplicate':
                    errorMsg = "重複しています。";
                    break;
            }

            // エラーセルのフォーカスをセット
            hot.selectCell(result.row, result.col);
            // エラー表示
            alert(errorMsg);
        });
}

// エラーセット
function setError(obj) {
    var headers = hot.getColHeader();

    for (var i = 0; i < hot.countRows(); i++) {
        for (var j = 2; j < hot.countCols(); j++) {
            var isValid = hot.getCellMeta(i, j).valid;
            if (isValid === false) {
                obj.row = i;
                obj.col = j;

                var value = hot.getDataAtCell(i, j);
                obj.msg = headers[j];
                if (value === null || value.trim() === '') {
                    obj.msg += "は、必須項目です。";;
                }
                else {
                    obj.msg += "は、不正な値です。";
                }
                return;
            }
        }
    }
}

データ保存処理

AjaxのPostを使用してサーバー側処理(ASP.NET)にJSON形式のデータを送信します。
今回はサーバー側処理の実装は省略します。
本来はデータ読込処理もサーバー側処理(ASP.NET)にする必要があります。

// POST用非同期処理
function postAjax(method, data, callback) {
    $.ajax({
        url: method,
        type: 'POST',
        dataType: 'json',
        data: data,
        contentType: 'application/json; charset=utf-8',
        async: true,
        processData: true,
        cache: false
    }).fail(function (xhr, status, error) {
        alert(error);
    }).done(function (data) {
        callback(data);
    });
}

// データ保存
function saveData() {
    var process = function (data) {
        if (data.success)
            alert("保存しました。");
    }
    postAjax('SetProductMasterData', JSON.stringify(hot.getSourceData()), process);
}
7
4
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
7
4