vendredi 31 juillet 2020

Grapesjs - Custom Checkbox Group

I am trying to create custom component type in grapejs, but not getting its documentation. Tried to write this plugin, but somehow its working partially, it render well when i drop it to canvas, but after refresh all checkboxes go away and static text Please update checkbox metadata for generating checkbox group appears.

I am also calling same checkbox render code in view: onRerender().

Please show some light.

const metaData = {
    name: 'checkbox-group',
    noOfCols: 2,
    class: 'checkbox-wrapper',
    checkboxes: `{
      "data": [
        {
          "label": "First",
          "value": "checkbox value"
        },
        {
          "label": "Second",
          "value": "checkbox value",
          "checked": true
        },
        {
          "label": "Third",
          "value": "checkbox value",
          "textbox": {
            "placeholder": "reason of choosing",
            "name": "other"
          }
        }
      ]
    }`,
  }
  
  const CustomCheckboxGroup = editor => {
    editor.DomComponents.addType('checkbox-group', {
      model: {
        defaults: {
          tagName: 'div',
          draggable: 'form, form *',
          droppable: false, 
          editable: false,
          traits: [
            'name',
            {
              type: 'text',
              name: 'class',
              label: 'class',
              changeProp: 1
            },
            { 
              type: 'text', 
              name: "checkboxMeta", 
              label: 'Checkbox Meta',
              changeProp: 1,
            },
            { 
              type: 'number', 
              name: "noOfCols", 
              label: 'Number of columns',
              changeProp: 1
            },
            {
              type: 'checkbox',
              name: 'required'
            }
          ],
          attributes: { name: metaData.name, required: true  },
          content: `Please update checkbox metadata for generating checkbox group`,
        },
        init(){
          this.on('change:noOfCols', this.handlePropChange);
          this.on('change:checkboxMeta', this.handlePropChange);
          this.on('change:attributes:name', this.handlePropChange);
          this.on('change:class', this.handlePropChange);
          this.on('change:attributes:required', this.updateRequired);
        },
        handlePropChange(){
          const el = this.getEl();
          const name = this.get('name') || Date.now().toString();
          const className = this.get('class') || metaData.class;
          const noOfCols = this.get('traits').where({name: 'noOfCols'})[0].get('value') || metaData.noOfCols;
          let checkboxesToGenerate = this.get('traits').where({name: 'checkboxMeta'})[0].get('value') || metaData.checkboxes;
          let generate = 0;
          const columns = [];
          if(checkboxesToGenerate.trim().length > 0) {
            generate = checkboxesToGenerate.length;
            try {
              checkboxesToGenerate = JSON.parse(checkboxesToGenerate).data;
              for (let i = noOfCols; i > 0; i--) {
                columns.push(checkboxesToGenerate.splice(0, Math.ceil(checkboxesToGenerate.length / i)));
              }
            } 
            catch(err) {
              console.log("Error :", err);
            }
          }
          el.innerHTML = "";
          if(generate > 0) {
            for (let j = 0; j < noOfCols; j++) {
              const data = columns[j];
              const column = (document.createElement("div") as HTMLElement);
              column.setAttribute('class', "col col-"+(j+1));
              column.style.width = (100 / noOfCols) + "%";
              if(data) {
                for(let i = 0; i < data.length; i++) {
                  const parentEle = (document.createElement("div") as HTMLElement);
                  parentEle.classList.add(className);
                  const checkboxEle = (document.createElement("input") as HTMLInputElement);
                  checkboxEle.setAttribute('class', 'checkbox');
                  checkboxEle.type = 'checkbox';
                  checkboxEle.name = name;
                  checkboxEle.value = data[i]['value'];
                  checkboxEle.id = name + '-' + j + '-'+ i;
                  checkboxEle.checked = data[i]['checked'];
                  var newlabel = document.createElement("Label");
                  newlabel.setAttribute("for", checkboxEle.id);
                  newlabel.innerHTML = data[i]['label'];
                  parentEle.appendChild(checkboxEle);
                  parentEle.appendChild(newlabel);
                  column.appendChild(parentEle);
                  if(data[i]['textbox']) {
                    var newTextBox = document.createElement("input");
                    newTextBox.setAttribute('type', 'text');
                    newTextBox.name = data[i]['textbox']['name'];
                    newTextBox.placeholder = data[i]['textbox']['placeholder'];
                    newTextBox.classList.add('hide');
                    // eslint-disable-next-line no-loop-func
                    checkboxEle.addEventListener('change', function(){
                      if(this.checked) {
                        newTextBox.classList.remove("hide");
                      } else {
                        newTextBox.classList.add('hide');
                      }
                    });
                    parentEle.appendChild(newTextBox);
                  }
                }
                el.appendChild(column);
              }
            }
          }
        }
      },
      view: {
        tagName: 'div',
        onRender({ el, model }) {
          const name = model.get('traits').where({name: 'name'})[0].get('value') || Date.now;
          const className = model.get('traits').where({name: 'class'})[0].get('value') || metaData.class;
          const noOfCols = model.get('traits').where({name: 'noOfCols'})[0].get('value') || metaData.noOfCols;
          let checkboxesToGenerate = model.get('traits').where({name: 'checkboxMeta'})[0].get('value') || metaData.checkboxes;

          let generate = 0;
          const columns = [];
          if(checkboxesToGenerate.trim().length > 0) {
            generate = checkboxesToGenerate.length;
            try {
              checkboxesToGenerate = JSON.parse(checkboxesToGenerate).data;
              for (let i = noOfCols; i > 0; i--) {
                columns.push(checkboxesToGenerate.splice(0, Math.ceil(checkboxesToGenerate.length / i)));
              }
            } 
            catch(err) {
              console.log("Error :", err);
            }
          }
          if(generate > 0) {
            for (let j = 0; j < noOfCols; j++) {
              const data = checkboxesToGenerate[j];
              const column = (document.createElement("div") as HTMLElement);
              column.setAttribute('class', "col col-"+(j+1));
              column.style.width = (100 / noOfCols) + "%";
              if(data) {
                for(let i = 0; i < data.length; i++) {
                  const parentEle = (document.createElement("div") as HTMLElement);
                  parentEle.setAttribute('class', className);
                  const checkboxEle = (document.createElement("input") as HTMLInputElement);
                  checkboxEle.setAttribute('class', 'checkbox');
                  checkboxEle.type = 'checkbox';
                  checkboxEle.name = name;
                  checkboxEle.value = data[i]['value'];
                  checkboxEle.id = name + '-' + j + '-'+ i;
                  checkboxEle.checked = data[i]['checked'];
                  
                  var newlabel = document.createElement("Label");
                  newlabel.setAttribute("for", checkboxEle.id);
                  newlabel.innerHTML = data[i]['label'];
                  parentEle.appendChild(checkboxEle);
                  parentEle.appendChild(newlabel);
                  column.appendChild(parentEle);
                  if(data[i]['textbox']) {
                    var newTextBox = document.createElement("input");
                    newTextBox.setAttribute('type', 'text');
                    newTextBox.name = data[i]['textbox']['name'];
                    newTextBox.placeholder = data[i]['textbox']['placeholder'];
                    newTextBox.classList.add('hide');
                    // eslint-disable-next-line no-loop-func
                    checkboxEle.addEventListener('change', function(){
                      if(this.checked) {
                        newTextBox.classList.remove("hide");
                      } else {
                        newTextBox.classList.add('hide');
                      }
                    });
                    parentEle.appendChild(newTextBox);
                  }
                }
                el.appendChild(column);
              }
            }
          }
        }
    })
  }
  export default CustomCheckboxGroup;



Aucun commentaire:

Enregistrer un commentaire