チェックボックスの項目を一部階層化したい

JavaScript未経験者です。

チェックボックスの項目を一部階層化したいです。

拙いですが画像で実装したいイメージを作成しました。

チェックボックスフィールド:お夕飯

上記フィールドで"中華"にチェックが入ったら、または、"中華"の横の+ボタンを押下したら

麻婆豆腐や青椒肉絲のリストが一階層下に出現する、といった形が望ましいです。

または、麻婆豆腐系のチェックボックスのみ、+ボタンでの開閉をするだけでも構いません。

お知恵をお貸しください。

よろしくお願いいたします。

 

 

それぞれの料理(麻婆豆腐…)のチェックボックスフィールドを新たに作り、そのチェックボックスフィールドを「お夕飯」の値に応じて表示・非表示等の制御をする形ではいかがでしょうか。以下のような形で可能です。

(() => {
  'use strict';

  let dinner = 'お夕飯'; // お夕飯のフィールドコード
let foods = {
  '和食': '和食',
  '洋食': '洋食',
  '中華': '中華'
}; // 左に「お夕飯」のチェックボックスの値 右に各料理のチェックボックスのフィールドコード

  kintone.events.on([
  'app.record.detail.show', 'app.record.create.show', 'app.record.edit.show',
  `app.record.create.change.${dinner}`, `app.record.edit.change.${dinner}`
], (event) => {
  let record = event.record;

  Object.keys(foods).forEach((food) => {
    if (record[dinner].value.includes(food)) {
        kintone.app.record.setFieldShown(foods[food], true);
    } else {
      kintone.app.record.setFieldShown(foods[food], false);
      record[foods[food]].value = [];
    }
  });

    return event;
});
})();

mls-hashimoto様

ご回答ありがとうございます。

ご教示の通りにしてみましたが、思った通りに動かすことができません。

全て表示されたままとなってしまいます。

また、kintone上のJavaScriptのデバック方法もわからず、画面とコードのみで恐縮ですが

お教えいただけましたら幸いです。

※フィールド名=フィールドコードにしています

 

(() => {
  ‘use strict’;

  let dinner = ‘お夕飯’; // お夕飯のフィールドコード
  let foods = {
    ‘和食’: ‘TEST1’,
    ‘洋食’: ‘TEST2’,
  }; // 左に「お夕飯」のチェックボックスの値 右に各料理のチェックボックスのフィールドコード

  kintone.events.on([
    ‘app.record.detail.show’, ‘app.record.create.show’, ‘app.record.edit.show’,
    app.record.create.change.${dinner}, app.record.edit.change.${dinner}
  ], (event) => {
    let record = event.record;

    Object.keys(foods).forEach((food) => {
      if (record[dinner].value.includes(food)) {
        kintone.app.record.setFieldShown(foods[food], true);
      } else {
        kintone.app.record.setFieldShown(foods[food], false);
        record[foods[food]].value = [];
      }
    });

    return event;
  });
})();

田中千穂 さま

当方環境では動作しております。順番に原因を探していきましょう。
まず、デバッグですがGoogleChromeをお使いであれば「Ctrl + Shift + I」で起動するほか適当なところで右クリック→検証を選択でもデベロッパーツールが起動します(他のブラウザでもほとんどデベロッパーツールは付随しています)。

エラーがあればコンソールに表示されます。プログラムが実行しているかどうかもコンソールに出力するように変更しましたので、以下でコンソールに表示されるものを教えて下さい。

(() => {
  'use strict';

  let dinner = 'お夕飯'; // お夕飯のフィールドコード
let foods = {
  '和食': 'TEST1',
  '洋食': 'TEST2',
  '中華': 'TEST3'
}; // 左に「お夕飯」のチェックボックスの値 右に各料理のチェックボックスのフィールドコード

  kintone.events.on([
  'app.record.detail.show', 'app.record.create.show', 'app.record.edit.show',
  `app.record.create.change.${dinner}`, `app.record.edit.change.${dinner}`
], (event) => {
  let record = event.record;

    console.log(record[dinner].value);

    Object.keys(foods).forEach((food) => {
    if (record[dinner].value.includes(food)) {
      kintone.app.record.setFieldShown(foods[food], true);
    } else {
      kintone.app.record.setFieldShown(foods[food], false);
      record[foods[food]].value = [];
    }
  });

    return event;
});
})();

 

mls-hashimoto様

ご回答ありがとうございます。

お恥ずかしながらコンソールの場所がおかげ様でようやくわかりました。

日本語が文字化けしているようです。文字コード指定をする必要があるでしょうか。

show.js:138 Uncaught TypeError: Cannot read properties of undefined (reading ‘value’)
  at download.do?app=*****(社用環境URLに該当するため念のため伏せさせていただきます)
    at show.js:272:116
    at new il (show.js:139:431)
    at qea (show.js:272:95)
    at show.js:271:412
    at e.o (show.js:141:327)
    at xl (show.js:143:366)
    at ul (show.js:143:249)
    at il.N (show.js:1281:103)
    at bl (show.js:139:274)

 

