-
-
Save excalq/2961415 to your computer and use it in GitHub Desktop.
// 2024 Update, use URLSearchParams [https://caniuse.com/urlsearchparams] | |
export function createQueryString2(name: string, value: string, searchParams: any) { | |
const params = new URLSearchParams(searchParams); | |
params.set(name, value.toLowerCase()); | |
return params.toString(); | |
} | |
// ---- Original 2012 version, when browsers really sucked ---- | |
// Explicitly save/update a url parameter using HTML5's replaceState(). | |
function updateQueryStringParam(param, value) { | |
baseUrl = [location.protocol, '//', location.host, location.pathname].join(''); | |
urlQueryString = document.location.search; | |
var newParam = key + '=' + value, | |
params = '?' + newParam; | |
// If the "search" string exists, then build params from it | |
if (urlQueryString) { | |
keyRegex = new RegExp('([\?&])' + key + '[^&]*'); | |
// If param exists already, update it | |
if (urlQueryString.match(keyRegex) !== null) { | |
params = urlQueryString.replace(keyRegex, "$1" + newParam); | |
} else { // Otherwise, add it to end of query string | |
params = urlQueryString + '&' + newParam; | |
} | |
} | |
window.history.replaceState({}, "", baseUrl + params); | |
} |
It navigates instead of replacing.
Thanks for this – here's a slightly fixed version with the correct argument names and proper var
declarations:
var updateQueryStringParam = function (key, value) {
var baseUrl = [location.protocol, '//', location.host, location.pathname].join(''),
urlQueryString = document.location.search,
newParam = key + '=' + value,
params = '?' + newParam;
// If the "search" string exists, then build params from it
if (urlQueryString) {
keyRegex = new RegExp('([\?&])' + key + '[^&]*');
// If param exists already, update it
if (urlQueryString.match(keyRegex) !== null) {
params = urlQueryString.replace(keyRegex, "$1" + newParam);
} else { // Otherwise, add it to end of query string
params = urlQueryString + '&' + newParam;
}
}
window.history.replaceState({}, "", baseUrl + params);
};
@mattandrews: great stuff. Amazing would be if the url parameter gets removed if no value is entered.
Here is a quick idea based on this stackoverflow answer:
http://stackoverflow.com/questions/1634748/how-can-i-delete-a-query-string-parameter-in-javascript
Not sure if its stable like this ... regex is not one of my strengths
var updateQueryStringParam = function (key, value) {
var baseUrl = [location.protocol, '//', location.host, location.pathname].join(''),
urlQueryString = document.location.search,
newParam = key + '=' + value,
params = '?' + newParam;
// If the "search" string exists, then build params from it
if (urlQueryString) {
updateRegex = new RegExp('([\?&])' + key + '[^&]*');
removeRegex = new RegExp('([\?&])' + key + '=[^&;]+[&;]?');
if( typeof value == 'undefined' || value == null || value == '' ) { // Remove param if value is empty
params = urlQueryString.replace(removeRegex, "$1");
params = params.replace( /[&;]$/, "" );
} else if (urlQueryString.match(updateRegex) !== null) { // If param exists already, update it
params = urlQueryString.replace(updateRegex, "$1" + newParam);
} else { // Otherwise, add it to end of query string
params = urlQueryString + '&' + newParam;
}
}
window.history.replaceState({}, "", baseUrl + params);
};
This is awesome! Gave it a test, and when passing a blank 'value' or just the 'key' and no value, it will remove the query string from the url. Nice!
Not working, for example EventSearch[date] param RegExp return null
@johannesgrandy beautiful, exactly what I was looking for. Now time to back to all my code and refactor haha
added params = params == '?' ? '' : params;
otherwise a ?
would stay even there are no more params left.
var updateQueryStringParam = function (key, value) {
var baseUrl = [location.protocol, '//', location.host, location.pathname].join(''),
urlQueryString = document.location.search,
newParam = key + '=' + value,
params = '?' + newParam;
// If the "search" string exists, then build params from it
if (urlQueryString) {
var updateRegex = new RegExp('([\?&])' + key + '[^&]*');
var removeRegex = new RegExp('([\?&])' + key + '=[^&;]+[&;]?');
if( typeof value == 'undefined' || value == null || value == '' ) { // Remove param if value is empty
params = urlQueryString.replace(removeRegex, "$1");
params = params.replace( /[&;]$/, "" );
} else if (urlQueryString.match(updateRegex) !== null) { // If param exists already, update it
params = urlQueryString.replace(updateRegex, "$1" + newParam);
} else { // Otherwise, add it to end of query string
params = urlQueryString + '&' + newParam;
}
}
// no parameter was set so we don't need the question mark
params = params == '?' ? '' : params;
window.history.replaceState({}, "", baseUrl + params);
};
If you're not using IE/Edge this can be achieved with URLSearchParams
const params = new URLSearchParams(location.search);
params.set('test', 123);
window.history.replaceState({}, '', `${location.pathname}?${params}`);
@johnrees that's great. 👍
Can anyone please show me how do I implement updateQueryStringParam()
in a <button>
or <a>
or <select>
[onChange]?
Thanks for the code snippet and sharing your thoughts – but I noted when using the code , updateQueryStringParam() adds a "?" every time, so, here is my solution around this;
export const createQueryString = (key: string, value: string) => {
var urlQueryString = document.location.search,
newParam = key + '=' + value,
params = '?' + newParam; //replace this line with the one below
params = newParam;
// If the "search" string exists, then build params from it
if (urlQueryString) {
let keyRegex = new RegExp('([?&])' + key + '[^&]*');
// If param exists already, update it
if (urlQueryString.match(keyRegex) !== null) {
params = urlQueryString.replace(keyRegex, "$1" + newParam);//replace this line with the one below
params = urlQueryString.replace(keyRegex, newParam);
} else {
// Otherwise, add it to end of query string
params = urlQueryString + '&' + newParam;
}
}
// window.history.replaceState({}, "", baseUrl + params);
return params;
}
Add here is a better solution for the same
export function createQueryString2(name: string, value: string, searchParams: any) {
const params = new URLSearchParams(searchParams);
params.set(name, value.toLowerCase());
return params.toString();
}
the function takes care of repalcing the value of a key if already exists
Thanks @mbuguaMaina, URLSearchParams
is definitely the best modern approach. I've updated the original Gist to use your version.
Thanks for the code snippet. The arguments are wrong - this should be:
updateQueryStringParam(key, value)