新規投稿
フォローする

kintone UI Componentを使ってサブテーブル内フィールドのDOMをカスタマイズ

kintoneのサブテーブル内のDOM要素を取得できるkintone APIはないので、サブテーブル内フィールドのDOMのカスタマイズは比較的困難です。 カスタマイズの方法としては、タグ名や属性値をもとに目的のDOM要素を取得するか、スペース要素内にテーブルごと自作することなどが挙げられます。 前者の方法は、kintoneのバージョンアップによって動作しなくなる可能性があるため非推奨とされています。 今回は後者の「スペース要素内にテーブルごと自作する」をkintone UI Componentを使って実現し、フィールドのカスタマイズを行いました。
※本記事の方法では、テーブルの行ごとにフィールドを制御することはできません。あらかじめご了承ください。

サンプル

ラジオボタンの値によって、サブテーブル内の「アレンジ」フィールドのフィールドタイプを切り替えます。 

フォーム設定

コード

まず、kintone-ui-component.min.jsとkintone-ui-component.min.cssを登録したのち、下記sample.jsを登録します。

sample.js

(function() {
  "use strict";
  kintone.events.on([
    'app.record.create.show',
    'app.record.edit.show',
  ], function(event){
    kintone.app.record.setFieldShown('Table', false); //もとのサブテーブルを非表示
    SubTable.prototype.getFieldProperties().then(function(){ //フォーム設定の取得
      var table = new SubTable('Table', 'tableSpace').setDefaultFields().createTable(event.record); //kintone UI Componentを用いてサブテーブルを複製
      //ここからアレンジ
      var radio = new kintoneUIComponent.RadioButton({
        items: [
          {value: '自由入力', label: '自由入力'},
          {value: '1つ選択', label: '1つ選択'},
          {value: '複数選択', label: '複数選択'},
        ],
        name: 'radio',
        value: '自由入力'
      });
      var items = [
        {value: 'sample1', label: 'sample1'},
        {value: 'sample2', label: 'sample2'},
      ];
      kintone.app.record.getSpaceElement('radioSpace').appendChild(radio.render());
      radio.on('change', function(value){
        var arrange;
        if(value == '自由入力'){
          arrange = new kintoneUIComponent.Text();
        }else if(value == '1つ選択'){
          arrange = new kintoneUIComponent.RadioButton({
            items: items
          });
        }else{
          arrange = new kintoneUIComponent.CheckBox({
            items: items
          });
        }
        table.setField('アレンジ', arrange);
        table.reload();
      });
      //ここまでアレンジ
    });
    return event;
  });
  //サブテーブル複製用のコンストラクタ
  var SubTable = (function(fieldCode, spaceId){
    function SubTable(fieldCode, spaceId){
      this.fieldCode = fieldCode;
      this.spaceId = spaceId;
      this.fieldProperties = SubTable.prototype.appFieldProperties[fieldCode].fields;
      this.fields = {};
    };
    SubTable.prototype = {
      getFieldProperties: function(){
        return kintone.api(kintone.api.url('/k/v1/app/form/fields', true), 'GET', {
          app: kintone.app.getId(),
        }).then(function(response){
          SubTable.prototype.appFieldProperties = response.properties;
        });
      },
      setDefaultFields: function(){
        for(var fieldCode in this.fieldProperties){
          this.setDefaultField(this.fieldProperties[fieldCode]);
        }
        return this;
      },
      setDefaultField: function(fieldProperty){
        var options = {};
        if(fieldProperty.options){
          options.items = Object.keys(fieldProperty.options).map(function(option){
            return {
              index: fieldProperty.options[option].index,
              value: fieldProperty.options[option].label,
              label: fieldProperty.options[option].label
            };
          });
          options.items.sort(function(a, b){
            return a.index > b.index;
          });
          if(fieldProperty.type === 'DROP_DOWN'){
            options.items.unshift({
              value: '',
              label: '-----'
            });
          }
        }
        if(fieldProperty.defaultValue){
          options.value = fieldProperty.defaultValue;
        }
        switch(fieldProperty.type){
          case 'SINGLE_LINE_TEXT':
            this.fields[fieldProperty.code] = new kintoneUIComponent.Text();
            break;
          case 'DROP_DOWN':
            this.fields[fieldProperty.code] = new kintoneUIComponent.Dropdown(options);
            break;
          case 'CHECK_BOX':
            this.fields[fieldProperty.code] = new kintoneUIComponent.CheckBox(options);
            break;
          case 'MULTI_SELECT':
            this.fields[fieldProperty.code] = new kintoneUIComponent.MultipleChoice(options);
            break;
          case 'RADIO_BUTTON':
            this.fields[fieldProperty.code] = new kintoneUIComponent.RadioButton(options);
            break;
        }
      },
      setField: function(fieldCode, KUC){
        this.fields[fieldCode] = KUC;
      },
      createTable: function(record){
        var _this = this;
        this.table = new kintoneUIComponent.Table({
          rowTemplate: Object.keys(this.fields).map(function(fieldCode){return _this.fields[fieldCode]}),
          header: Object.keys(this.fields)
        });
        this.renderTable();
        this.setValue(record);
        this.setEvents();
        return this;
      },
      renderTable: function(){
        kintone.app.record.getSpaceElement(this.spaceId).appendChild(this.table.render());
      },
      setValue: function(record){
        var _this = this;
        this.table.setValue(record[this.fieldCode].value.map(function(row){
          return Object.keys(_this.fields).map(function(fieldCode){
            if(_this.fields[fieldCode].getItems){
              if(Array.isArray(row.value[fieldCode].value)){
                return row.value[fieldCode].value.filter(function(value){
                  return _this.fields[fieldCode].getItems().some(function(item){
                    return item.value === value;
                  });
                });
              }else{
                if(_this.fields[fieldCode].getItems().some(function(item){
                  return item.value === row.value[fieldCode].value;
                })){
                  if(_this.fields[fieldCode].getItem){
                    return [row.value[fieldCode].value];
                  }else{
                    return row.value[fieldCode].value;
                  }
                }else{
                  if(_this.fields[fieldCode].getItem){
                    return [];
                  }else{
                    return _this.fields[fieldCode].getItems()[0].value;
                  }
                }
              }
            }else{
              return row.value[fieldCode].value;
            }
          });
        }));
      },
      setEvents: function(){
        var _this = this;
        ['rowAdd', 'rowRemove', 'cellChange'].forEach(function(eventName){
          _this.table.on(eventName, function(data){
            _this.setRecord(data.tableValue);
          });
        });
      },
      setRecord: function(tableValue){
        var _this = this;
        var event = kintone.app.record.get();
        tableValue = tableValue || this.table.getValue();
        event.record[this.fieldCode].value = tableValue.map(function(row){
          return {value: row.reduce(function(cells, cell, index){
            var fieldCode = Object.keys(_this.fields)[index];
            var fieldType = _this.fieldProperties[fieldCode].type;
            if(!cell && (fieldType === 'CHECK_BOX' || fieldType === 'MULTI_SELECT')){
              cell = [];
            }
            cells[fieldCode] = {
              type: fieldType,
              value: cell
            };
            return cells;
          }, {})};
        });
        kintone.app.record.set(event);
      },
      reload: function(){
        this.table.hide();
        this.createTable(kintone.app.record.get().record);
      }
    };
    return SubTable;
  })();
})();

※本コードでは、カラムの表示順はもとのサブテーブルと一致しない可能性があります。 また、「文字列 (1行)」、「ドロップダウン」、「チェックボックス」、「複数選択」、「ラジオボタン」以外のフィールドタイプのフィールドを含むサブテーブルに対しては動作しません。

0

0件のコメント

サインインしてコメントを残してください。