Skip to content

Instantly share code, notes, and snippets.

@dominic-p
Last active August 29, 2015 14:01
Show Gist options
  • Save dominic-p/6eb345194d508ecaf243 to your computer and use it in GitHub Desktop.
Save dominic-p/6eb345194d508ecaf243 to your computer and use it in GitHub Desktop.
JavaScript Query String Parameter Update and Test Suite
/**
* JavaScript Query string replacement function and test suite.
*
* The function is designed to add or update a query string parameter in a given
* URL. If all of the tests pass, the function should be pretty good.
*/
var test_val = 'new',
test_uris = [
[ 'http://example.com/', 'http://example.com/?param=' + test_val ],
[ 'http://example.com/?', 'http://example.com/?param=' + test_val ],
[ 'http://example.com/?param', 'http://example.com/?param=' + test_val ],
[ 'http://example.com/?param=val', 'http://example.com/?param=' + test_val ],
[ 'http://example.com/?param=val&param2', 'http://example.com/?param=' + test_val + '&param2' ],
[ 'http://example.com/?param=&param2', 'http://example.com/?param=' + test_val + '&param2' ],
[ 'http://example.com/?param=&param2', 'http://example.com/?param=' + test_val + '&param2' ],
[ 'http://example.com/?param=val&param2=val', 'http://example.com/?param=' + test_val + '&param2=val' ],
[ 'http://example.com/?param2=val&param[]=val', 'http://example.com/?param2=val&param[]=' + test_val ],
[ 'http://example.com/?param[test]=val&param2=val', 'http://example.com/?param[test]=' + test_val + '&param2=val' ],
[ 'http://example.com/?param[test]=val&param2[]=val', 'http://example.com/?param[test]=' + test_val + '&param2[]=val' ],
[ 'http://example.com/?param[]=val&param[]=another&param2=val', 'http://example.com/?param[]=' + test_val + '&param[]=' + test_val + '&param2=val' ],
[ 'http://example.com/?param=val#', 'http://example.com/?param=' + test_val + '#' ],
[ 'http://example.com/?param=val&param2=val#param=val', 'http://example.com/?param=' + test_val + '&param2=val#param=val' ],
[ 'http://example.com/?param=val&param2=val#param=val#test', 'http://example.com/?param=' + test_val + '&param2=val#param=val#test' ],
[ 'http://example.com/?param2=val&param=val#param=val#test?param=val', 'http://example.com/?param2=val&param=' + test_val + '#param=val#test?param=val' ],
[ 'http://example.com/#param=val', 'http://example.com/?param=' + test_val + '#param=val' ],
[ 'http://example.com/#test-string', 'http://example.com/?param=' + test_val + '#test-string' ],
[ 'http://example.com/#?test-string', 'http://example.com/?param=' + test_val + '#?test-string' ]
],
len = test_uris.length,
output,
result;
// Loop through all of the test URIs and check them against the function
for ( var i = 0; i < len; i++ ) {
output = update_query_string( test_uris[i][0], 'param', test_val );
result = ( ( output === test_uris[i][1] ) ? 'PASS' : 'FAIL' );
// Output, result :: old_uri :: new_uri
console.log( result + ' :: ' + test_uris[i][0] + ' :: ' + output );
// If a test failed, indicate what the expected value was
if ( 'FAIL' == result ) {
console.log( ' Expected: ' + test_uris[i][1] );
}
}
/**
* Add or update a query string parameter. If no URI is given, we use the current
* window.location.href value for the URI.
*
* Based on the DOM URL parser described here:
* http://james.padolsey.com/javascript/parsing-urls-with-the-dom/
*
* @param (string) uri Optional: The URI to add or update a parameter in
* @param (string) key The key to add or update
* @param (string) value The new value to set for key
*
* Tested on Chrome 34, Firefox 29, IE 7 and 11
*/
function update_query_string( uri, key, value ) {
// Use window URL if no query string is provided
if ( ! uri ) { uri = window.location.href; }
// Create a dummy element to parse the URI with
var a = document.createElement( 'a' ),
// match the key, optional square bracktes, an equals sign or end of string, the optional value
reg_ex = new RegExp( key + '((?:\\[[^\\]]*\\])?)(=|$)(.*)' ),
// Setup some additional variables
qs,
qs_len,
key_found = false;
// Use the JS API to parse the URI
a.href = uri;
// If the URI doesn't have a query string, add it and return
if ( ! a.search ) {
a.search = '?' + key + '=' + value;
return a.href;
}
// Split the query string by ampersands
qs = a.search.replace( /^\?/, '' ).split( /&(?:amp;)?/ );
qs_len = qs.length;
// Loop through each query string part
while ( qs_len > 0 ) {
qs_len--;
// Check if the current part matches our key
if ( reg_ex.test( qs[qs_len] ) ) {
// Replace the current value
qs[qs_len] = qs[qs_len].replace( reg_ex, key + '$1' ) + '=' + value;
key_found = true;
}
}
// If we haven't replaced any occurences above, add the new parameter and value
if ( ! key_found ) { qs.push( key + '=' + value ); }
// Set the new query string
a.search = '?' + qs.join( '&' );
return a.href;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment