Edited at

【Handsontable】変更マークの付与と必須チェック


はじめに

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

前回は「【Handsontable】全選択/全解除チェックと行削除」では全選択/全解除チェックと行削除を行いました、今回は変更マークの付与と必須チェックを実装していきます。


変更マークの付与

先頭列(Edit)に同じ行のいずれかの列の変更があった場合に「*」を付ける。

但し、編集列と選択列は対象外とする。

Handsontableではデータの更新時、afterChangeオプションに指定したメソッドが呼び出される。

const EDIT_MARK = '*';

// changesには[[row, col, pretext, aftertext]] でセットされる。
afterChange: function (changes, source) {
if (source === 'loadData') return;

for (var i = 0; i < changes.length; i++) {
var change = changes[i];
// 編集と選択は対象外
if (change[1] === COL_EDIT || change[1] === COL_SELECT) continue;
// 変更前と変更後が同じは対象外
if (change[2] === change[3]) continue;

// 編集に"*"を付ける
hot.setDataAtCell(changes[0][0], 0, EDIT_MARK);
}
}


必須チェック

必須チェックする項目としては、商品コードと商品名と単価となります。

値をチェックするカラムに下記のvalidatorオプションを追加します。

validator: function (value, callback) { callback(true); }

var hot = new Handsontable(grid, {

columns: [
{ data: COL_EDIT, readOnly: true, type: 'text' },
{ data: COL_SELECT, type: 'checkbox' },
{ data: COL_PRODUCTCODE, type: 'text', width: 80, validator: function (value, callback) { callback(true); } },
{ data: COL_PRODUCTNAME, type: 'text', width: 200, className: "htLeft htMiddle", validator: function (value, callback) { callback(true); } },
{ data: COL_UNITPRICE, type: 'numeric', numericFormat: { pattern: '0,00', culture: 'ja-JP' }, validator: function (value, callback) { callback(true); } },
{ data: COL_COMMENT, type: 'text', width: 300, className: "htLeft htMiddle", validator: function (value, callback) { callback(true); } }
],

すると、afterValidateオプションに指定したメソッドが呼び出されます。

※カラムにvalidatorオプションが必要だったかちょっと分からなくなったのですが、ないとメソッドが呼ばれない。

【2018/12/16追記】過去の自分用のメモには下記のように書いてありました。


text入力で afterValidateでまとめて桁数チェックをしようとしたが、afterValidateが動作しない。

無理矢理、validatorを経由させることでafterValidateの処理に入ってくるようになった。

※IE11対応なのでアロー演算子は使用していない。


今回は、先頭列に編集マークがある場合のみ必須項目チェックを行います。

こうすることで新規行はチェックされないようになります。

※編集マークがなければ beforeValidateオプション でもいいと思う。

afterValidate: function (isValid, value, row, prop, source) {

// 既にエラーなら何もしない
if (!isValid) return false;

// 桁数チェック
switch (prop) {
case COL_PRODUCTCODE:
// 必須項目チェック
if (this.getDataAtCell(row, 0) === EDIT_MARK && (value === null || value.trim() === "")) return false;
// 桁数チェック
if (value !== null && value.length !== 5) return false;
break;
case COL_PRODUCTNAME:
// 必須項目チェック
if (this.getDataAtCell(row, 0) === EDIT_MARK && (value === null || value.trim() === "")) return false;
// 桁数チェック
if (value !== null && value.length > 30) return false;
break;
case COL_UNITPRICE:
// 必須項目チェック
if (this.getDataAtCell(row, 0) === EDIT_MARK && (value === null || value === "")) return false;
break;
case COL_COMMENT:
if (value !== null && value.length > 100) return false;
break;
}

return true;
}

桁数が不一致やオーバーしていたり値が入っていない場合、不正な項目の背景色が赤くなります。

必須チェック.png