VueJS component in TableBuilder

vargvinter - 1 week ago

Hello,

I am playing around with TableBuilder and VueJS. I want to have custom VueJS component in table. I have something like this:

    /**
     * The table columns.
     *
     * @var array|string
     */
    protected $columns = [
        'name',
        'state' => [
            'wrapper' => '<toggler :state={value}></toggler>'
        ]
    ];

    /**
     * The table assets.
     *
     * @var array
     */
    protected $assets = [
        'scripts.js' => [
            'acme.module.foobar::js/toggler.js'
        ]
    ];

And JS file:

Vue.component('toggler', {
    template: '<button>Test</button>',

    props: ['state']
});

new Vue({
    el: 'body',

    created: function() {
        alert('Works');
    }
});

Alert message appears, so VueJS is properly loaded but my custom component toggler is not displayed. Does Pyro cut off non standard html tags?

Answer

piterden - 1 week ago

Because you couldn't use body as root element. And I suppose there is old version of vue. What version do you use?

ryanthompson - 1 week ago

This is something that is relatively new as a security measure but you'll need to add 'is_safe' => true to your column definition. It's sanitized by default as to not allow input information to inject into the page.

vargvinter - 1 week ago

Thanks @ryanthompson 'is_safe' => true did the trick. I can see toggler tag in page source code.

There is another problem. VueJS does not change <toggler> into '<button>Test</button>'. :(

piterden - 1 week ago

Because you couldn't use body as root element. And I suppose there is old version of vue. What version do you use?

vargvinter - 1 week ago

@piterden You are correct. I have mounted VueJS to table via some dummy class and now all works as intended. Thanks.

vargvinter - 1 week ago

One more thing. Pyro doesn't view table if I pass dynamic property to custom Vue component.

Table columns definition:

    /**
     * The table columns.
     *
     * @var array|string
     */
    protected $columns = [
        'name',
        'featured' => [
            'sort_column' => 'featured',
            'is_safe' => true,
            'view' => 'acme.module.foobar::toggler'
        ]
    ];

And toggler.twig code:

This works:

<toggler state="{{ entry.featured }}"></toggler>

This fails. Table is not displayed:

<toggler :state="{{ entry.featured }}"></toggler>

Any walkaround?

ryanthompson - 1 week ago

How do you mean fails? Does it through an error? If that code with the entry.featured is added by view AFTER rendering then the HTML / DOM is 100% on you. Cause it's post rendering. But I might be missing your issue.

vargvinter - 1 week ago

It think it was my mistake. Just solved it a moment ago like that:

        'featured' => [
            'sort_column' => 'featured',
            'is_safe' => true,
            'wrapper' => '<toggler :state="{{ entry.featured }}"></toggler>'
        ]

Earlier I had:

 'wrapper' => '<toggler :state="{ value }"></toggler>'

and the table just didn't appear. Strange. :)

ryanthompson - 1 week ago

Ah - yep that'll do it.

Keep in mind you can define value as an array too like this: https://github.com/anomalylabs/files-module/blob/2.4/src/File/Table/FileTableBuilder.php#L56-L71