はじめに
これは、Handsontable Advent Calendar 2018の2日目の記事となります。
前回「【Handsontable】導入と設定」では商品マスタの画面設定をしました。今回から少しずつ実装を組んでいきます。
先ずはデータの読み込みと行追加を実装していきます。
データの読み込み
前回はダミーデータをソースコード上に書きましたが、今回はJSONデータを読み込むようにします。
2件のデータを登録します。
{
"ProductMaster":[
{
"Edit":"",
"Select":false,
"ProductCode":"S0001",
"ProductName":"りんご",
"UnitPrice":100,
"Comment":"青森産"
},
{
"Edit":"",
"Select":false,
"ProductCode":"S0002",
"ProductName":"みかん",
"UnitPrice":80,
"Comment":"静岡産"
}
]
}
ajax にてJSONデータを読み込み、loadDataメソッドを使用してHandsontableにデータをロードさせます。
columns属性のdata
にJSONデータに合わせたキー名を指定しておきます。
const COL_EDIT = 'Edit';
const COL_SELECT = 'Select';
const COL_PRODUCTCODE = 'ProductCode';
const COL_PRODUCTNAME = 'ProductName';
const COL_UNITPRICE = 'UnitPrice';
const COL_COMMENT = 'Comment';
var grid = document.getElementById('grid');
var hot = new Handsontable(grid, {
data: [],
colHeaders: ['編集', '選択', '商品CD', '商品名', '単価', '備考'],
columns: [
{ data: COL_EDIT, readOnly: true, type: 'text' },
{ data: COL_SELECT, type: 'checkbox' },
{ data: COL_PRODUCTCODE, type: 'text' , width: 80 },
{ data: COL_PRODUCTNAME, type: 'text' , width: 200, className: "htLeft htMiddle" },
{ data: COL_UNITPRICE, type: 'numeric', numericFormat: { pattern: '0,00', culture: 'ja-JP' }},
{ data: COL_COMMENT, type: 'text' , width: 300, className: "htLeft htMiddle" }
],
enterMoves: { row: 0, col: 1 },
outsideClickDeselects: true,
manualColumnResize: true,
fillHandle: false
});
// 読み込み時
$(function () {
loadData()
})
// GET用非同期処理
function getAjax(method, data, callback) {
$.ajax({
url: method,
type: 'GET',
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 loadData() {
var process = function (data) {
hot.loadData(data.ProductMaster);
}
getAjax('../data/product-master.json', null, process);
}
行追加
最下行に追加
最下行は、現在の行数(countRows)を指定します。
hot.alter('insert_row', hot.countRows());
指定セルのフォーカスをセット
行追加後に新規行にフォーカスを移動させたい。
指定は行、列の順番となります。
hot.selectCell(row, col);
行追加ボタンの実装
行追加ボタンをクリックしたら最下行に新規行を追加します。
そして、セルを新規行の商品コードにセットします。
// 行追加ボタン処理
function addRow() {
hot.alter('insert_row', hot.countRows());
var col = hot.propToCol(COL_PRODUCTCODE);
hot.selectCell(hot.countRows() - 1, col);
}
選択位置の上下に行を挿入
コンテキストメニューには「上に行を挿入:Insert Row Above」と「下に行を挿入:Insert Row Below」と2種類がデフォルトで用意されている。
Handsontable のグリッドオプションに追加すれば使える。
Handsontable 使い方メモ2(グリッドのオプション)- デフォルトで使用できるメニューのラベルを変更する
contextMenu: {
items: {
row_above: { name: '上に行を挿入' },
row_below: { name: '下に行を挿入' }
}
}
上記だとフォーカスを新規行にセットされないため、メニューが選択されたときのコールバック関数を指定して実現させる。
contextMenu: {
items: {
row_above: {
name: '上に行を挿入',
callback: function (key, normalizedSelection) {
var latestSelection = normalizedSelection[Math.max(normalizedSelection.length - 1, 0)];
this.alter('insert_row', latestSelection.start.row);
var col = hot.propToCol(COL_PRODUCTCODE);
hot.selectCell(latestSelection.start.row, col);
}
},
row_below: {
name: '下に行を挿入',
callback: function (key, normalizedSelection) {
var latestSelection = normalizedSelection[Math.max(normalizedSelection.length - 1, 0)];
this.alter('insert_row', latestSelection.end.row + 1);
var col = hot.propToCol(COL_PRODUCTCODE);
hot.selectCell(latestSelection.end.row + 1, col);
}
}
}
}