kintoneカスタマイズに利用できそうな、ES2019-2020の機能を調べてみました。
Object.fromEntries [ES2019]
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries
Object.entriesでObjectからArrayにしたものを,再びObjectに戻すことができます. Object.entriesと合わせて使うと,recordオブジェクトなどに対してループ処理ができて非常に便利です.
サンプル
詳細画面にボタンを設置し,レコードコピー機能を実装します. POSTの際,recordオブジェクトから組み込みフィールドを除外する処理が必要です. 除外処理にObject.fromEntriesを利用してみます.
kintone.events.on([
'app.record.detail.show',
], (event) => {
const presetFieldTypes = [
'RECORD_NUMBER',
' __ID__',
' __REVISION__',
'CREATOR',
'MODIFIER',
'CREATED_TIME',
'UPDATED_TIME',
'CATEGORY',
'STATUS',
'STATUS_ASSIGNEE',
];
const removePresetFields = (record) => {
// 後述
};
const copyButton = document.createElement('a');
copyButton.innerText = 'copy';
kintone.app.record.getHeaderMenuSpaceElement().appendChild(copyButton);
copyButton.addEventListener('click', () => {
kintone.api(kintone.api.url('/k/v1/record', true), 'POST', {
app: kintone.app.getId(),
// record: event.record // これはエラーなる.
record: removePresetFields(event.record) // 組み込みフィールドを削除しておく.これならOK.
}).then((response) => {
alert('copied');
location.href = './show#record=' + response.id;
});
});
});
上述のremovePresetFieldsについて,Object.fromEntries利用なしと利用ありを比較します.
・Object.fromEntries利用なし
const removePresetFields = (record) => {
return Object.entries(record).filter(
([fieldCode, field]) => !presetFieldTypes.includes(field.type)
).reduce((filteredRecord, [fieldCode, field]) => ({
...filteredRecord,
[fieldCode]: field
}), {});
};
reduceを使ってArrayからObjectに戻す必要があり,複雑です.
・Object.fromEntries利用あり
const removePresetFields = (record) => {
return Object.fromEntries(
Object.entries(record).filter(
([fieldCode, field]) => !presetFieldTypes.includes(field.type)
)
);
};
Object.fromEntriesで囲むだけなので簡単です.
よく使う,mapやfilterなどは関数化するのも良いですね.
https://hfuji.hatenablog.jp/entry/2019/04/30/223722
Optional Chaining [ES2020]
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Optional_chaining
「.」(チェーン演算子)と似ていますが,オブジェクトチェーンの参照がnullishでもエラーを出さないようにできます. こちらにある通り,レコード追加画面では未入力の「文字列 (1行)」フィールドのvalueプロパティは「undefined」となります. 従来の「.」(チェーン演算子)で参照して,Stringオブジェクトのメソッド等を呼び出そうとするとエラーとなります.
サンプル
「文字列 (1行)」フィールドにバリデーションを設定します.
kintone.events.on([
'app.record.create.submit',
'app.record.edit.submit',
], (event) => {
if(/* 後述 */){
event.record['文字列__1行_'].error = '半角英数のみ入力できます.';
}
return event;
});
上述のif文の()内について,Optional Chaining利用なしと利用ありを比較します.
・Optional Chaining利用なし
if(!(event.record['文字列__1行_'].value && event.record['文字列__1行_'].value.match(/^[A-Za-z0-9]*$/)))
エラーを避けるために「&&」(AND演算子)を用いる必要があり,冗長になります.
・Optional Chaining利用あり
if(!event.record['文字列__1行_'].value?.match(/^[A-Za-z0-9]*$/))
「.」から「?.」に置き換えるだけで,シンプルになりますね.
Nullish Coalescing [ES2020]
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator
「||」(OR演算子)と似ていますが,左がnullish以外の場合は全て左を返します. 「‘’」(空文字)と「undefined」を区別したい場合などに役立つと思います.
サンプル
レコード詳細画面で,「文字列 (1行)」フィールドが存在する場合はそのvalueを,存在しない場合は’default value’を変数に格納します.(こちらにある通り,レコード詳細画面では未入力の「文字列 (1行)」フィールドのvalueプロパティは「‘’」(空文字)となります.)
kintone.events.on([
'app.record.detail.show',
], (event) => {
const hoge = /* 後述 */
});
Nullish Coalescing利用なしと利用ありを比較します.
・Nullish Coalescing利用なし
const hoge = event.record['文字列__1行_'] ? event.record['文字列__1行_'].value : 'default value';
三項演算子を用いる必要があり,冗長になります.
・Nullish Coalescing利用あり
const hoge = event.record['文字列__1行_']?.value ?? 'default value';
Optional ChainingとNullish Coalescingを組み合わせてシンプルに書けます.