見出し画像

ラジオボタンで動的に変化するドロップダウンリストの実装

やりたいこと

kintoneアプリで、ラジオボタンの値を変更するとリスト値が動的に変化するドロップダウンリストを設置します。
仕組みとしては、フォームのラジオボタンの値で別アプリのレコードを条件検索して、ドロップダウンリストの値として動的に取得・表示します。
この機能は、kintone標準機能のドロップダウンリストでは出来ません。
kintone UI Component v1を利用したJavascriptカスタマイズ例です
本稿では、標準のドロップダウンリストと区別するために、カスタマイズするドロップダウンリストを「KUC版Dropdwon」と呼びます。

kintone UI Componentについて

kintone UI Componentを使用することで、JavaScript 内で HTML の要素や属性を書いたり、CSS で色や大きさなどを変更する必要なく、簡単に kintone ライクな UI (ユーザーインターフェイス)を作成できます。
kintone UI Component は、V0が2023年12月31日でセキュリティ対策を含むメンテナンス対応が終了したので、kintone UI Component v1の利用が推奨となっています。

https://cybozu.dev/ja/kintone/sdk/library/kintone-ui-component-v1/

デモ画面

デモ画面は、ラジオボタン「分類」の値「男性用/女性用」の変更イベントで、外部参照アプリ(商品マスタ)のレコードを「分類」値で検索した結果を、KUC版Dropdwonのリスト値にセットしています。

動的に値が変化するドロップダウンリストのデモ画面

アプリの設定方法

(1)アプリの準備

