Issue #1661Opened December 14, 2018by Konger19680 reactions

I've created html table and cannot drag new elements to table cells

Question

Hello. if I create html table with next block of code, everything works, I'm able to drop a Quote, for example, to any cell:

 bm.add('table1centered', {
        label: '1 centered',
        category: 'Button Layout',
        attributes: { class: 'fa fa-table' },
        content: '<f7-list-item iPatrolType="f7-table">
        <table border="0" width="100%" style="min-height:5mm;">
          <tbody>
            <tr>
              <td width="45%">
              </td>
              <td width="10%">
              </td>
              <td width="45%">
              </td>
            </tr>
          </tbody>
        </table>
        </f7-list-item>'
    });

But next code produces html table with no possibility to drop new element into a cell. What am I doing wrong?

   bm.add('f7-list-item-table', {
        label: 'Table',
        category: 'Button Layout',
        attributes: { class: 'fa fa-table' },
        content: '<f7-list-item iPatrolType="f7-table"></f7-list-item>'
    });
    domComps.addType('f7-list-item-table', {
        model: dModel.extend({
            defaults: Object.assign({}, dModel.prototype.defaults,
                {
                    traits: [
                        //         // strings are automatically converted to text types
                        { type: 'number', label: 'columns', name: 'columns', placeholder: 'eg. columns quantity', default: 3 },
                        { type: 'text', label: 'column widths', name: 'columnwidths', placeholder: 'eg. 33%,34%,33%', default: '33%,34%,33%' },
                    ]
                }),
            initialize(o, opt) {
                dModel.prototype.initialize.apply(this, arguments);

                this.get('traits').each(function (trait) {
                    if (trait.get('name') == 'columns') {
                        trait.set('value', 3);
                    }
                    if (trait.get('name') == 'columnwidths') {
                        trait.set('value', '33%,34%,33%');
                    }
                });

            },
            showalert(mess) {
                setTimeout(() => { alert(mess); }, 1000);
            },
            getHtmlTemplate() {
                var columns = this.get('traits').where({ name: 'columns' })[0].get('value');
                var columnwidths = this.get('traits').where({ name: 'columnwidths' })[0].get('value');
                var columnwidthsArray = columnwidths.split(",");

                var template = '<f7-list-item iPatrolType="f7-table"><table width="100%" style="min-height:5mm;"><tr class="row">';
                // this.showalert(template);
                for (let index = 0; index < columns; index++) {
                    var wStr = columnwidthsArray.length >= index ? columnwidthsArray[index] : '';
                    if (wStr && !wStr.endsWith('%'))
                        wStr += '%';
                    template += '<td' + (wStr ? ' width="' + wStr + '"' : '') + ' class="cell"></td>';
                }
                template += '</tr></table></f7-list-item>';

                return template;
            },
            toHTML: function () {
                return this.getHtmlTemplate();
            }
        },
            {
                isComponent: function (el) {
                    if (el.tagName == 'F7-LIST-ITEM' && el.getAttribute('iPatrolType') == 'f7-table') {
                        return { type: 'f7-list-item-table' };
                    }
                },
            }),

        view: dView
            .extend({
                tagName: 'f7-list-item',
                initialize(o) {
                    dView.prototype.initialize.apply(this, arguments);
                    this.listenTo(this.model,
                        'change:attributes:columns ' +
                        'change:attributes:columnwidths '
                        , this.render)
                },
                showalert(mess) {
                    setTimeout(() => { alert(mess); }, 1000);
                },
                getHtmlTemplate() {
                    // this.showalert("getHtmlTemplate");
                    var columns = this.model.get('traits').where({ name: 'columns' })[0].get('value');
                    var columnwidths = this.model.get('traits').where({ name: 'columnwidths' })[0].get('value');
                    var columnwidthsArray = columnwidths.split(",");

                    var template = `<li>
                    <table border="1" width="100%" style="min-height:15mm;"
                    >
                    <tr>`;
                    for (let index = 0; index < columns; index++) {
                        wStr = '';
                        var wStr = columnwidthsArray.length >= index ? columnwidthsArray[index] : '';
                        if (wStr && !wStr.endsWith('%'))
                            wStr += '%';
                        template += '<td ' + (wStr ? ' width="' + wStr + '"' : '') + ' ></td>';
                    }
                    template += '</tr></table></li> ';

                    return template;
                },
                render(...args) {
                    this.updateAttributes();
                    this.updateClasses();

                    var template = this.getHtmlTemplate();
                    this.el.className = "f7-list-item-table";
                    this.el.innerHTML = template;
                    // this.showalert(this.el.outerHTML);
                    return this;
                }
            }),
    });

Answers (3)

artfDecember 20, 20180 reactions

Hi Konstantin, by doing this this.el.innerHTML = template; you're basically removing components by replacing them with a static HTML. Each component, once inserted inside the canvas has a Model (let's say, the component's JSON structure) bind to its View (render elements), so this View.el.innerHTML = '<div>...</div>' it' is like just adding another View but without the Model, the editor doesn't see elements without models. You need to update the model if you want to keep components live, so in your case, probably what you probably need is to move your view.getHtmlTemplate content inside the init of the model

domComps.addType('f7-list-item-table', {
        model: dModel.extend({
			...
			// use init instead of initialize, so you can skip 
			// calling the parent method dModel.prototype.initialize....
			init() {
				...
				// Check if the component is empty
				if (!this.components().length) {
					this.components(`<li>
                    <table border="1"... you content from view.getHtmlTemplate`)
				}
			}
Konger1968December 20, 20180 reactions

Thanks.

lock[bot]December 20, 20190 reactions

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

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.