Closed ErnestsMillers closed 7 years ago
Hi @ErnestsMillers honestly I don't think I'm gonna support tables soon. The best I can do for now is to tell you to check https://github.com/artf/grapesjs-mjml/blob/master/src/components.js this is where mjml components are created. Try to see how other components are implemented, but it's not too much different from defining a new Component, you just have to extend coreMjmlModel
and coreMjmlView
@artf
I have been trying to add tables functionality for days but without any success. First of all I don't understand why tr's and td's just gets deleted in the view. The result is <table>Test</table>
. Adding blocks is easy but when it comes to components.js I can't figure out how to properly render things. I am posting my code below and if I can get any additional guidelines it would be a lifesaver.
I want tables to be added within mjml-column. All the elements in the mjml-column view are added as tr element. If I want a table would it mean doing something like this? tr>td>table(the actual table starts here?)>tr's>td's.
If anyone can help me with this I would be extremely thankful.
:)
blocks.js
bm.add('mj-table', {
label: 'Table',
content: `<mj-table><tr><td>Test</td></tr></mj-table>`,
attributes: {
'data-type': 'mj-table',
},
});
bm.add('tr', {
label: 'Tr',
content: `<tr><td>Test</td></tr>`,
attributes: {
'data-type': 'tr',
},
});
bm.add('td', {
label: 'Td',
content: `<td>Test</td>`,
attributes: {
'data-type': 'td',
},
});
components.js
// mj-table
domc.addType('Table', {
model: defaultModel.extend(Object.assign({}, coreMjmlModel, {
defaults: Object.assign({}, defaultModel.prototype.defaults, {
'custom-name': 'Table',
draggable: '[data-type=mj-column]',
highlightable: true,
stylable: [
// Dimension
'width'
// Typography
// Decorations
],
style: {
'width': '100%'
},
}),
}), {
isComponent(el) {
if (el.tagName == 'MJ-TABLE') {
return {
type: 'Table',
};
}
},
}),
view: defaultView.extend(Object.assign({}, coreMjmlView, {
tagName: 'table',
attributes: {
style: 'pointer-events: all; display: table; width: 100%',
},
})),
});
// tr
domc.addType('Tr', {
model: defaultModel.extend(Object.assign({}, coreMjmlModel, {
defaults: Object.assign({}, defaultModel.prototype.defaults, {
'custom-name': 'Tr',
draggable: '[data-type=mj-table]',
highlightable: true,
stylable: [
// Dimension
// Typography
// Decorations
],
style: {
},
}),
}), {
isComponent(el) {
if (el.tagName == 'tr') {
return {
type: 'tr',
};
}
},
}),
view: defaultView,
});
// td
domc.addType('Td', {
model: defaultModel.extend(Object.assign({}, coreMjmlModel, {
defaults: Object.assign({}, defaultModel.prototype.defaults, {
'custom-name': 'Tr',
draggable: '[data-type=tr]',
highlightable: true,
stylable: [
// Dimension
// Typography
// Decorations
],
style: {
},
}),
}), {
isComponent(el) {
if (el.tagName == 'td') {
return {
type: 'td',
};
}
},
}),
view: defaultView,
});
@ErnestsMillers just by quick looking I've seen this:
domc.addType('Td', { // <-- declaring `Td`
...
return {
type: 'td', // returning `td`... so you just don't get this type
};
// same for tr
Hi, @artf. Thank you, I noticed it some time ago and already fixed it. The main issue I am having, I don't understand where the tr, td disappears from markup. Mjml-table works together with standard tr's and td's. But somehow they disappear both in view code and when I inspect editor. You can see in blocks.js The way I add block to the editor.
In the following pictures table block is added with following markup:
<mj-table><tr style="border-bottom:1px solid #ecedee;text-align:left;padding:15px 0;">
<th style="padding: 0 15px 0 0;">Year</th>
<th style="padding: 0 15px;">Language</th>
<th style="padding: 0 0 0 15px;">Inspired from</th>
</tr>
<tr>
<td style="padding: 0 15px 0 0;">1995</td>
<td style="padding: 0 15px;">PHP</td>
<td style="padding: 0 0 0 15px;">C, Shell Unix</td>
</tr>
<tr>
<td style="padding: 0 15px 0 0;">1995</td>
<td style="padding: 0 15px;">JavaScript</td>
<td style="padding: 0 0 0 15px;">Scheme, Self</td>
</tr> </mj-table>
I believe the best approach is to place the table element in tr as any other element, then making a td and then table which will contain the actual tr's td's for table.
I really love GrapesJS but I think I am missing something/can't figure out your code. I hope you can help me out with this one, if I figure out the way components work, I surely will add others for you to pull as my project will involve a lot of work with grapesjs-mjml. :)
blocks.js is the same. components.js looks like this:
// mj-table
domc.addType('mj-table', {
model: defaultModel.extend(Object.assign({}, coreMjmlModel, {
defaults: Object.assign({}, defaultModel.prototype.defaults, {
'custom-name': 'Table',
draggable: '[data-type=mj-column]',
highlightable: true,
stylable: [
' height', 'font-style', 'font-size', 'font-weight', 'font-family', 'color',
// Dimension
'width'
// Typography
// Decorations
],
style: {
'width': '100%',
'font-size': '14px'
},
}),
}), {
isComponent(el) {
if (el.tagName == 'MJ-TABLE') {
return {
type: 'mj-table',
};
}
},
}),
view: defaultView.extend(Object.assign({}, coreMjmlView, {
tagName: 'tr',
attributes: {
style: 'pointer-events: all; display: table; width: 100%; user-select: none;',
'data-type': 'mj-table',
},
getChildrenSelector() {
return 'td > table';
},
getMjmlTemplate() {
return {
start: `<mjml><mj-body><mj-column>`,
end: `</mj-column></mj-body></mjml>`,
};
},
})),
});
// tr
domc.addType('tr', {
model: defaultModel.extend(Object.assign({}, coreMjmlModel, {
defaults: Object.assign({}, defaultModel.prototype.defaults, {
'custom-name': 'Tr',
draggable: '[data-type=mj-table]',
highlightable: true,
stylable: [
// Dimension
// Typography
// Decorations
],
style: {
'width': '100%'
},
}),
}), {
isComponent(el) {
if (el.tagName == 'TR') {
return {
type: 'tr',
};
}
},
}),
view: defaultView.extend(Object.assign({}, coreMjmlView, {
tagName: 'tr',
attributes: {
'data-type': 'tr',
},
})),
});
// td
domc.addType('td', {
model: defaultModel.extend(Object.assign({}, coreMjmlModel, {
defaults: Object.assign({}, defaultModel.prototype.defaults, {
'custom-name': 'Td',
draggable: '[data-type=tr]',
highlightable: true,
stylable: [
// Dimension
// Typography
// Decorations
],
style: {
'width': '100%'
},
}),
}), {
isComponent(el) {
if (el.tagName == 'TD') {
return {
type: 'td',
};
}
},
}),
view: defaultView.extend(Object.assign({}, coreMjmlView, {
tagName: 'td',
attributes: {
'data-type': 'td',
},
})),
});
I'll try to add it by myself and will let you know
Was a fix found for this issue? Since it is closed.
What is changes in @ErnestsMillers mentioned code. Please post code
@artf is it fixed ??
@ErnestsMillers I don't know if you are still interested in this issue but I noticed that the reason that <tr>
and <td>
aren't appearing is because they aren't being parsed at all. If you noticed the calls to the isComponent
those tags are never checked. My guess is that the issue may be related with grapesjs itself.
Were you ever to get this to work successfully @ErnestsMillers ?
Are there any updates regarding the issue? I've spend 2 days trying to get this working, but no luck for now...
The reason this doesn't work is this:
Grapesjs uses browsers internal html parser in order to parse an html to a tree.
However, for browsers, mj-table
is not a valid element. Thus, they wont allow tr
to be inside an mj-table
.
The root cause is similar to #149. And the solution for both would be Grapesjs either using a different dom parser (eg DOMParser api) which would properly parse non-html code like mjml, or at least making it possible to use a different parser so plugins like grapesjs-mjml can do that on their own.
@emilsedgh yeah it's correct but, you are actually already able to change the HTML parser type on init (here the default config).
grapesjs.init({
// ...
parser: { htmlType: 'text/xml' } // text/xml won't change the HTML
})
One thing worth noting, we have to update isComponentType in mjml components, with XML parser, tagName is not uppercased.
This is not really an issue. I am trying to do it myself, but is it possible to get mjml-table support anywhere soon? It's quite confusing because of td and tr. There really is no documentation about creating blocks for grapesjs-mjml and I am quite stuck when it comes to getting to understand all the conversion between html and mjml.
Please, that would be great help. If I make this work myself I will make pull request. :)