ratiw / vue-table

data table simplify! -- vuetable is a Vue.js component that will automatically request (JSON) data from the server and display them nicely in html table with swappable/extensible pagination component.
MIT License
1.83k stars 303 forks source link

Ajax Table Configuration #74

Closed rafaellupo closed 8 years ago

rafaellupo commented 8 years ago

Hi @ratiw, Great job on Vue Table component ! Well, I've got an use case here where is needed to load all vue-table props from the server. For example, this is what I have on the server:

public function tableParams()
    {
        $table = new Table;
        $nome = new TableField;
        $abrev = new TableField;
        $actions = new TableField;

        $nome->name = 'nome';
        $nome->sortField = 'nome';

        $abrev->name = 'abrev';
        $abrev->title = 'Abreviatura';
        $abrev->sortField = 'abrev';

        $actions->name = '__actions';
        $actions->title = 'Ações';
        $actions->titleClass = 'text-center';
        $actions->dataClass = 'text-center';
        $actions->extra = array('width' => '11%');

        $actionEdit = new ItemAction;
        $actionEdit->name = 'edit-item';
        $actionEdit->icon = 'fa fa-pencil';
        $actionEdit->class = 'btn btn-warning';

        $actionDelete = new ItemAction;
        $actionDelete->name = 'delete-item';
        $actionDelete->icon = 'fa fa-trash';
        $actionDelete->class = 'btn btn-danger';

        $table->apiUrl = '/cadastros/unidades';
        $table->columns = [$nome , $abrev , $actions];
        $table->itemActions = [$actionEdit , $actionDelete];
        $table->sortOrder = [array('field' => 'nome', 'direction' => 'asc')];

        return $table->show();

    }

Well, this routine returns a Json,with all the configuration. There's no problem on binding everything. The problem I've found is that I couldn't find a vue-table event or method to initialize. What I've found is the loadOnStart property, which I've set to FALSE in order to prevent the table to load until the ajax request is done. Well, if I just broadcast the vuetable:reload or vuetable:refresh events, it wont work because it never calls the nomalizeFields method.

I've created an event like this:

'vuetable:initialize': function() {
            this.normalizeFields();
            this.currentPage = 1;
            this.loadData();
        }

but unfortunately didn't work (table shows only the pagination). What is curious, is that if I send the vue-table component to the console and call $vm.normalizeFields() the table appears. So, do you think is a timing issue ? Have any idea on how to solve that ?

rafaellupo commented 8 years ago

PS: Solved adding the property visible = true to each field object. But I keep curious on why I can't just have the table rendered by broadcasting the vuetable:initialize event on the promise !

ratiw commented 8 years ago

@rafaellupo It's hard to say. Have you notice any error in the browser console?

I don't know how you construct the <vuetable> tag using your tableParams(). But there might be problem(s) during the construction of vuetable by Vue.js and that's why I asked if there is an error dumped in the console output.

vuetable has two required props, which are api-url and fields props. These two props should be set beforehand. The api-url prop could be set later if you set load-on-start to false. But the fields prop will be used in the created hook by normalizeFields() to normalize each field so that all required options will be set with the default value if it's not present.

There is actually an event that you could broadcast from your main vue instance that will tell vuetable to set its own props using the given object, which is vuetable:set-options.

According your use case, here's what I come up that is working ok based on the example provided in examples directory.

    <vuetable v-ref:vuetable
        api-url=""
        :fields="[]"
        :load-on-start="false"
    ></vuetable>

This is the minimum setup that will prevent vuetable and vue.js throwing error out in the console

And here is the javascript part that initializes vuetable at a later stage.

  new Vue({
    el: '#app',
    data: {
      // omit for brevity, see the actual code in examples directory 
    },
    ready: function() {
        // 
        // you could do an ajax request here to retrieve vuetable settings from your server
        //
        this.$broadcast('vuetable:set-options', {
            apiUrl: 'http://vuetable.ratiw.net/api/users',
            fields: this.fields,
            itemActions: this.itemActions,
            paginationPath: ''
        })
        this.$refs.vuetable.normalizeFields()
        this.$refs.vuetable.loadData()
    }
  })

Please note that you need to call normalizeFields() to allow vuetable to normalize the given fields, otherwise, it might not work correctly. Also, since we've instruct vuetable not to load the data during the first initialization via load-on-start="false", we will have to do that manually as well by calling loadData().

Please note that this may not no longer work when vuetable is updated to use Vue 2.0 due to the deprecation of event system in Vue 1.x.

rafaellupo commented 8 years ago

Thank you @ratiw ! I got it working as expected ! Regards !