フィールド値の変更イベント
kintone では、ユーザーがフィールドの値を変更したタイミングで JavaScript の処理を実行できる「フィールド値変更イベント」が用意されています。このイベントを使うことで、あるフィールドの値に応じて別のフィールドの値を自動計算したり、入力制限を動的に変更したりすることが可能です。
この記事では、フィールド値変更イベントの基本的な使い方から、実践的な活用パターンまで詳しく解説します。
フィールド値変更イベントとは
フィールド値変更イベントは、レコードの作成画面・編集画面において、特定のフィールドの値が変更されたときに発火するイベントです。
イベント名は以下の形式で指定します。
app.record.create.change.{フィールドコード} // レコード作成画面での変更
app.record.edit.change.{フィールドコード} // レコード編集画面での変更
モバイル版の場合は、先頭に mobile. が付きます。 - mobile.app.record.create.change. {フィールドコード} - mobile.app.record.edit.change.{フィールドコード}
対応しているフィールドタイプ
すべてのフィールドタイプが変更イベントに対応しているわけではありません。対応しているフィールドタイプは以下の通りです。
| フィールドタイプ | 発火タイミング |
|---|---|
| 文字列(1行) | フォーカスが外れた時 |
| 数値 | フォーカスが外れた時 |
| 日付 | 値が変更された時 |
| 時刻 | 値が変更された時 |
| 日時 | 値が変更された時 |
| ドロップダウン | 選択が変更された時 |
| ラジオボタン | 選択が変更された時 |
| チェックボックス | 選択が変更された時 |
| 複数選択 | 選択が変更された時 |
| リンク | フォーカスが外れた時 |
| ルックアップ | ルックアップの取得が完了した時 |
文字列(複数行)やリッチエディターには変更イベントは対応していません。これらのフィールドの値変更を検知したい場合は、保存イベント(submit)で検証する方法を検討してください。
基本的な使い方
ドロップダウンの変更を検知する
ドロップダウンの値が変更されたタイミングで処理を実行する基本的な例です。
(() => {
'use strict';
const events = [
'app.record.create.change.優先度',
'app.record.edit.change.優先度',
];
kintone.events.on(events, (event) => {
const record = event.record;
const priority = record['優先度'].value;
console.log(`優先度が「${priority}」に変更されました`);
return event;
});
})();
フィールドの値を変更する
変更イベント内で、他のフィールドの値を変更することができます。event.record のフィールドの value を書き換えて return event することで反映されます。
(() => {
'use strict';
// 単価または数量が変更されたタイミングで合計金額を自動計算する
const events = [
'app.record.create.change.単価',
'app.record.create.change.数量',
'app.record.edit.change.単価',
'app.record.edit.change.数量',
];
kintone.events.on(events, (event) => {
const record = event.record;
const unitPrice = Number(record['単価'].value) || 0;
const quantity = Number(record['数量'].value) || 0;
// 合計金額を自動計算して設定
record['合計金額'].value = unitPrice * quantity;
return event;
});
})();
変更イベント内でフィールドの値を変更する場合、kintone.app.record.set は不要です。event.record
の値を直接書き換えて return event するだけで反映されます。
テーブル内フィールドの変更イベント
サブテーブル内のフィールドにも変更イベントを使用できます。テーブル内フィールドの場合、event.changes プロパティから変更された行の情報を取得できます。
(() => {
'use strict';
const events = [
'app.record.create.change.明細_単価',
'app.record.edit.change.明細_単価',
'app.record.create.change.明細_数量',
'app.record.edit.change.明細_数量',
];
kintone.events.on(events, (event) => {
const record = event.record;
// テーブル全行の小計を再計算し、合計も算出する
let total = 0;
record['明細テーブル'].value.forEach((row) => {
const unitPrice = Number(row.value['明細_単価'].value) || 0;
const quantity = Number(row.value['明細_数量'].value) || 0;
const subtotal = unitPrice * quantity;
row.value['明細_小計'].value = subtotal;
total += subtotal;
});
record['合計金額'].value = total;
return event;
});
})();
テーブルの行の追加・削除を検知するには、テーブルフィールドコード自体に対する変更イベント
app.record.create.change.{テーブルフィールドコード} を使用します。
テーブル行の追加・削除の検知
サブテーブルのフィールドコードに対して変更イベントを登録すると、行の追加・削除を検知できます。
(() => {
'use strict';
const events = [
'app.record.create.change.明細テーブル',
'app.record.edit.change.明細テーブル',
];
kintone.events.on(events, (event) => {
const rows = event.record['明細テーブル'].value;
console.log(`テーブルの行数: ${rows.length}`);
// 行数に応じた処理(例: 行数が上限を超えた場合に警告)
if (rows.length > 20) {
event.record['明細テーブル'].error = '明細は20行以内で入力してください';
} else {
event.record['明細テーブル'].error = null;
}
return event;
});
})();
ルックアップの変更を検知する
ルックアップフィールドの値が取得されたタイミングで、関連するフィールドの制御を行うパターンです。
(() => {
'use strict';
const events = [
'app.record.create.change.顧客名',
'app.record.edit.change.顧客名',
];
kintone.events.on(events, (event) => {
const record = event.record;
const customerName = record['顧客名'].value;
if (customerName) {
// ルックアップで顧客名が取得されたら、関連フィールドを入力不可にする
record['顧客住所'].disabled = true;
record['顧客電話番号'].disabled = true;
} else {
// ルックアップがクリアされたら、入力可能に戻す
record['顧客住所'].disabled = false;
record['顧客電話番号'].disabled = false;
}
return event;
});
})();
show イベントとの組み合わせ
画面表示時(show イベント)と変更時(change イベント)を組み合わせることで、初期状態の設定とリアルタイムな連動を両立できます。
(() => {
'use strict';
/**
* カテゴリの値に応じてフィールドの表示・入力制限を更新する
* @param { Object } record - レコードオブジェクト
*/
const applyCategory = (record) => {
const category = record['カテゴリ'].value;
const isBug = category === 'バグ';
// バグの場合のみ「再現手順」「影響範囲」を表示
kintone.app.record.setFieldShown('再現手順', isBug);
kintone.app.record.setFieldShown('影響範囲', isBug);
// バグの場合は優先度を「高」に自動設定
if (isBug && !record['優先度'].value) {
record['優先度'].value = '高';
}
};
// 画面表示時に初期設定
kintone.events.on(['app.record.create.show', 'app.record.edit.show'], (event) => {
applyCategory(event.record);
return event;
});
// カテゴリが変更されたら連動して更新
kintone.events.on(
['app.record.create.change.カテゴリ', 'app.record.edit.change.カテゴリ'],
(event) => {
applyCategory(event.record);
return event;
}
);
})();
注意点
変更イベントは非同期処理に対応していない
変更イベントのコールバック関数は、非同期処理(async/await)に対応していません。REST API の呼び出しなど非同期処理が必要な場合は、保存イベント(submit)で実行するか、ボタンクリックなど別のトリガーで処理する設計を検討してください。
以下のコードは期待通りに動作しません。変更イベントでは return event が同期的に返される必要があります。
// ⚠ 動作しないコード
kintone.events.on('app.record.create.change.顧客コード', async (event) => {
const response = await kintone.api('/k/v1/record.json', 'GET', { app: 10, id: 1 });
event.record['顧客名'].value = response.record['名前'].value;
return event; // 非同期のため kintone に正しく反映されない
}); プログラムによる値変更では発火しない
event.record 内のフィールドの値をプログラムで変更しても、変更イベントは発火しません。変更イベントはあくまでユーザーが画面上で値を操作した場合にのみ発火します。
まとめ
app.record.create.change.{フィールドコード}でフィールド値の変更を検知できる- ドロップダウン、ラジオボタン、チェックボックス、日付、数値など多くのフィールドタイプに対応
- テーブル内フィールドやテーブルの行追加・削除も検知可能
showイベントと組み合わせることで、初期表示と変更時の両方に対応できる- 変更イベントは非同期処理に対応していない点に注意
- プログラムによる値変更では発火しないため、ロジックの設計に注意が必要