今回のアップデート(2016/05/08 の定期メンテナンスにおけるkintone API、User API更新情報)の中で地味そうに見えてJavaScriptカスタマイズを劇的に楽にしてくれる内容がありました。フィールド値変更イベントにおける「変更されたフィールドやサブテーブルの行オブジェクトの取得」です!
早速見ていきましょう。
サンプルアプリ
契約内容を記入するサブテーブルを含む次のようなアプリを考えてみたいと思います。
| フィールド名 | フィールドコード(フィールドタイプ) | 利用目的 |
|---|---|---|
| 項目 | 契約一覧/項目(サブテーブル/文字列1行) | 契約内容 |
| 契約年数 | 契約一覧/契約年数(ドロップダウン) | 契約年数 |
| 契約開始日 | 契約一覧/契約開始日(サブテーブル/日付) | 契約開始日 |
| 契約終了日 | 契約一覧/契約終了日(サブテーブル/日付) | 契約終了日 |
| コメント | レコード内コメント一覧/コメント(サブテーブル/文字列複数行) | コメント |
JavaScriptカスタマイズ
JavaScriptコーディング
/*
* Dependencies:
* Moment.js ( https://js.cybozu.com/momentjs/2.10.6/moment-with-locales.min.js )
*/
(function() {
"use strict";
kintone.events.on([
'app.record.create.change.契約開始日',
'app.record.edit.change.契約開始日',
'app.record.create.change.契約年数',
'app.record.edit.change.契約年数'
], function(event) {
var changes = event.changes;
// 契約開始日が入力されている時
if(changes['row'].value['契約開始日'].value){
changes['row'].value['契約終了日'].value
= moment(changes['row'].value['契約開始日'].value)
.add(parseInt(changes['row'].value['契約年数'].value), 'year')
.subtract(1, 'day')
.format('YYYY-MM-DD');
}
// 契約年数が未定義になった時
if(!changes['row'].value['契約年数'].value){
changes['row'].value['契約終了日'].value = null;
}
return event;
});
})();
アプリの動作
「契約開始日」と「契約年数」の変更時イベントを設定したため、「契約開始日」と「契約年数」に応じて、これらと同じ行の「契約終了日」がセットされます。

changesオブジェクトの考察
まず、event.changesオブジェクトは次のような内容になっています。
"changes": {
"field": {
"type": "DATE",
"value": "2016-05-08"
},
"row": {
"id": null,
"value": {
"契約年数": {
"type": "DROP_DOWN",
"value": "3"
},
"契約終了日": {
"type": "DATE"
},
"契約開始日": {
"type": "DATE",
"value": "2016-05-08"
},
"項目": {
"type": "SINGLE_LINE_TEXT",
"value": "kintoneプラグイン年間契約"
}
}
}
}
変更したフィールドそのものである「field」プロパティと変更した行を指す「row」プロパティをその配下に持っています。この構造を見ると、特にevent.changes.row変更行に注目したカスタマイズを可能にしていることが分かります。先のJavaScriptコードと合わせて見て頂くとわかりますが、大切なのは注目した変更行に含まれるフィールドへの値のセットが「return event」によってなされるということです。フィールド値変更時イベントで、event.changes.rowを取得して、書き換えて、「return event」でセットして書き換えを反映するという流れが成立するとも言い換えられます。「今までevent.recordオブジェクトでやっていたことを、サブテーブル中の変更行に対してevent.changes.rowオブジェクトでおこなえるようになった」という表現でお分かり頂ける方も多いと思います。
まとめ
今回はMoment.jsを使って変更行の日付セットを例示しましたが、サブテーブルの変更に対するカスタマイズが楽になったことがおわかり頂けたのではないでしょうか。
ただ、実はちょっと美味しくないケースが1つだけあります。「kintone.Promiseを紐解く」で述べていますが、変更時イベントはkintone.Promiseオブジェクトをreturn出来ないため、非同期処理を経由した値のセットは「return event」では実現できません。今回追加されたchangesオブジェクトは、get/setが可能なrecordオブジェクトの場合と異なり代替方法もありません。サブテーブルで独自ルックアップの実装等が必要なケースで欲しい機能ですので、変更時イベントでもkintone.Promiseオブジェクトをreturn出来ることが出来ると嬉しいなぁと思います。今後に期待ですね!
