サブテーブルの並び替え
kintone のサブテーブル機能を使用すると、レコード内で 1:n の関係を表現できます。
便利な機能ですが、行数が増えると見づらくなります。例えば、日付と内容のフィールドを持つサブテーブルでタスクを管理している場合、行を追加し続けるだけでは、最新のタスクを探しにくくなります。
この記事では、サブテーブルの行を指定したフィールドの値で並び替え、保存する JavaScript カスタマイズを紹介します。
2 つの行を比較する関数を作成
まず、2 つの行の大小を比較する関数を作成します。
引数と返り値は、Array.prototype.sort() の比較関数に合わせます。
以下は、サブテーブル内の日付フィールドを降順(新しい順)に並び替える例です。
const compareRows = (rowA, rowB) => {
const timeA = new Date(rowA.value['日付フィールド'].value).getTime();
const timeB = new Date(rowB.value['日付フィールド'].value).getTime();
return timeB - timeA;
};
昇順(古い順)にする場合は、timeA - timeB を返します(未入力の行の扱いは次の注意を参照)。
日付フィールドが未入力の行は値が空文字列になり、new Date('').getTime() は NaN を返します。NaN を含む比較は結果が不定になり、並び順が崩れる原因になります。未入力の行を末尾にまとめたい場合は、NaN を -Infinity に置き換えるなどの処理を加えてください。
const toTime = (value) => {
const time = new Date(value).getTime();
return Number.isNaN(time) ? -Infinity : time;
};
const compareRows = (rowA, rowB) => {
const timeA = toTime(rowA.value['日付フィールド'].value);
const timeB = toTime(rowB.value['日付フィールド'].value);
if (timeA === timeB) {
return 0;
}
return timeA < timeB ? 1 : -1; // 降順。未入力の行は末尾になる(昇順にする場合は 1 と -1 を入れ替える。未入力の行は先頭になる)
};
なお、-Infinity - -Infinity は NaN になるため、上記のように引き算ではなく大小比較で書いています。
ソート処理を実装
続いて、サブテーブルを並び替える処理を記述します。sort() は配列を直接書き換えるため、戻り値を受け取る必要はありません。
サブテーブルの行は event.record['フィールドコード'].value に配列として格納されています。ここで指定するのは、フィールドIDではなくフィールドコードです。
kintone.events.on のコールバック関数内で実行する場合
レコードの保存時に自動で並び替えるには、保存実行前イベントを利用します。
kintone.events.on(['app.record.create.submit', 'app.record.edit.submit'], (event) => {
event.record['サブテーブルのフィールドコード'].value.sort(compareRows);
return event;
});
return event を忘れると、変更がレコードに反映されません。
独自のタイミングで実行する場合
ボタンのクリック時など、イベントのコールバック関数の外で実行する場合は、event オブジェクトを使えません。kintone.app.record.get() でレコード情報を取得し、並び替えたあとに kintone.app.record.set() で画面に反映します。
/** 実行時のレコード情報 */
const { record } = kintone.app.record.get();
// サブテーブルの行を並び替え
record['サブテーブルのフィールドコード'].value.sort(compareRows);
// レコード情報をセット
kintone.app.record.set({ record });
kintone.app.record.set() は、レコードの追加・編集画面でのみ利用できます(get() は詳細画面でも利用できます)。set() は画面上の値を書き換えるだけで、保存は行いません。変更を確定するには、ユーザーがレコードを保存する必要があります。