Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
kintone x handsontable
(function() {
"use strict";
var hot; // handsontable用変数
  // kintoneのレコード更新・追加時は、レコード番号などアップデートできないフィールドがあるので、除外するためのメソッド
var setParams = function(record) {
var result = {};
for (var prop in record) {
if (['レコード番号', '作成日時', '更新日時', '作成者', '更新者', 'ステータス', '作業者'].indexOf(prop) === -1) {
result[prop] = record[prop];
}
}
return result;
};
// kintoneのレコード取得用メソッド
var getRecords = function(callback, errorCallback) {
kintone.api('/k/v1/records', 'GET', {app: kintone.app.getId(), query: 'order by レコード番号 asc limit 500'},
function(resp) {
callback(resp);
},
function(resp) {
errorCallback(resp);
}
);
}
// kintoneのレコード更新、追加用メソッド
var saveRecords = function(records, changedDatas, callback, errorCallback) {
var requests = [];
var updateRecords = [];
var insertRecords = [];
var changedRows = [];
var i;
// 変更されたセルの配列から、変更があった行だけ抜き出す
for(i = 0; i < changedDatas.length; i++) {
changedRows.push(changedDatas[i][0]);
}
// 変更があった行番号の重複を排除
changedRows = changedRows.filter(function (x, i, self) {
return self.indexOf(x) === i;
});
// 変更があった行から、レコード追加か変更かを判断し、クエリをつくる
for(i = 0; i < changedRows.length; i++) {
if (records[changedRows[i]]["レコード番号"].value === null) {
insertRecords.push(
setParams(records[changedRows[i]])
);
} else {
updateRecords.push({
id: records[changedRows[i]]["レコード番号"].value,
record: setParams(records[changedRows[i]])
});
}
}
// 更新用bulkRequest
requests.push({
method: "PUT",
api: "/k/v1/records.json",
payload: {
app: kintone.app.getId(),
records: updateRecords
}
});
// 追加用bulkRequest
requests.push({
method: "POST",
api: "/k/v1/records.json",
payload: {
app: kintone.app.getId(),
records: insertRecords
}
});
// bulkrequestで一括で追加、更新。
// 失敗した場合はロールバックされる。
kintone.api('/k/v1/bulkRequest', 'POST', {requests: requests},
function(resp) {
console.dir(requests);
console.dir(resp);
callback(resp);
},
function(resp) {
errorCallback(resp);
}
);
};
// kintoneのレコード削除用メソッド
var deleteRecords = function(records, index, amount, callback, errorCallback) {
var i;
var ids = [];
for(i = index; i < index+amount; i++) {
ids.push(records[i]["レコード番号"].value);
}
kintone.api('/k/v1/records', 'DELETE', {app: kintone.app.getId(), ids: ids},
function(resp) {
callback(resp);
},
function(resp) {
errorCallback(resp);
}
);
};
// 定期的にkintone上のデータを再取得する
var autoload = function() {
setTimeout(function(){
getRecords(function(resp){
hot.loadData(resp.records);
});
autoload();
}, 10000); // 10秒。APIの呼び出し数の上限があるので、必要に応じて変更してください。
};
  // 一覧ビュー表示用のイベントハンドラ
kintone.events.on(['app.record.index.show'], function(event) {
if (event.viewId !== 7199) return;
var container = document.getElementById('sheet');
// handsontable初期化
hot = new Handsontable(container, {
// この時点ではdataは入力せず、あとから読み込ませるようにする。(データ更新時も再読み込みさせたいため)
data: [],
// 空白行
minSpareRows: 100,
// 表示したいカラム
colHeaders: ["レコード番号", "会社名", "先方担当者名", "見込み時期", "確度", "製品名", "単価", "ユーザー数", "小計"],
// コンテキストメニュー(右クリックメニュー)を指定。今回は削除用メニューのみ。
contextMenu: ["remove_row"],
// 必要に応じてreadOnlyの指定ができます。
columns: [
{data: "レコード番号.value", readOnly: true},
{data: "会社名.value"},
{data: "先方担当者名.value"},
{data: "見込み時期.value"},
{data: "確度.value"},
{data: "製品名.value"},
{data: "単価.value"},
{data: "ユーザー数.value"},
{data: "小計.value", readOnly: true}
],
// スプレットシート上のレコードを削除したときに呼び出されるイベント
// 引数indexは削除する行
// 引数amountは削除する行数
beforeRemoveRow: function(index, amount) {
var self = this;
// kintoneのレコードを削除する
deleteRecords(this.getSourceData(), index, amount,
function(resp){
console.dir(resp);
getRecords(function(resp){
// 削除後、データを再読み込み
self.loadData(resp.records);
});
},
function(resp){
console.dir(resp);
}
);
},
// スプレットシート上のレコードが編集されたときに呼び出されるイベント
afterChange: function (change, source) {
var self = this;
console.log(source);
// データ読み込み時はイベントを終了
if (source === 'loadData') {
return;
}
// kintoneのレコードを更新、追加する
saveRecords(this.getSourceData(), change,
function(resp){
console.dir(resp);
getRecords(function(resp){
// 更新後、データを再読み込み
self.loadData(resp.records);
},
function(resp){
// レコード取得失敗時に呼び出される
console.dir(resp);
});
},
function(resp){
// 更新・追加時に呼び出される
console.dir(resp);
}
);
}
});
// レコードを取得してhandsontableに反映
getRecords(function(resp){
hot.loadData(resp.records);
autoload();
});
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment