見出し画像

アプリのフィールド表示/非表示をラジオボタンの値で切り替える

やりたいこと

ラジオボタンの値の変更で、別フィールドの表示/非表示を変更したい。
操作ミスを防ぐために、ラジオボタンの状態で入力しなくても良いフィールドは見えない様にしたい。
例として、kintoneアプリストアの「問診表」アプリを用いてラジオボタンの値でフィールドの表示と非常時を切り替える機能を実装してみます。

問診表アプリの検索結果

参考にした記事(Cybouz Developer Network)

アプリストアの問診表アプリ用に、フィールドの表示/非表示を切り替えるJavascriptコードが紹介されています。
しかし「問診表アプリ専用のコード設計」となっており汎用性は低いので、本記事では、できるだけ汎用性の高いコードになる様に工夫してみました。

デモ画面

デモ画面では、ラジオボタンの値によって、入力フィールドの表示/非表示を切り替えています。
※性別=「女」の場合に「妊娠中ですか?」を確認するフィールドを追加しました。

問診表アプリのフィールド表示切替デモ

フィールドの表示/非表示を制御するJavascriptコード

/* ラジオボタンの値でフィールドの表示/非表示を制御 */
(function() {
    "use strict";

    /* 初期設定
       1つ目:選択肢のフィールドコード
       2つ目:表示するラジオボタンの値
       3つ目:表示/非表示を切り替えるフィールドコード(複数指定可)
       4つ目:非表示時にフィールドの値をクリアする(true)/しない(false)
    */
    const fieldSettings = {
        '選択肢1': { showValue: '表示値1', fields: ['field_1A', 'field_1B'],clearOn: false },
        '選択肢2': { showValue: '表示値2', fields: ['field_2A', 'field_2B'],clearOn: true },
        '選択肢3': { showValue: '表示値3', fields: ['field_3A', 'field_3B'],clearOn: true },
        '選択肢4': { showValue: '表示値4', fields: ['field_4A', 'field_4B'],clearOn: true },
        '選択肢5': { showValue: '表示値5', fields: ['field_5A', 'field_5B'],clearOn: true }
    };

    // フィールドの表示/非表示と値のクリアを設定する関数
    function toggleFieldVisibility(record, radioButtonCode, settings) {
        const isVisible = record[radioButtonCode].value === settings.showValue;
        settings.fields.forEach(fieldCode => {
            kintone.app.record.setFieldShown(fieldCode, isVisible);
            if (!isVisible && settings.clearOn) {
                record[fieldCode].value = null;
            }
        });
    }

    // イベントハンドラの登録
    Object.keys(fieldSettings).forEach(radioButtonCode => {
        const settings = fieldSettings[radioButtonCode];
        kintone.events.on([
            'app.record.create.show', 'app.record.edit.show',
            'app.record.create.change.' + radioButtonCode, 'app.record.edit.change.' + radioButtonCode
        ], function(event) {
            let record = event.record;
            toggleFieldVisibility(record, radioButtonCode, settings);
            return event;
        });
    });
})();

初期設定で、以下の4種類の設定を連想配列で指定します。
①ラジオボタンのフィールドコード
②表示する状態を判定するラジオボタンの値
③ラジオボタンと連携するフィールドコード(複数指定可)
④非表示モードで値のクリアを実行する/しないの設定

以下に、デモ画面の問診表アプリの設定例を示します。
※設定例が分かり易いようにオリジナルの「問診表アプリ」のフィールドコードを、漢字のフィールドコードに変更しています。

    /* 初期設定
       1つ目:選択肢のフィールドコード
       2つ目:表示するラジオボタンの値
       3つ目:表示/非表示を切り替えるフィールドコード(複数指定可)
       4つ目:非表示時にフィールドの値をクリアする(true)/しない(false)
    */
    const fieldSettings = {
        '性別': { showValue: '女',   fields: ['妊娠', '妊娠歴'],clearOn: false },
        '選択肢2':  { showValue: 'ある', fields: ['予防接種名'],clearOn: true },
        '選択肢3':  { showValue: 'はい', fields: ['病名', '発症時期'],clearOn: false },
        '選択肢4':  { showValue: 'ある', fields: ['原因', '症状'],clearOn: false },
        '選択肢5':  { showValue: 'ある', fields: ['詳細'],clearOn: true }
    };

【注意】
設定は、フィールド名ではなく「フィールドコード」を設定して下さい。
上記のコードは動作検証済ですので、もし動作しない場合は、フィールドコードの設定値がアプリ側と一致しているか確認して下さい。


複数選択フィールドの値で別フィールドの表示/非表示

上記のカスタムコードは、ラジオボタン(又はドロップダウン)用であり、複数選択フィールドでは動作しません。
複数選択フィールドは、入力内容が配列で格納されるため、配列を意識した別ロジックで処理する必要が有ります。

でも問診表アプリには、「今までかかったことのある病気はありますか?」という病歴の複数選択があり、選択肢にない病歴は「その他フィールド」に入力する仕様となっていますので、複数選択でも別フィールドの表示切替を実現してみたいと思います。

複数選択フィールドで「その他」を選択したら「その他フィールド」を表示するカスタムコードを別途に作成して設定する例を示します。

デモ画面

以下のデモ画面では、ラジオボタンと複数選択の両方で別フィールドの表示/非表示を切り替えています。

複数選択でフィールドの表示/非表示の切り替え

複数選択肢で別フィールドの表示/非表示切替のJavascript

(function() {
    "use strict";

    /* 初期設定
       1つ目:複数選択フィールドコード
       2つ目:表示する値
       3つ目:表示/非表示を切り替えるフィールドコード(複数指定可)
       4つ目:非表示時にフィールドの値をクリアする(true)/しない(false)
    */
    const fieldSettings = {
        '複数選択1': { showValue: 'その他', fields: ['Field_1A'], clearOn: false },
     // '複数選択2': { showValue: '選択2', fields: ['Field_2A', 'Field_2B'], clearOn: true }
    };

    // フィールドの表示/非表示を設定する関数
    function toggleFieldVisibility(record, multiSelectCode, settings) {
        // 複数選択フィールドの値を配列として扱う
        const selectedValues = record[multiSelectCode].value;
        const isVisible = selectedValues.includes(settings.showValue);

        settings.fields.forEach(fieldCode => {
            kintone.app.record.setFieldShown(fieldCode, isVisible);
            if (!isVisible && settings.clearOn) {
                record[fieldCode].value = null;
            }
        });
    }

    // イベントハンドラの登録
    Object.keys(fieldSettings).forEach(multiSelectCode => {
        const settings = fieldSettings[multiSelectCode];
        kintone.events.on([
            'app.record.create.show', 'app.record.edit.show',
            'app.record.create.change.' + multiSelectCode, 'app.record.edit.change.' + multiSelectCode
        ], function(event) {
            let record = event.record;
            toggleFieldVisibility(record, multiSelectCode, settings);
            return event;
        });
    });
})();

初期設定方法は、ラジオボタン版と同じです。
初期設定で複数選択肢フィールドを2つ以上設定できる仕様になっていますが、今回は1つだけなので、2つ目の設定をコメント化しています。

コードの汎用性と保守性について

今回はJavascriptコードを「ラジオボタン版」と「複数選択版」で2つに分けて作成ました。
もちろん1つのコードに集約することも出来ますが、そうするとIF分岐が増えて処理が複雑になりコードの保守性も低下します。

カスタムコードをあえて機能別に2つに分けることで、コードの用途が広がり、アプリの保守も簡単になりますので、1つのコードに沢山の機能を詰め込むよりも機能別に分割して作成する方が、個人的には良いと思います。


簡易なフィールド非表示の例

簡易なフィールド非表示の処理は、以下の記事も参考にしてください。
ドロップダウンリストの値が「その他」の場合だけ、文字列1行フィールドを表示するという処理を実装しています。


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