見出し画像

ルックアップのコピーフィールドを編集可能にする(テーブル内を含む)

やりたいこと

Kintoneのルックアップでコピーしたフィールドを編集可能にしたい。
テーブル内でルックアップしたコピーフィールドも編集可能にしたい。
※今回は、テーブル内フィールドの操作方法が本題です

Kintoneのルックアップは便利な機能ですが、参照元のアプリから値をコピーする様に設定したフィールドは編集できない仕様です。
(他アプリの値をコピーする前提なので編集不可なのが当然です)

以下の受注管理アプリでは、顧客名をルックアップして担当部署と電話番号をコピーしています。受注明細テーブルでは、商品マスタをルックアップして単価と商品名をコピーしています。
赤枠で囲ったフィールドがルックアップ機能でコピーされたフィールドで、標準機能では「編集できない」状態になっています。

受注管理アプリのルックアップフィールドの事例

しかし中小企業の現場では、ルール通りには行かない「例外処理」が頻繁に発生しますので、情シス担当者を悩ませる標準機能では難しい要望事項が出ることが良くあります。「ルックアップのコピーフィールドを編集できる様にして欲しい」という要望も良くあるケースの一つです。
例)受注管理で一部の案件だけ取引先の担当部署が変わる場合など

また、受注管理アプリでテーブルを使用して商品マスタからルックアップでコピーした単価を案件別に「変更したい」というケースもあると思います。
(こちらは実際に、お客様から要望を頂いたケースがあります)


フィールドの編集モードの切り替え

フィールドの編集可/不可の状態は、Javascriptカスタマイズでフィールドのdisableプロパティを操作することで切り替えが可能です。

record[フィールドコード名].disabled = true;  // 編集不可
record[フィールドコード名].disabled = false; // 編集可能

(1)テーブル外の単体フィールドの編集モード切替

テーブル外の単体フィールドの編集モードを切替するサンプルコードを下記に示します。
受注管理アプリで顧客マスタのルックアップ機能でコピーした「担当部署」と「電話番号」フィールドのプロパティを編集可能に変更しています。
初期設定(対象フィールドコード)部分を変更すれば、他のアプリにも適用することが可能です。

単体フィールド(テーブル外)を編集可能にするJavascript

/* ルックアップのコピーフィールドを編集可能にする */
// 初期設定(対象フィールドコード)
const editableFields = ['担当部署', '電話番号'];

// レコード編集イベント
kintone.events.on(['app.record.create.show', 'app.record.edit.show'], (event) => {
    const record = event.record;
    editableFields.forEach((field) => {
        record[field].disabled = false; // 編集可能にする
    });
    return event;
});

フィールドの編集可否を条件付きで変更したい方は以下の過去記事を参考にしてください。

(過去記事)フィールドの編集可否を切り替えるカスタマイズ例


(2)テーブル内フィールドの編集モード切替

それでは今回の本題です。
テーブル内のルックアップでコピーしたフィールドを編集可能にする処理を考えます。フィールドの編集可/不可は、disableプロパティを操作することで切り替えが可能です。
但し、テーブル内フィールドのプロパティ操作は、テーブルの構造(行数)を考慮した以下の処理が必要になります。

1.テーブルの行数分だけ処理を繰り返す
2.テーブルの行毎に操作対象フィールドの数だけ処理を繰り返す
3.テーブル内フィールドが未定義(undefine)になるケースのエラー回避

1番の行数と2番のフィールド数の入れ子状態のループ処理が必要です。
3番は、テーブル内フィールドが未定義(undefine)状態でプロパティ操作するとコードエラーが発生しますので、エラー回避の対応が必要です。
未作成(未定義)のフィールドのプロパティは「存在しない」からです。
※テーブル内フィールドが「未定義」の状態は、レコード新規登録とテーブル行追加のイベントで発生します。

処理フロー図

テーブル内フィールドの処理方法を言葉だけで説明しても分かり難いので、自分用に簡単な処理フロー図も作成してみました。

テーブル内フィールドの処理フロー図

デモ画面

受注管理アプリに実装したデモ画面です。
顧客名のルックアップでコピーした担当部署と電話番号が編集可能です。
受注明細テーブル内の商品コードのルックアップでコピーした単価と商品名も編集可能になっています。

ルックアップでコピーしたフィールドを編集可能にしたデモ画面

テーブル内フィールドを編集可能にするJavascriptコード

テーブル内のルックアップで値をコピーする編集不可フィールドを編集可能にするサンプルコードを以下に掲載します。
初期設定のサブテーブルコード名と操作対象フィールドコードの配列内容を変更すれば、他のアプリにも適用が可能です。

// 初期設定
const subtableCode = '受注明細';  // サブテーブルコード名
const editableFields = ['単価','商品名'];  // 操作対象フィールドコードの配列

// テーブル内フィールドを編集可能にする関数
function makeFieldEditable(record) {
    const subtableRows = record[subtableCode].value;
    if (subtableRows && Array.isArray(subtableRows)) {
        subtableRows.forEach(row => {
           editableFields.forEach(field => {
               // 未定義フィールドにはデフォルト値を設定
               if (!row.value[field]) {
                   row.value[field] = {value: ''};  // デフォルト値の設定
               }
               // フィールドを編集可能に設定
               row.value[field].disabled = false;
           });
       });
    }
    return record;
}

//関数の呼び出し例
kintone.events.on(['app.record.create.show', 'app.record.edit.show'], (event) => {
      makeFieldEditable(event.record);
      return event;
});

条件分岐も少ないので、割と短いコード(約40行以下)です。
その代わり、例外処理やエラーハンドリングを厳密に行ってません。
その辺が気になるという方は、ご自身で工夫してみて下さい。

【注意事項】
ルックアップしたコピーフィールドを編集しても、ルックアップを再実行すると参照元フィールドの値で上書きされるので、運用面で注意が必要です。

※レコード保存時にルックアップを自動実行するプラグインやカスタマイズと併用はできません。


カスタマイズした感想

今回は、ルックアップ機能でコピーしたフィールドを編集可能にする事例でしたが、主目的はサブテーブル内フィールドの操作方法の検証でした。
フィールドの表示/非表示や編集可/不可を切り替えるカスタマイズ事例はこれまで複数回取り上げましたが、サブテーブル内フィールドのプロパティを操作するカスタマイズ事例は、本記事が初めてかもしれません。

テーブル内フィールドを参照するには、テーブルの行数情報が必要なことも今回のカスタマイズの事例で新しく知ることができました。
行数.value[フィールドコード]で参照します。
テーブル内フィールドのプロパティ操作では、レコード新規登録とテーブル行追加のイベントで「フィールドが未定義(undefine)です」という意味のコードエラーが発生するので、これを回避する方法で少し悩みました。

新規登録画面、編集画面、テーブルの行追加・削除等のイベント種類やフィールド状態で条件分枝を増やすと、コードがどんどん複雑になるので、最終的に「フィールドが未定義(false)の場合はデフォルト値をセットする」という単純な方法にしました(処理フロー図参照)

このエラー回避の方法(デフォルト値をセット)は、少し手抜きに見えるかもしれませんが、例外処理で条件分枝を増やして複雑なコードにするよりもシンプルな対応方法でコードも短くなるので、自分では気に入っています。

今回も、最後まで読んで頂いてありがとうございました。

よろしければサポートお願いします! いただいたサポートは、note記事制作の活動費に使わせていただきます!