【Handsontable】データの読み込みと行追加


はじめに

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

前回「【Handsontable】導入と設定」では商品マスタの画面設定をしました。今回から少しずつ実装を組んでいきます。

先ずはデータの読み込みと行追加を実装していきます。


データの読み込み

前回はダミーデータをソースコード上に書きましたが、今回はJSONデータを読み込むようにします。

2件のデータを登録します。


product-master.json

{

"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データに合わせたキー名を指定しておきます。


product-master.js

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);


行追加ボタンの実装

行追加ボタンをクリックしたら最下行に新規行を追加します。

そして、セルを新規行の商品コードにセットします。

商品マスタ2.png


ProductMaster.js

// 行追加ボタン処理

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種類がデフォルトで用意されている。

行追加.png

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);
}
}
}
}