[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.

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>
});
}

But the problem is...
- Cannot detect the cell's location. above code just add on canvas below. not inside cell.
- 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)
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 });
}
});
- The
contentinside 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 usecomponents: '<tr data-gjs-type="row" ...' - You can always get the selected Component and use its API, so your
table-insert-row-abovecould 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 });
}
});
Thanks for your kindness answer.
Related Questions and Answers
Continue research with similar issue discussions.
Issue #2278
[QUESTION]: Simplify dropping columns/rows
What I need is to simplify dropping elements in a way to speed up page creation. So if I drop a column and there is no parent row there, I...
Issue #599
Set Device Height along with Device Width
Hi I want to add new devices with both width and height, Is there any way I can do this? An other issue is that when I give width of device...
Issue #2012
[question] how to add script for all widgets(like protectedCss)
I want to add some functions for all components accessible. when initialize editor, there is a option like protectedCss. Isn't there a way...
Issue #1738
[Bug] Table cell(td, th) resize error
Hello. I'm working on Table feature with this awesome project grapesjs. ProblemI added table component on canvas. In ComponentTableBody.js,...
Paid Plugins That Match This Issue
Curated by issue keywords and label relevance to help you ship faster.
Loading paid plugin recommendations...
Browse Plugin Categories
Jump directly to plugin category pages on the marketplace.