はじめに
これは、Handsontable Advent Calendar 2018の16日目の記事となります。
前回「【Handsontable】最大文字数制限(MaxLength)」では最大文字数制限を行いました、今回は確定ボタンのチェック処理を実装していきます。
確定ボタンのチェック処理
確定ボタンのチェック処理では、複数列セルのバリデーションを順次実行するようにします。そのため非同期処理を操作する Promise
を利用しています。エラーは catch
で一括チェックするようにしました。
※IE11対応をするため、await
は使用しませんでした。
必須チェックをした際、必須項目が入力されていないところは赤くなりました。
validateCells
メソッドでは全てのセルのバリデージョンを明示的に実行します。
全てのセルを対象とするため、エラー箇所は全て赤くなります。
1箇所でもバリデージョンエラーがあった場合、バリデージョンエラーの位置を getCellMeta(i, j).valid
を使用して特定し必須項目または値の不正エラーメッセージを表示します。
次は主キーである商品コードが重複していないかをチェックします。
全てのエラーがなくなった場合、更新の確認メッセージを表示します。
// チェック処理
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);
}