KUC版Dropdwonを設置するアプリと、外部参照される商品マスターアプリを準備します。
必要なフィールド名(フィールドコード)は以下の通りです。
フィールド名は自由ですが()内のフィールドコードは、Javascriptの設定と合わせる必要が有ります。
また、分類の設定値(男性用、女性用)は、レコード絞り込み検索に用いる検索キーなので、2つのアプリ間で同じ設定値にする必要が有ります。
<KUC版Dropdwonを設置するアプリ>
・ラジオボタン:フィールド名:分類(分類
・文字列1行 :フィールド名:商品名(商品名
・スぺ―ス  :スペース要素ID(DropdownLIST_Space

KUC版Dropdwonリスト設置アプリ

<外部参照される商品マスターアプリ>
・文字列1行 :フィールド名:商品コード(商品コード
・文字列1行 :フィールド名:商品名(商品名
・ラジオボタン:フィールド名:分類(分類
 ※分類は、ラジオボタン又はドロップダウンリストで設定して下さい

外部参照される商品マスターアプリ

(2)動的ドロップダウンリストのJavascriptコード

kintone UI Component v1を利用したカスタマイズ例です。
ドロップダウンリストのデータを取得する関数の検索クエリ部分が未完成ですが、ご自身の要望に合わせて工夫してみて下さい。
kintoneAPIでのクエリの書き方は、以下のサイトが参考になります。

/* ラジオボタンで動的に他アプリの値を参照するドロップダウンリスト */
(function() {
  'use strict';

  // 初期設定(ドロップダウン設置側アプリ)
  const MAIN_APP_CATEGORY_FIELD = '分類';      // ラジオボタンのフィールドコード
  const MAIN_OUTPUT_FIELD = '商品名';          // ドロップダウンリストの値を保存するフィールドコード
  const MAIN_SPACE_ID = 'DropdownLIST_Space';  // ドロップダウンリストを配置するスペース要素ID

  // 初期設定(外部参照するアプリ)
  const REF_APPID = 123;         // 参照するアプリID
  const REF_FIELDS = {
    ListCategory: '分類',       // 参照するアプリ側の分類コード
    ListSortKey:  '商品コード', // 参照するアプリ側のリスト値のソートキー
    ListValue:    '商品名'      // 参照するアプリ側のリスト値のフィールドコード
  };
//-------- 初期設定はここまで -------- //

  // ドロップダウンリストのデータを取得して設置する関数
  function setupDropdown(classification) {
    const query = // ここに分類コードで検索&ソートするクエリを記述します。
      app: REF_APPID,
      query: query
    };

    kintone.api(kintone.api.url('/k/v1/records', true), 'GET', body, function(resp) {
      const records = resp.records;

      let items = records.map(record => ({
        'label': record[REF_FIELDS.ListValue].value, //ドロップダウンリストのラベル
        'value': record[REF_FIELDS.ListValue].value  //ドロップダウンリストの値
      }));

      // ドロップダウンリストの先頭に未選択項目を追加
      items.unshift({label: '----', value: ''});

      // KUC版Dropdownリストの作成
      const dropdown = new Kuc.Dropdown({ 
        label: '商品名',
        requiredIcon: true,
        items: items,
        value: kintone.app.record.get().record[MAIN_OUTPUT_FIELD].value || "", // 編集時の初期値をフィールドから設定
        className: 'options-class',
        id: 'options-id',
        visible: true,
        disabled: false
      });

      // スペースへドロップダウンリストを追加
      const space = kintone.app.record.getSpaceElement(MAIN_SPACE_ID);
      if (space) {
        while (space.firstChild) {
          space.removeChild(space.firstChild); // スペース要素をリセット
        }
        space.appendChild(dropdown);  // スペース要素に描画
      }

      // ドロップダウンリストのイベント処理
      dropdown.addEventListener('change', event => {
        let record = kintone.app.record.get();
        record.record[MAIN_OUTPUT_FIELD].value = event.detail.value;  // ドロップダウンで選択された項目の値
        kintone.app.record.set(record);
      });
    }, function(error) {
      console.log(error);  // デバッグ用
    });
  }

  // 動作イベントの設定
  kintone.events.on(['app.record.create.show', 'app.record.edit.show'], function(event) {
    const record = event.record;
    const classificationValue = event.record[MAIN_APP_CATEGORY_FIELD].value;
    setupDropdown(classificationValue);
    kintone.app.record.setFieldShown(MAIN_OUTPUT_FIELD, false);  // 値保存用フィールドの非表示
    return event;
  });

  // 新規レコード登録画面と編集画面で「分類」フィールドの変更を監視
  kintone.events.on(['app.record.create.change.' + MAIN_APP_CATEGORY_FIELD, 'app.record.edit.change.' + MAIN_APP_CATEGORY_FIELD], function(event) {
    const classificationValue = event.record[MAIN_APP_CATEGORY_FIELD].value;
    setupDropdown(classificationValue);
    return event;
  });

})();

(3)Javascriptコードの初期設定

初期設定で最初にKUC版Dropdwon設置側アプリのフィールドコードやスペース要素IDを設定します。
 ラジオボタンフィールドコードは「分類」を指定します。
 商品名の文字一行フィールドコードは「商品名」にします。
 ここに「KUC版Dropdwon」で選択された値が保存されます。
 商品名の右横スペースは「KUC版Dropdwon」の表示場所です。
 スペース要素IDは「DropdownLIST_Space」とします。

※必ずKUC版Dropdwon設置側アプリ側のフィールドコードやスペース要素IDと合わせるように設定します。

次に外部参照される商品マスターアプリの初期設定を行います。
REF_APPIDに、外部参照されるアプリIDを指定します。
アプリ画面を開き、https://[サブドメイン].cybozu.com/k/に続いて表示されている末尾の数字がアプリIDです。

アプリIDの確認方法

REF_FIELDSの配列には、外部参照アプリのフィールドコードを指定します。
・ListCategory :分類コード(検索キーになります)
・ListSortKey :商品コード(ソートキーになります )
・ListValue  :商品名KUC版Dropdwonに表示する値)

※必ず「商品マスター」などの外部参照されるアプリのフィールドコードと合わせるように設定して下さい。

(4)アプリの設定>JavaScript / CSSでカスタマイズ

KUC版Dropdwon」を設置する側アプリの、アプリの設定>JavaScript / CSSでカスタマイズの画面で、kintone UI ComponentのCDNをURL指定で追加し、次に初期設定済のJavascriptコードをアップロードして追加します。

最新版の kintone UI Component は、以下のCDNで利用できます。https://unpkg.com/kintone-ui-component/umd/kuc.min.js

https://kintone-ui-component.netlify.app/ja/docs/getting-started/quick-start/
JavaScript / CSSでカスタマイズ画面

最後に、アプリの更新を完了させれば、設定は完了です。

【注意事項】 2024/04/16加筆

kintone UI ComponentのCDN版は動作試験の目的でのみご利用ください。
本番環境で利用する際はUDM版が推奨です。
詳しくは、以下の記事を参照して下さい。


KUC版ドロップダウンリストの横幅を変更する

外部参照する商品名の名前が長いと、ドロップダウンリストの横幅が短く感じるので、CSSカスタマイズで横幅を長くしてみました。
KUC版Dropdwonのプロパティ設定で「id値」を指定していれば、用意されているCSSプロパティを用いたカスタムCSSファイルの作成とアップロードでデザインの変更が可能です。
下記のCSSコードは、ドロップダウンリストの横幅を320pxに変更します。

#options-id {
    --kuc-dropdown-toggle-width: 320px;
  }

カスタマイズした感想

Javascriptカスタマイズでも、kintoneの標準入出力パーツ(フィールド)のプロパティを操作すること(設定値の変更等)は出来ませんでした。
kintone UI Component
は、kintoneライクな入出力パーツのオブジェクトを生成して専用のプロパティを操作出来るので、この様なカスタマイズも可能になることが良く分かりました。

kintone UI Componentを利用したJavascriptカスタマイズ例は、面白いので今後も少しづつ続けていく予定です。

最後まで読んで頂き、ありがとうございました。

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