Smart Query Strings part 2: AJAX
This is a version of the PHP snippet I wrote last post, but for JavaScript (specifically jQuery for AJAX calls).
Basically, using the same type of call as before, you can use this to keep track of previously set variables set for AJAX calls. That way, you can easily keep all of the other parameters (good for multiple filter options passed via AJAX) and change only what you need. The code's a smidgen more complicated for this one.
function buildQueryString(changesString, currentString) {
if(!currentString || currentString == undefined) {
// get the current URL
var href = window.location.href;
// get the part after the ?
var queryStringHash = href.slice(href.indexOf('?') + 1);
// if it exists, cut off the # and after
if(queryStringHash.indexOf('#') < 0)
var queryString = queryStringHash;
else
var queryString = queryStringHash.slice(0, queryStringHash.indexOf('#'));
} else {
// strip ?
if(currentString.indexOf('?') >= 0)
queryString = currentString
.slice(currentString.indexOf('?') + 1);
}
// strip ?
if(changesString.indexOf('?') >= 0)
changesString = changesString.slice(changesString.indexOf('?') + 1);
// turn strings into
var query = queryStringToArray(queryString);
var change = queryStringToArray(changesString);
if(query.indexOf('undefined') < 0) query = [];
// this gets fun... look to see if each change matches
// then if it is, change the query value.
// if it's not found, then add it to the query
for(var i=0; i < change.length; i++) {
var found = false;
for(var j=0; j < query.length; j++) {
// compare each change value with query value, etc
if(query[j].name === change[i].name) {
query[j].value = change[i].value;
found = true;
}
}
// did find it, so we have to append it
if(!found)
query.push($.parseJSON('{"name":' + '"' + change[i].name + '","value":"' + change[i].value + '"}'))
}
// save it to currentQueryString for use next time (i.e. for AJAX calls)
currentQueryString = $.param(query);
// turn it back into a string
return $.param(query);
}
It's reliant on this little helper function that turns a query string of parameters (i.e. sort=name&page=3&dir=DESC) into an array;
function queryStringToArray(queryString) {
var queryVariablePairs = queryString.split("&");
var queryArray = [];
for(var i=0; i < queryVariablePairs.length; i++) {
var queryParts = queryVariablePairs[i].split('=');
queryJSON = '{"name":' + '"' + queryParts[0] + '","value":"' +
queryParts[1] + '"}';
queryArray.push($.parseJSON(queryJSON));
}
return queryArray;
}
Here's an example of usage:
HTML
<a href="?a=1&b=2&c=3">Click Me!</a>
JavaScript:
// IMPORTANT -> This variable keeps track of the variables in the last call.
var current = undefined;
$(document).ready(function() {
$('a').click(function(event) {
var changes = $(this).attr('href');
var data = buildQueryString(changes, current);
$.post("action.php", data, function(response) {
$('body').append(response);
});
});
});
Quick explanation of why it's useful: If the last query string used in an AJAX call had the parameters b = 7 and d = 5, then the query string you'd have sent would be b=7&d=5. If you click on the "Click Me" link, it would build a string changing b to 2 and adding a and c and leaving d alone, creating a=1&b=2&c=3&d=5. It's easy to see how this could be useful when a user can apply multiple simultaneous filters to a dataset.