jQuery Datatable DOM positioning for Buttons
Asked Answered
T

2

11

I just upgraded my jQuery Datatable version to 1.10. And then i tried to remove its retired plugin such as "Colvis" and "Tabletools" with the "Button" extension. Everything works fine here.

But the problem for me is, I could not able to separate "Colvis" button from the "Tabletool" buttons.

"sDom": "B<'row'><'row'<'col-md-6'l><'col-md-6'f>r>t<'row'<'col-md-4'i>><'row'p>B",
    "buttons": [
        'copyHtml5',
        'excelHtml5',
        'csvHtml5',     
        {
            extend: 'colvis',
            postfixButtons: [ 'colvisRestore' ],
            columns: '0,1,2,3,4,5,6'
        }
    ],
    language: {
        buttons: {
            colvis: 'Change columns'
        }
    }

Where in the "sDom", the letter "B" denotes for Buttons. So i am getting all four Buttons (Copy, Excel, CSV and Colvis) in a single row. But i need the "Colvis" button to be separated from (Copy, Excel and CSV).

So Is there any way to add one button near to search box and another one near to the pagination?

OR

Is there any configuration available in the "sDom" or in the "Button"?

Thank you!

Tergiversate answered 22/12, 2015 at 13:15 Comment(0)
C
14

You add new elements to the dataTables dom controls by using <'.class'> or <'#id'>. Example, insert a new <div id="colvis"> element to the left of the pagination, <'#colvis'> before p :

"sDom": "B<'row'><'row'<'col-md-6'l><'col-md-6'f>r>t<'row'<'col-md-4'i>><'row'<'#colvis'>p>"

colvis buttons has the class .buttons-colvis, so you move them permanently to the injected #colvis element by :

$('.buttons-colvis').detach().appendTo('#colvis')

This is the fast way to move the colvis button to another location.


Regarding @GreeKatrina's suggestion, yes - but the correct placement method is :

var colvis = new $.fn.dataTable.Buttons( table, {
    buttons: [
        {
            extend: 'colvis',
            ... 
        }
   ]
})
colvis.container().appendTo('#colvis')

if you have a #colvis element of course.


My recommendation : Besides the above hardcoded solution, where you target the colvis buttons specifically, you could monkey patch dataTables buttons so each extended button can have a container option. After initialisation, the button is moved to the specified container :

var org_buildButton = $.fn.DataTable.Buttons.prototype._buildButton;
$.fn.DataTable.Buttons.prototype._buildButton = function(config, collectionButton) {
   var button = org_buildButton.apply(this, arguments);
   $(document).one('init.dt', function(e, settings, json) {
       if (config.container && $(config.container).length) {
          $(button.inserter[0]).detach().appendTo(config.container)
       }
   })    
   return button;
}

use the container option :

{
   extend: 'colvis',
   postfixButtons: [ 'colvisRestore' ],
   container : '#colvis', //<---
   columns: '0,1,2,3,4,5'
}

demo -> http://jsfiddle.net/v4bLv83h/

As the example demonstrates, you can now specify an alternative container for each and every button. Note that container can be any element, it does not have to be an element injected by dom. Also note (as you may notice in the fiddle) that you need to do some styling if you want to make injected elements flow properly along with the native control elements, such as the pagination block.

Coleman answered 3/1, 2016 at 13:40 Comment(1)
This is the exact solution i was looking for, works great, thank you so much.Plaice
A
3

I'm not an expert with the data tables library, but the documentation says you can have multiple collections of buttons and insert them separately. It also has an example for multiple button groups that you could use instead of putting "B" multiple times in the dom option, which I don't think is valid.

Combining the examples from the documentation and your example (not tested):

var table = $('#myTable').DataTable( {
    dom: "B<'#colvis row'><'row'><'row'<'col-md-6'l><'col-md-6'f>r>t<'row'<'col-md-4'i>><'row'p>",
    buttons: [
        'copyHtml5',
        'excelHtml5',
        'csvHtml5'
    ]
} );

new $.fn.dataTable.Buttons( table, {
    buttons: [
        {
            extend: 'colvis',
            // Shorter than using the language.buttons.colvis option
            text: 'Change columns',
            postfixButtons: [ 'colvisRestore' ],
            columns: '0,1,2,3,4,5,6'
        }
    ]
} );

// To append it at the bottom of the table
// 3 since the colvis button is at the 3rd index in the buttons array
table.buttons( 3, null ).container().appendTo(
    table.table().container()
);

// To append it on the first row after the buttons, in the #colvis row
table.buttons( 3, null ).container().appendTo(
     $('#colvis'), table.table().container()
); 

If it doesn't work let me know and I'll update my answer.

Aswan answered 30/12, 2015 at 19:37 Comment(3)
Hi, Thank you for you reply. But it is throwing an error like "Uncaught TypeError: Cannot read property 'inst' of undefined" from the Datatable JS file.Tergiversate
Mutilple B's is perfectly legal. dataTables just inserts a "cloned" button section for each B. Yes, declaring multiple button objects could be a workaround, a more complex version of just moving the buttons. However, it should be <buttonObject>.container().appendTo(<element>), and table.table().container() is just the table wrapper itself.Coleman
@Yadheendran I'm guessing you are getting that error because you are not loading the library correctly. $.fn.dataTable is probably undefined and throwing that error. I would have to see how you're loading the scripts to be sure. See this question and both answers.Aswan

© 2022 - 2024 — McMap. All rights reserved.