Issue #1632Opened December 5, 2018by cnaa975 reactions

[QUESTION] control table cell (add row, column..)

Question

Hello. I want to dev some of feature to control the table.

There are many feature for table the other editor like add columns, rows, set color, reset column width for each cell...

I just have a dev plan to implementation on below..

1. add a button on block manager

bm.add('table-block', {
  id: 'table',
  label: 'Table',
  category: 'Basic',
  attributes: { class: 'fa fa-table' },
  content: `
      <table class="table table-striped table-bordered table-resizable">
          <tr><td></td><td></td><td></td></tr>
          <tr><td></td><td></td><td></td></tr>
          <tr><td></td><td></td><td></td></tr>
      </table>
    `,
});

this is a dummy table 3x3. each cell have a text component.

2018-12-05 17-11-35 2018-12-05 17_12_04

2. customize toolbar on cell

{
    defaults: {
      ...Component.prototype.defaults,
      type: 'cell',
      tagName: 'td',
      draggable: ['tr'],
      toolbar: [
        {
          attributes: { class: "fa fa-arrows" },
          command: "tlb-move"
        },
        {
          attributes: { class: "fa fa-flag" },
          command: "table-insert-row-above"
        }
      ]
    },
  },

add a custom command to insert row above.

3. Add a command in order to insert a row

run(editor, sender, opts) {
  var domComponents = editor.DomComponents;

  domComponents.addComponent({
      tagName: 'table',
      removable: true, // Can't remove it
      draggable: true, // Can't move it
      copyable: true, // Disable copy/past
      style: { background: 'red'},
      attributes: { title: 'here' },
      content: `<tr data-gjs-type="row" data-highlightable="1">
         <td data-gjs-type="cell" data-highlightable="1" style="min-width: 100px;"><div data-gjs-type="text" data-highlightable="1"></div></td>
    });
}

2018-12-05 17-14-10 2018-12-05 17_16_29

But the problem is...

  1. Cannot detect the cell's location. above code just add on canvas below. not inside cell.
  2. Cannot add multiple components into the cell. It just added only one depth. but need to add muitiple depth. (tr > td * 3)

Anyone have a nice idea? I cannot find a awesome plugin.

Have a nice day.

Answers (3)

shubhd47October 7, 20193 reactions

Hey, @cnaa97 No worries I have added the default commands in the toolbar. I got what I wanted. Thanks for helping.

Below is the code

        const blockManager = this._editor.BlockManager;
        blockManager.add('table-block', {
          id: 'table',
          label: 'Table',
          category: 'Basic',
          attributes: { class: 'fa fa-table' },
          content: `
              <table class="table  table-bordered table-resizable">
                  <tr><td></td><td></td><td></td></tr>
                  <tr><td></td><td></td><td></td></tr>
                  <tr><td></td><td></td><td></td></tr>
              </table>
            `,
        });
        const TOOLBAR_CELL = [
          {
            attributes: { class: "fa fa-arrows" },
            command: "tlb-move"
          },
          {
            attributes: { class: "fa fa-flag" },
            command: "table-insert-row-above"
          },
          
          {
            attributes: {class: 'fa fa-clone'},
            command: 'tlb-clone',
          },
          {
            attributes: {class: 'fa fa-trash-o'},
            command: 'tlb-delete',
          }
        ];
        const getCellToolbar = () => TOOLBAR_CELL;


        const components = this._editor.DomComponents;
        const text = components.getType('text');
        components.addType('cell', {
          model: text.model.extend({
            defaults: Object.assign({}, text.model.prototype.defaults, {
              type: 'cell',
              tagName: 'td',
              draggable: ['tr'],
              
            }),
          },

            {
              isComponent(el) {
                let result;
                const tag = el.tagName;
                if (tag == 'TD' || tag == 'TH') {
                  result = {
                    type: 'cell',
                    tagName: tag.toLowerCase()
                  };
                }
                return result;
              }
            }),
          view: text.view,
        });

        

        this._editor.on('component:selected', m => {
          const compType = m.get('type');
          switch (compType) {
            case 'cell':
              m.set('toolbar', getCellToolbar()); // set a toolbars
          }
        });



        this._editor.Commands.add('table-insert-row-above', editor => {
          const selected = editor.getSelected();

          if (selected.is('cell')) {
            const rowComponent = selected.parent();
            const rowIndex = rowComponent.collection.indexOf(rowComponent);
            const cells = rowComponent.components().length;
            const rowContainer = rowComponent.parent();

            rowContainer.components().add({
              type: 'row',
              components: [...Array(cells).keys()].map(i => ({
                type: 'cell',
                content: 'New Cell',
              }))
            }, { at: rowIndex });
          }
        });
artfDecember 7, 20182 reactions
  1. The content inside the component definition is for static text (eg. the content is used for editing with Rich Text Editor) so you can't select its element once added, instead you should use components: '<tr data-gjs-type="row" ...'
  2. You can always get the selected Component and use its API, so your table-insert-row-above could be:
editor.Commands.add('table-insert-row-above', editor => {
  const selected = editor.getSelected();

  if (selected.is('cell')) {
      const rowComponent = selected.parent();
      const rowIndex = rowComponent.collection.indexOf(rowComponent);
      const cells = rowComponent.components().length;
      const rowContainer = rowComponent.parent();

      rowContainer.components().add({
        type: 'row',
        components: [ ...Array(cells).keys() ].map(i => ({
          type: 'cell',
          content: 'New Cell',
        }))
      }, { at: rowIndex });
  }
});
cnaa97December 10, 20180 reactions

Thanks for your kindness answer.

Related Questions and Answers

Continue research with similar issue discussions.

Paid Plugins That Match This Issue

Curated by issue keywords and label relevance to help you ship faster.

View all plugins

Loading paid plugin recommendations...

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.