(() => {
  ‘use strict’;

  let dinner = ‘���[��’; // ���[�т̃t�B�[���h�R�[�h
  let foods = {
    ‘�a�H’: ‘TEST1’,
    ‘�m�H’: ‘TEST2’,
    ‘����’: ‘TEST3’
  }; // ���Ɂu���[�сv�̃�F�b�N�{�b�N�X�̒l �E�Ɋe�����̃�F�b�N�{�b�N�X�̃t�B�[���h�R�[�h

  kintone.events.on([
    ‘app.record.detail.show’, ‘app.record.create.show’, ‘app.record.edit.show’,
    app.record.create.change.${dinner}, app.record.edit.change.${dinner}
  ], (event) => {
    let record = event.record;

    console.log(record[dinner].value);

    Object.keys(foods).forEach((food) => {
      if (record[dinner].value.includes(food)) {
        kintone.app.record.setFieldShown(foods[food], true);
      } else {
        kintone.app.record.setFieldShown(foods[food], false);
        record[foods[food]].value = [];
      }
    });

    return event;
  });
})();

 

田中千穂 さま

そうですね。文字コードはUTF-8である必要があります(�は他の文字コードからUTF-8に変換できなかった場合の記号です)。

mls-hashimoto様

ご回答ありがとうございます。

おかげ様で、無事実装することができました。

 

尚、ドリルダウンというか、左の項目に紐づいたような見え方にするのは、難しいでしょうか。

重ね重ね恐縮ですが、よろしくお願いいたします。

田中千穂 さま

 

最初に添付された画像のような動作にすることも可能ではありますが、非推奨のDOM操作になります。

以下のような形になります。フォーム設定時に親となるチェックボックス(お夕飯)と子となるチェックボックス(各料理)が同じ行に配置されている必要があります。

「fieldCode」にはそれぞれのフィールドコード、「fieldElement」にはそれぞれのフィールドに割り振られている番号(Chromeであれば対象のフィールドを右クリック→検証を選択すると「field-xxxxxxx」と記載されています)を設定して下さい。

(() => {
  'use strict';

  let dinner = {
  fieldCode: 'お夕飯',
  fieldElement: 'value-xxxxxxx'
};
let foods = {
  '和食': {
    fieldCode: 'TEST1',
    fieldElement: 'field-xxxxxxx'
  },
  '洋食': {
    fieldCode: 'TEST2',
    fieldElement: 'field-xxxxxxx'
  },
  '中華': {
    fieldCode: 'TEST3',
    fieldElement: 'field-xxxxxxx'
  }
};

  kintone.events.on([
  'app.record.detail.show', 'app.record.create.show', 'app.record.edit.show',
  `app.record.create.change.${dinner.fieldCode}`, `app.record.edit.change.${dinner.fieldCode}`
], (event) => {
  let record = event.record;
  let checks = [...document.getElementsByClassName(dinner.fieldElement)[0].firstChild.children];

    checks.forEach((check) => {
    let checkboxField = document.getElementsByClassName(foods[check.innerText].fieldElement)[0];

      if (record[dinner.fieldCode].value.includes(check.innerText)) {
      kintone.app.record.setFieldShown(foods[check.innerText].fieldCode, true);
      check.style.paddingBottom = `${checkboxField.clientHeight + 20}px`;
      checkboxField.style.position = 'absolute';

      let rect = check.getBoundingClientRect();
      let parentRect = check.parentNode.getBoundingClientRect();

        checkboxField.style.top = `${rect.top - parentRect.top + 70}px`;
      checkboxField.style.left = `${rect.left + window.scrollX + 30}px`;
    } else {
      kintone.app.record.setFieldShown(foods[check.innerText].fieldCode, false);
      record[foods[check.innerText].fieldCode].value = [];
      check.style.paddingBottom = null;
      checkboxField.style.position = null;
      checkboxField.style.top = null;
      checkboxField.style.left = null;
    }
  });

    return event;
});

  kintone.events.on('app.record.detail.show', (event) => {
  let record = event.record;

    Object.keys(foods).forEach((food) => {
    if (!record[dinner.fieldCode].value.includes(food)) kintone.app.record.setFieldShown(foods[food].fieldCode, false);
  });

    return event;
});
})();

 

チェックボックスフィールドの背景は透明のため、アプリのテーマ配色に応じて背景色等の装飾を行って下さい。

mls-hashimoto様

ご回答ありがとうございます。

まず、作成いただいたgifですが、まさに想像通りです。ありがとうございます。

お時間割いていただき、コードのご教示も重ね重ね御礼申し上げます。

>非推奨のDOM操作になります

非推奨とのことで、ここまで凝った挙動の実装は、今回は見送ることとなりました。

 

丁寧にご回答ご教示いただきまして、誠にありがとうございました。