Friday, 18 March 2016

Moving data between pages using DataTables and the Query string

I recently got a tweet from someone I previously helped with a DataTable question:

And, seeing as I was playing with the really rather marvelous MDB framework, I thought I'd give it a try.

I knew I'd be able to get the data from the selected rows and also indicate their state as being selected but what was I to do with that data? If I could create a global data JSON object within the script I could use the unique ID of each row as the key to the full data of the representation of the row within the JSON object. The ID was for my benefit and could have been anything unique about the row... I guess I could've used a hash of the rows values as well, but why make things difficult?

So I needed a global data object, something to hide the the ID row within the table and some way of manipulating the data object when the user interacted with the table:

var data = {};
$(function(){
    var example = $("#example").DataTable({
        "columnDefs": [
            { 
                targets: [0], 
                visible: false
            }
        ]
    });
    $('#example tbody').on("click", "tr", function () {
        var temp = example.row(this).data()
        var obj = { 
            "ID": temp[0],
            "Name": temp[1],
            "Position": temp[2],
            "Office": temp[3],
            "Age": temp[4],
            "Start date": temp[5],
            "Salary": temp[6],
        }
        if($(this).hasClass("info")){
            $(this).removeClass("info");
            delete data[temp[0]];
        }else{
            $(this).addClass("info");
            data[temp[0]] = obj;
        }
        console.log(data);
    });
});

In case you're wondering, this is what the data looks like:

{
    "4": {
        "ID": "4",
        "Name": "Cedric Kelly",
        "Position": "Senior Javascript Developer",
        "Office": "Edinburgh",
        "Age": "22",
        "Start date": "2012/03/29",
        "Salary": "$433,060"
    },
    "5": {
        "ID": "5",
        "Name": "Airi Satou",
        "Position": "Accountant",
        "Office": "Tokyo",
        "Age": "33",
        "Start date": "2008/11/28",
        "Salary": "$162,700"
    },
    "6": {
        "ID": "6",
        "Name": "Brielle Williamson",
        "Position": "Integration Specialist",
        "Office": "New York",
        "Age": "61",
        "Start date": "2012/12/02",
        "Salary": "$372,000"
    }
}

So far so good, but how to move the data between the pages?

$("#move").on("click", function(){
    var encodedData = window.btoa(JSON.stringify(data));;
    var href = window.location.href.split("/");
    href.pop();
    href.push("catch.html");
    var newURL = href.join("/");
    document.location.href = newURL + "?data=" + encodedData;
});

When the button with an id of move is clicked I encode the stringed data object, take the uri of the current page, strip off the original page and add a new one (catch.html, in this case) and add the Base64 encoded data to the data query string. I then change the document.location.href to the catching page.

Simple ehh?

Within catch.html I needed to decode the Base64 encoded data and put it back into an object, I also needed to tell the catching DataTable how to read the caught data.

$(function(){
    var example = $("#example").DataTable({
        "columns": [
            { 
                "data": "ID",
                "visible": false
            },
            { 
                "data": "Name",
                "title": "Name"
            },
            { 
                "data": "Position",
                "title": "Position"
            },
            { 
                "data": "Office",
                "title": "Office"
            },
            { 
                "data": "Age",
                "title": "Age"
            },
            { 
                "data": "Start date",
                "title": "Start date"
            },
            { 
                "data": "Salary",
                "title": "Salary"
            }
        ]
    });
    var data = JSON.parse(window.atob(GetURLParameter("data")));
    if(Object.keys(data).length){
        $.each(data, function(k,v){
            example.row.add(v);
        });
        example.draw();
    }
});
function GetURLParameter(sParam){
    var sPageURL = window.location.search.substring(1);
    var sURLVariables = sPageURL.split('&');
    for (var i = 0; i < sURLVariables.length; i++){
        var sParameterName = sURLVariables[i].split('=');
        if (sParameterName[0] == sParam){
            return sParameterName[1];
        }
    }
}

Also simple ehh?

This was a nice little challenge and allowed me to slot wee bits of logic together to get something that just works, it was just what I needed to relax now I've picked all the low-hanging fruit from Empire of Code.