kintoneの案件で、「1つのカテゴリを選択したら、それに関連するサブカテゴリを選択できるようにしたい」という要望をよくいただきます。
例えば、ドロップボックスで「商品A」を選択したら、その商品のオプション「オプションA-1〜A-5」だけを選べるようにしたいといったケースです。
いくつか解決策はあるかと思いますが、その中でひとつjavascriptカスタマイズを使用して、機能を実装してみたいと思います。
カスタマイズはしたいけれど自分だけではできないという方は、カスタマイズ開発を1週間20万円という定額料金で提供していますので、弊社までお気軽にお問い合わせください。
主な仕様は以下のとおりとします。
- メインカテゴリに対してサブカテゴリを1階層作成する
- メインカテゴリで”A”を選択した場合はサブカテゴリA、”B”を選択した場合はサブカテゴリBのドロップダウンを選択可能にする
- 選択可能なサブカテゴリに値が指定されていない場合は登録時にエラーを表示する
- メインカテゴリに関連づいていないサブカテゴリに値が選択されている場合は、登録時に値を空にする
画面イメージはこんな感じです。
今回使用するフィールドは以下のとおりです。
フィールド名 | フィールドコード | タイプ | 値 |
---|---|---|---|
メインカテゴリ | main_category | ドロップボックス | A,B |
サブカテゴリA | sub_category_1 | ドロップボックス | A-1,A-2 |
サブカテゴリB | sub_category_2 | ドロップボックス | B-1,B-2 |
コードはこんなかんじで。
(function () { ///// // 大項目に紐付いた中項目を選択しているかをチェック ///// function checkSubCategory(event) { var record = event.record; //メインカテゴリが選ばれていない場合は処理を飛ばす if (record['main_category']['value'] === void 0 || record['main_category']['value'] === null || record['main_category']['value'] === '') { return event; } var main = record['main_category']['value']; //メインカテゴリ毎にサブカテゴリの選択状況をチェック switch(main) { case 'A' : //Aを選択している場合 if (record['sub_category_1']['value'] === void 0 || record['sub_category_1']['value'] === null || record['sub_category_1']['value'] === '') { record['sub_category_1']['error'] = "選択してください"; event.error = 'Aのサブカテゴリを選択してください。'; } record['sub_category_2']['value'] = []; //サブカテゴリBの値を削除しておく break; case 'B' : //Bを選択している場合 if (record['sub_category_2']['value'] === void 0 || record['sub_category_2']['value'] === null || record['sub_category_2']['value'] === '') { record['sub_category_2']['error'] = "選択してください"; event.error = 'Aのサブカテゴリを選択してください。'; } record['sub_category_1']['value'] = []; //サブカテゴリAの値を削除しておく break; } return event; } ///// // メインカテゴリを選択したら該当するサブカテゴリのdisableを解除する ///// function clearDisabledSubCategory(event) { var record = event.record; //メインカテゴリが選ばれていない場合は処理を飛ばす if (record['main_category']['value'] === void 0 || record['main_category']['value'] === null || record['main_category']['value'] === '') { return event; } //選択してるメインカテゴリによってサブカテゴリの選択を解除する switch(record['main_category']['value']) { case 'A' : //'A'を選択 record['sub_category_1']['disabled'] = false; //サブカテゴリAを選択可能 record['sub_category_2']['disabled'] = true; //サブカテゴリBは選択不可 break; case 'B' : //'B'を選択 record['sub_category_1']['disabled'] = true; //サブカテゴリAを選択不可 record['sub_category_2']['disabled'] = false; //サブカテゴリBは選択可能 break; } return event; } ///// // 初期状態は中項目をすべてdisabledに ///// function disabledSubCategory(event) { var record = event.record; //初期状態はすべて選択不可 record['sub_category_1']['disabled'] = true; record['sub_category_2']['disabled'] = true; //メインカテゴリが選ばれていない場合は処理を飛ばす if (record['main_category']['value'] === void 0 || record['main_category']['value'] === null || record['main_category']['value'] === '') { return event; } //選択してるメインカテゴリによってサブカテゴリの選択を解除する switch(record['main_category']['value']) { case 'A' : //'A'を選択 record['sub_category_1']['disabled'] = false; //サブカテゴリAを選択可能 record['sub_category_2']['disabled'] = true; //サブカテゴリBは選択不可 break; case 'B' : //'B'を選択 record['sub_category_1']['disabled'] = true; //サブカテゴリAを選択不可 record['sub_category_2']['disabled'] = false; //サブカテゴリBは選択可能 break; } return event; } // レコード新規画面の表示 kintone.events.on('app.record.create.show', disabledSubCategory); // レコード編集画面の表示 kintone.events.on('app.record.edit.show', disabledSubCategory); // レコード新規画面の保存前処理 kintone.events.on('app.record.create.submit', checkSubCategory); // レコード編集画面の保存前処理 kintone.events.on('app.record.edit.submit', checkSubCategory); // メインカテゴリの値を変更した際の処理(新規登録) kintone.events.on('app.record.create.change.main_category', clearDisabledSubCategory); // メインカテゴリの値を変更した際の処理(編集) kintone.events.on('app.record.edit.change.main_category', clearDisabledSubCategory); })();
レコード登録(編集)画面を開いた時にサブカテゴリを選択不可に
まず、レコード登録(編集)画面を開いた時にサブカテゴリを選択不可状態にします。登録画面を開いた時は app.record.create(edit).show を使用します。
//初期状態はすべて選択不可 record['sub_category_1']['disabled'] = true; record['sub_category_2']['disabled'] = true;
新規ではなく更新の時はすでにメインカテゴリが選択されていますので、もしメインカテゴリが選択されている場合は、関連するサブカテゴリを選択可能にする必要があります。
//選択してる大項目によって中項目の選択を解除する switch(record['main_category']['value']) { case 'A' : //'A'を選択 record['sub_category_1']['disabled'] = false; //サブカテゴリAを選択可能 record['sub_category_2']['disabled'] = true; //サブカテゴリBは選択不可 break; case 'B' : //'B'を選択 record['sub_category_1']['disabled'] = true; //サブカテゴリAを選択不可 record['sub_category_2']['disabled'] = false; //サブカテゴリBは選択可能 break; }
これで画面表示時の制御ができました。
メインカテゴリで選択された値でサブカテゴリを選択可能に
次にメインカテゴリで値を選択した場合に、関連するサブカテゴリを選択可能にします。ここではフィールドの値が変更されたら実行される app.record.create(edit).change.フィールドコード というイベントを利用します。
今回は、main_categoryが対象フィールドとなるので、新規登録時の場合は ‘app.record.create.change.main_category’ となります。
// メインカテゴリの値を変更した際の処理(新規登録) kintone.events.on('app.record.create.change.main_category', clearDisabledSubCategory); // メインカテゴリの値を変更した際の処理(編集) kintone.events.on('app.record.edit.change.main_category', clearDisabledSubCategory);
clearDisabledSubCategory では、登録(編集)画面表示時に実行した「メインカテゴリが選択された場合、関連するサブカテゴリを選択可能にする」実装をいれてあります。
サブカテゴリが未選択の場合はエラー
最後に保存時に選択したメインカテゴリに関連するサブカテゴリが選択されていない場合にエラーにします。イベントは app.record.create(edit).submit になります。
//メインカテゴリ毎にサブカテゴリの選択状況をチェック switch(main) { case 'A' : //Aを選択している場合 if (record['sub_category_1']['value'] === void 0 || record['sub_category_1']['value'] === null || record['sub_category_1']['value'] === '') { record['sub_category_1']['error'] = "選択してください"; event.error = 'Aのサブカテゴリを選択してください。'; } record['sub_category_2']['value'] = []; //サブカテゴリBの値を削除しておく break; case 'B' : //Bを選択している場合 if (record['sub_category_2']['value'] === void 0 || record['sub_category_2']['value'] === null || record['sub_category_2']['value'] === '') { record['sub_category_2']['error'] = "選択してください"; event.error = 'Aのサブカテゴリを選択してください。'; } record['sub_category_1']['value'] = []; //サブカテゴリAの値を削除しておく break; }
登録時には選択したメインカテゴリに関連していないサブカテゴリの値をクリアしておきます。そうすることで必ず選択したカテゴリのサブカテゴリの値だけが残るようになります。
record['sub_category_2']['value'] = []; //サブカテゴリBの値を削除しておく
この場合、サブカテゴリ毎にフィールドを作成しなければいけないといった制約がでてしまいますが、比較的簡単に関連づいたサブカテゴリを作ることができます。