Thursday, 20 August 2015

Datatables and Semantic UI

We're doing loads of work with Semantic UI at the minute at work and so I've spent some time this morning getting Datatables to work nicely with it. With the update of Datatables to 1.10.8 we can now access the numbers pagingType and this is just crying out for tweaking. In order to do this I added this function on the draw call back:

"pagingType": "numbers",
"drawCallback": function() {
    var tableA_paginate = $("#tableA_paginate");
    var page_numbers = tableA_paginate.find("span").children().clone(true);
    tableA_paginate.empty().append(page_numbers);
    tableA_paginate.addClass("right floated ui pagination menu");
    tableA_paginate.children().each(function(k, v){
        $(v).addClass("item");
        if($(v).hasClass("current")){
            $(v).addClass("active");
        }
        if($(v).hasClass("ellipsis")){
            $(v).addClass("disabled");
        }
    })
},

That left the length and search parts though so I got to thinking about grids within Semantic and I altered the dom to (actually, you should probably do this in order for the pagination above to look nice):

"dom": '<"ui grid form"<"four wide column"l><"eight wide column"><"four wide column"f>>t<"ui grid"<"eight wide column"i><"right floated eight wide column"p>>',

And then to turn the length and search parts of the Datatable into proper Semantic UI elements I added this initialization complete callback:

"initComplete": function(settings, json) {
    // Tidy up length select
    var tableA_length = $("#tableA_length");
    var select = tableA_length.find("select").clone(true);
    tableA_length.find("select").remove();
    select.attr("id", select.attr("name") + "_select").addClass("ui dropdown");
    tableA_length.find("label").attr("for", select.attr("name") + "_select");
    tableA_length.append(select);
    tableA_length.addClass("field");
    select.dropdown();
    // Tidy up search
    var tableA_filter = $("#tableA_filter");
    var input = tableA_filter.find("input").clone(true);
    tableA_filter.find("input").remove();
    input.attr("id", tableA_filter.attr("id") + "_input");
    tableA_filter.find("label").attr("for", tableA_filter.attr("id") + "_input");
    tableA_filter.append(input);
 },

A fully working example is on JSFiddle, with a couple of added extras that we needed for our implementation.

I know that there has been some discussion about implementing a Semantic UI theme but I've found this use of callbacks to work a treat... perhaps I should get my finger out and make a proper plug-in though...?

I think I'm correct in putting the pagination into a draw callback as this gets redrawn on each table draw and the other parts of the table don't seem to be so I've kept them in the initialization callback.