niiknow / vue-datatables-net

Vue jQuery DataTables.net wrapper component
https://niiknow.github.io/vue-datatables-net/
MIT License
171 stars 58 forks source link

Handle search, page and order events #17

Closed jonathanoh1 closed 5 years ago

jonathanoh1 commented 5 years ago

I want to execute methods in vue, but i do not find the event dispatched when 'search', 'pagination', and 'order' are used. According datatable events, these events exists using instance of datatable, i need detect it when event is fired and execute code but from Vue.

noogen commented 5 years ago

@jonathanoh1 I just made some change to allow for wiring of native events. Check out 1.1.8 https://github.com/niiknow/vue-datatables-net#events

jonathanoh1 commented 5 years ago

Thanks for your quick response. I am testing the changes, but the events issued do not work, @tableCreating and @tableCreated do not activate my methods.

I already checked if my compiled js was updated with its changes of version 1.1.9 and is correct. I don't know what is the problem with this.

noogen commented 5 years ago

Sorry, I got confused for event with property. It should be kebab case as in: @table-creating and @table-created

jonathanoh1 commented 5 years ago

Yeah, this is the problem, thank you. Hey, do you think it will be necessary to emmit an event for draw.dt? I am rendering the action buttons using the Bulma style, with this framework it is necessary to add my own javascript code, so the problem is that when thedraw event of datatable is triggered, the events defined for the bulma example are ignored , and I need to reset the code for this event.

How I solved my problem is with the following code:

vm.dataTable.on('draw.dt', function (e) {
    setTimeout(function() {
        vm.dropdowns = Array.prototype.slice.call(document.querySelectorAll('.dropdown:not(.is-hoverable)'), 0);
        vm.dropdowns.forEach(function ($el, currentIndex) {
            $el.addEventListener('click', function (event) {
                event.stopPropagation();
                vm.renderActionButtons($el, currentIndex);
            });
        });
    }, 100);
});`

Then using the table-created event, I will have to define a new event to wait for thedraw.dt event. It's just a suggestion.

Thanks for answering.

noogen commented 5 years ago

Not entirely sure what you want to do, but I'm guessing that your rendering a menu dropdown for each row?

I would suggest using the templating feature:

actions: {
  label: 'Actions',
  defaultContent: '<a href="javascript:void(0);" data-action="showdropdown" class="btn btn-primary btn-sm"><i class="mdi mdi-menu"></i> ... </a>' +
    '<div class="dropdown hidden"><button data-action="edit">one</button><button data-action="delete">two</button></div>'
}

Then in vue:

<vdtnet-table ...
  @showdropdown="doDropDown"
  @edit="doEdit"
  @delete="doDelete"
/>

And handler:

doDropDown(data, row, tr, el) {
  row.find('.dropdown').toggleClass('hidden');
}
doEdit(data, row, tr, el) {
  var that = this;
   that.$router.push({
        path: "/modelName/".concat(data.id, "/edit")
   });
}
jonathanoh1 commented 5 years ago

Another question, using defaultContent, in the data-action attribute, can I use any action ('edit,' 'delete', ..., 'other') and use it as (@edit, @delete, ..., @other)?

noogen commented 5 years ago

@jonathanoh1 - sorry for late response, long Holiday weekend. Anyway, since I provide 3 different methods of templating, instead of defaultContent, you can also use render function or template property to do this. I've also added vdtnet context in the latest version 1.2.0 to help make it easier. Let assume you have a global mix-in that provide a can function for permission checking.

You can use the render function instead of defaultContent

const vm = this

// ... some code here ...

actions: {
  label: 'Actions',
  render: () => {

     let result = '<a href="javascript:void(0);" data-action="showdropdown" class="btn btn-primary btn-sm"><i class="mdi mdi-menu"></i> ... </a>';

     if (vm.can('write')) {
       result += '<div class="dropdown hidden"><button data-action="edit">one</button>';
     }

     // since 1.2.0, this or this.vdtnet is the same as vm in this example
     // you get the idea
     return result;
}

// ... some code here ...

Or use the template property instead of defaultContent:


// template property allow for vue templating
// example using v-if
actions: {
  label: 'Actions',
  template: `
<a href="javascript:void(0);" data-action="showdropdown" class="btn btn-primary btn-sm"><i class="mdi mdi-menu"></i> ... </a><div class="dropdown hidden" v-if="vdtnet.can('write')"><button data-action="edit">one</button><button data-action="delete" v-if="vdtnet.can('delete')">two</button></div>
`

Additionally, template property also provide row data information: https://github.com/niiknow/vue-datatables-net/blob/043e7ac95876edfea0b67f2dda9956aa91beb42c/src/VdtnetTable.vue#L459

noogen commented 5 years ago

@jonathanoh1 I added native templating in 1.2.2, which should help - https://github.com/niiknow/vue-datatables-net#native-templating-sort-of-explained