kintoneでサブテーブルの列を非表示にする方法【コード解説】

kintoneでサブテーブルの列を非表示にする方法【コード解説】

以前、サブテーブルの背景色を変更する方法をメモしましたが、

列を非表示にしたいとの需要が発生したので、メモしておきます。

少なくとも自社内で1件、案件として1件発生しているので、需要が0ではないはず・・・。

サブテーブルのフィールドを操作するAPIが提供されていない為、DOM操作による実現です。

完成形

やりたい事は以下の通りで、あるフィールド(今回はラジオボタン)の値に応じて、
サブテーブルの指定のフィールド(数値)を表示/非表示したい。

コード

先に全体コードから。

思ったよりボリュームでてしまった。

細かいエラーハンドリングは割愛しています。

jQuery.noConflict();
(function($) {
    "use strict";

    const SHOW_EVENTS = [
        "app.record.create.show",
        "app.record.edit.show",
        "app.record.detail.show",
    ];
    
    const CHANGE_EVENTS = [
        "app.record.create.change.Table",
        "app.record.edit.change.Table",
        "app.record.create.change.ラジオボタン",
        "app.record.edit.change.ラジオボタン",
    ];
    
    // 表示制御するフィールド
    const FIELD_ID = "5536090";

    // 表示制御実行用関数
    const setFieldVisible = function(record) {
        const state = record["ラジオボタン"]["value"];
        const displayState = (state === "表示" ? "" : "none");
        $('.label-' + FIELD_ID).css({
            display: displayState
        });
        $('.field-' + FIELD_ID).parent().css({
            display: displayState
        });
    };
    
    // DOM要素検索用関数
    const findElement = function() {
        return new kintone.Promise(function(resolve, reject) {
            const MAX_FIND_COUNT = 10;
            let counter = 0;
            
            // 実際に一定間隔でDOM要素を検索する関数
            const findElementAtInterval = function() {
                counter++;
                // th要素とtd要素が取得できた場合のみ表示制御処理実行
                if ($('.label-' + FIELD_ID).length > 0 && $('.field-' + FIELD_ID).length > 0) {
                    clearInterval(intervalId);
                    resolve();
                } else {
                    if (counter >= MAX_FIND_COUNT) {
                        clearInterval(intervalId);
                        reject();
                    }
                }
            };
            // 一定間隔でDOM要素検索関数を実行
            let intervalId = setInterval(findElementAtInterval, 100);
        });
    };
    
    kintone.events.on(SHOW_EVENTS, function(e) {
        // レコード表示イベント時は、DOM要素が発見できてから表示制御
        findElement().then(function() {
            setFieldVisible(e.record);
        });
        return e;
    });
    
    kintone.events.on(CHANGE_EVENTS, function(e) {
        setFieldVisible(e.record);
        return e;
    });
})(jQuery);

フィールドIDを確認する

フィールドIDは私が勝手に呼んでいるだけですが・・・。

(フィールド名、フィールドコードは公式で呼ばれている名前なので)

kintoneでは、アプリのフィールドに自動的に採番されるIDらしき数列があるようで、それをフィールドIDとして、今回対象フィールドの判定に使用しています。

フィールドIDはどうやって確認するかというと、デバッグモードでゴソゴソと確認します・・・。

Chromeだと、以下のようにF12を押してからDOM要素を解析できます。

設定されているクラスのlabel-XXXXXXXのXXXXXX部分がフィールドIDです。
(下図の場合、5536090

取得したフィールドIDは以下のように定数で保持。

const FIELD_ID = "5536090";

サブテーブルの要素はすぐに表示されない

大きなポイントとしてはこの点でしょうか。

表示イベントの直後にはサブテーブルのth要素は表示されますが、td要素は表示されないようでした。

その為、以下の様にsetInterval()で対象DOM要素を発見するまで繰り返し検索しています。

第1引数は実行関数、第2引数は実行間隔(ms)

 let intervalId = setInterval(findElementAtInterval, 100);

setIntervalの挙動に関しては、Qiitaの記事を参考にさせていただきました。

対象要素が取得できたら表示制御処理を実行する

上記検索処理で要素が取得できたときにPromiseを返し、表示制御処理を実行しています。

    kintone.events.on(SHOW_EVENTS, function(e) {
        // レコード表示イベント時は、DOM要素が発見できてから表示制御
        findElement().then(function() {
            setFieldVisible(e.record);
        });
        return e;
    });

おわりに

のんびり待っていればAPIが実装されるかもですが、

そんなに待てない!という方は参考にしていただければと思います。

kintoneカテゴリの最新記事