Friday, 20 March 2015

Datatable Jump to Page functionality

I love Datatables, I'm sure if you've read any of my posts on here you'll probably already know that. But I was recently asked to implement "Jump to Page" functionality on a table which had something like 9000 rows. The heavy lifting was done on the server but I needed a way to allow the user to jump to a given page in the table. The table itself is on a site that uses bootstrap so updated the table DOM to give me some space to work in like this:

,"dom": 'T<"clearfix">lfrt<"row"<"col-md-4"i><"#page-jump.col-md-3"><"col-md-5"p>>'

This gave me a little space to put a number input so I used the fnInitComplete to do just that:

,"fnInitComplete": function(){
    var pagination_data = table.page.info();
    var jump_form = $("<div></div>",{
        "class": "form-inline row",
        "id": "jump-form"
    });
    var jump_form_group = $("<div></div>",{
        "class":"form-group col-xs-8"
    }).appendTo(jump_form);
    jump_form_group.append($("<label></label>",{
        "class": "sr-only",
        "for":"jump_page_number",
        "text":"Page:"
    }));
    var jump_input_group = $("<div></div>",{
        "style": "width:100%;",
        "class":"input-group"
    }).appendTo(jump_form_group);
    jump_input_group.append($("<input>",{
        "type": "number",
        "class": "form-control",
        "id": "jump-number",
        "placeholder": "Page",
        "min": "1",
        "value": "1"
    }));
    jump_form.append($("<button></button>",{
        "class":"btn btn-primary col-xs-4",
        "id": "jump-form-button",
        "text": "Go"
    }));
    $("#page-jump").append(jump_form);
    $("#jump-number").attr("max", pagination_data.pages).val(pagination_data.page + 1);
}

In order to make sure that the max attribute was always correct and updated when the number of rows displayed changed I also used the fnDrawCallback function like this:

,"fnDrawCallback": function () {
    if (typeof table != 'undefined'){
        var pagination_data = table.page.info();
        $("#jump-number").attr("max", pagination_data.pages).val(pagination_data.page + 1);
    }
}

Then I got to thinking about the input and how it didn't make sense to allow the user to add page numbers which might not exist so I added this jQuery to not only correct incorrect input but to also take care of moving pages:

$(document).on("click", "#jump-form-button", function(){
    table.page(parseInt($("#jump-number").val(), 10) - 1).draw(false);
}).on("input", "#jump-number", function(){
    if(isNaN(parseInt($("#jump-number").val(), 10))){
        $("#jump-number").val(parseInt($("#jump-number").attr("min"), 10));
    }else{
        if(parseInt($("#jump-number").val(), 10) > parseInt($("#jump-number").attr("max"), 10)){
            $("#jump-number").val(parseInt($("#jump-number").attr("max"), 10))
        }else{
            if(parseInt($("#jump-number").val(), 10) < parseInt($("#jump-number").attr("min"), 10)){
                $("#jump-number").val(parseInt($("#jump-number").attr("min"), 10))
            }
        }
    }
});

I know it's not exactly rocket science but I found it to work a treat so I hope it helps someone.