-
-
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.
Hello @excalq, what is the license of the original 2012 version? Thanks! :)
That's generic code, everyone used to code it that way back at this time, why caring about a license?
That's generic code, everyone used to code it that way back at this time, why caring about a license?
Thank you for clarifying the context of the code. As a FOSS Consultant, my role is to ensure compliance with open-source licensing requirements, which involves identifying and documenting the licenses associated with all code used in a project, regardless of its age or apparent generic nature.
Even for older snippets, it is essential to determine the licensing terms under which they were originally shared, as this information impacts how the code can be reused, modified, or redistributed today. Understanding the license helps mitigate potential legal or compliance risks, especially in modern projects that rely on legacy code.
If you have additional insights about the code’s origins or the context in which it was initially shared, I would greatly appreciate it. :)
Thanks for the code snippet. The arguments are wrong - this should be:
updateQueryStringParam(key, value)