Change URL parameters and specify defaults using JavaScript
Asked Answered
C

32

244

I have this URL:

site.fwx?position=1&archiveid=5000&columns=5&rows=20&sorting=ModifiedTimeAsc

what I need is to be able to change the 'rows' url param value to something i specify, lets say 10. And if the 'rows' doesn't exist, I need to add it to the end of the url and add the value i've already specified (10).

Cholera answered 7/7, 2009 at 8:5 Comment(10)
A lightweight, no-plugin answer: https://mcmap.net/q/75486/-change-url-parameters-and-specify-defaults-using-javascriptHemeralopia
I can't believe it's 2013 and there's not a better way to do it, like something built into the core browser libraries.French
See my answer for a modern solution: https://mcmap.net/q/75486/-change-url-parameters-and-specify-defaults-using-javascriptCholera
possible duplicate of querystring encoding of a javascript objectCholera
@TylerCollier mid-2015 now and still nothing :(Tribute
Already 3rd quarter of 2016, Wondering how Google Maps actually do it, need this functionality for bookmarking.Rasberry
Seems like we are getting there... developer.mozilla.org/en-US/docs/Web/API/URLSearchParams/…Tusche
https://mcmap.net/q/75486/-change-url-parameters-and-specify-defaults-using-javascript is the answer now (if you don't care about IE)Minne
@TylerCollier it's 2021 now and we finally got this :) const myUrl = new URL("http://www.example.com?columns=5&rows=20"); myUrl.searchParams.set('rows', 10); myUrl.href will contain updated URLCountermeasure
based on @Countermeasure comment , you may replace http://www.example.com?columns=5&rows=20 with window.location.href to make the code more dynamicallyElbring
C
82

To answer my own question 4 years later, after having learned a lot. Especially that you shouldn't use jQuery for everything. I've created a simple module that can parse/stringify a query string. This makes it easy to modify the query string.

You can use query-string as follows:

// parse the query string into an object
var q = queryString.parse(location.search);
// set the `row` property
q.rows = 10;
// convert the object to a query string
// and overwrite the existing query string
location.search = queryString.stringify(q);
Cholera answered 13/11, 2013 at 22:12 Comment(6)
Wow this is a brilliantly simple solution. Thank you!Kink
This works like a champ! Thank you Sindre 🏆🏆🏆 (all you gotta do is minify "query-string/index.js" and paste it in bottom of your js)Suburbicarian
Having an extra library just for that seems like a bit extra...Woodwind
jQuery was too much for 1 function, so instead you used typescript, travis, and several other non-dev dependencies :)Fenner
@JustinMeiners Please don't comment if you have nothing useful to contribute to the conversation. TypeScript is not used by this project. Travis is a CI, not a dependency.Cholera
@SindreSorhus It was little lighthearted, but I think it's important to keep the complexity of these things in perspective. If you don't feel that's constructive, then ditto.Fenner
B
135

I've extended Sujoy's code to make up a function.

/**
 * https://mcmap.net/q/75486/-change-url-parameters-and-specify-defaults-using-javascript
 */
function updateURLParameter(url, param, paramVal){
    var newAdditionalURL = "";
    var tempArray = url.split("?");
    var baseURL = tempArray[0];
    var additionalURL = tempArray[1];
    var temp = "";
    if (additionalURL) {
        tempArray = additionalURL.split("&");
        for (var i=0; i<tempArray.length; i++){
            if(tempArray[i].split('=')[0] != param){
                newAdditionalURL += temp + tempArray[i];
                temp = "&";
            }
        }
    }

    var rows_txt = temp + "" + param + "=" + paramVal;
    return baseURL + "?" + newAdditionalURL + rows_txt;
}

Function Calls:

var newURL = updateURLParameter(window.location.href, 'locId', 'newLoc');
newURL = updateURLParameter(newURL, 'resId', 'newResId');

window.history.replaceState('', '', updateURLParameter(window.location.href, "param", "value"));

Updated version that also take care of the anchors on the URL.

function updateURLParameter(url, param, paramVal)
{
    var TheAnchor = null;
    var newAdditionalURL = "";
    var tempArray = url.split("?");
    var baseURL = tempArray[0];
    var additionalURL = tempArray[1];
    var temp = "";

    if (additionalURL) 
    {
        var tmpAnchor = additionalURL.split("#");
        var TheParams = tmpAnchor[0];
            TheAnchor = tmpAnchor[1];
        if(TheAnchor)
            additionalURL = TheParams;

        tempArray = additionalURL.split("&");

        for (var i=0; i<tempArray.length; i++)
        {
            if(tempArray[i].split('=')[0] != param)
            {
                newAdditionalURL += temp + tempArray[i];
                temp = "&";
            }
        }        
    }
    else
    {
        var tmpAnchor = baseURL.split("#");
        var TheParams = tmpAnchor[0];
            TheAnchor  = tmpAnchor[1];

        if(TheParams)
            baseURL = TheParams;
    }

    if(TheAnchor)
        paramVal += "#" + TheAnchor;

    var rows_txt = temp + "" + param + "=" + paramVal;
    return baseURL + "?" + newAdditionalURL + rows_txt;
}
Berar answered 12/6, 2012 at 13:10 Comment(10)
I can't seem to get this to work. Here is my code: jsfiddle.net/Draven/tTPYL/1 The URL would look like http://www.domain.com/index.php?action=my_action&view-all=Yes and I need to change the "view-all" value. My SO question that was closed: #13026380Euphonize
Are you sure? it worked for me easily. Check it out here: jsfiddle.net/mw49aBerar
Use "var i=0" instead of "i=0" to prevent creating/modifying i as a global variable.Otterburn
Couple of other issues with this function: (1) paramVal is not uri-encoded. (2) if paramVal is null, then you get foo=null. It should be foo= (or even better, remove foo completely).Otterburn
I have used this and it works but the answer could do with some explanation as to what is going on, ie. 'if (additionalURL) { tempArray = additionalURL.split("&"); for (i=0; i<tempArray.length; i++){ if(tempArray[i].split('=')[0] != param){ newAdditionalURL += temp + tempArray[i]; temp = "&"; } } }' Especially the inner if.Electrophysiology
@JonathanAquino I also wanted the parameter to be removed when paramVal === null. For this effect I've replaced the last 2 lines to the following: if ( paramVal !== null ) newAdditionalURL += temp + '' + param + '=' + paramVal; return baseURL + '?' + newAdditionalURL;Heuristic
@matthew solution worked for me but i passed param key with encodeURI since param has two strings separated with space .thanks matthew u save my time. var newURL = parameter(window.location.href, encodeURI(key), value);Corker
It's really good to know my answer is helping people still after years :)Berar
Great answer! BTW, suggestion, there's no need to concat "" onto a string: var rows_txt = temp + "" + param + "=" + paramVal;Pedo
This answer is missing encoding of special characters such as "#", "=" and "&" in param and paramVal. It's not safe to use if user input can affect either parameter.Lehrer
C
95

I think you want the query plugin.

E.g.:

window.location.search = jQuery.query.set("rows", 10);

This will work regardless of the current state of rows.

Calciferous answered 7/7, 2009 at 8:10 Comment(7)
Mofle, that's because the Query plugin uses decodeURIComponent, and decodeURIComponent("%F8") is invalid.Calciferous
Get that weird stuff out of your URL. Or, in other words, "change your query-string to use only valid UTF-8 characters". :) F8 alone isn't a valid UTF-8 character.Calciferous
Is there a way to retrieve the base url from this plugin? For example, if my URL is 'youtube.com/watch?v=PZootaxRh3M', get 'youtube.com/watch'Materials
@Wraith, you don't need a plugin for that. It's just window.location.pathname.Calciferous
What I'm not working with the url of the page? I want to take any old url and swap out query strings.Bael
@Brad, use jQuery.query.load to get a query object. Demo.Calciferous
@MattNorris You don't need a plugin for this, but correct answer is: window.location.host + window.location.pathname In your case it will be "www.youtube.com/watch"Wanderoo
O
82

Quick little solution in pure js, no plugins needed:

function replaceQueryParam(param, newval, search) {
    var regex = new RegExp("([?;&])" + param + "[^&;]*[;&]?");
    var query = search.replace(regex, "$1").replace(/&$/, '');

    return (query.length > 2 ? query + "&" : "?") + (newval ? param + "=" + newval : '');
}

Call it like this:

 window.location = '/mypage' + replaceQueryParam('rows', 55, window.location.search)

Or, if you want to stay on the same page and replace multiple params:

 var str = window.location.search
 str = replaceQueryParam('rows', 55, str)
 str = replaceQueryParam('cols', 'no', str)
 window.location = window.location.pathname + str

edit, thanks Luke: To remove the parameter entirely, pass false or null for the value: replaceQueryParam('rows', false, params). Since 0 is also falsy, specify '0'.

Overvalue answered 19/10, 2013 at 23:54 Comment(8)
also to remove a used parameter from the output do this: str = replaceQueryParam('oldparam',false, str) - basically put a false type valueGenesa
has problem, duplication my parameter for no good reason, check out this similar solution https://mcmap.net/q/76264/-how-to-replace-url-parameter-with-javascript-jqueryWyly
@Bludream that code has been working in production for years. I haven't seen it duplicate a param yet. Can you post a repro or some more constructive info?Overvalue
@Bludream I understand now, it's the script you linked to that was adding duplicate parameters. :)Overvalue
@Overvalue This doesn't seem to work if you use 0 or false as the newval parameterPittman
@Pittman correct, a falsy value removes the parameter entirely. Use text '0' instead of integer 0.Overvalue
This is old but it worked perfectly for me. It's short, clean, easy to modify and gets the job done at last for what I needed. Thanks.Pardoes
Zero is not supported, change "newval ? param" to "newval === null ? param"Aubade
C
82

To answer my own question 4 years later, after having learned a lot. Especially that you shouldn't use jQuery for everything. I've created a simple module that can parse/stringify a query string. This makes it easy to modify the query string.

You can use query-string as follows:

// parse the query string into an object
var q = queryString.parse(location.search);
// set the `row` property
q.rows = 10;
// convert the object to a query string
// and overwrite the existing query string
location.search = queryString.stringify(q);
Cholera answered 13/11, 2013 at 22:12 Comment(6)
Wow this is a brilliantly simple solution. Thank you!Kink
This works like a champ! Thank you Sindre 🏆🏆🏆 (all you gotta do is minify "query-string/index.js" and paste it in bottom of your js)Suburbicarian
Having an extra library just for that seems like a bit extra...Woodwind
jQuery was too much for 1 function, so instead you used typescript, travis, and several other non-dev dependencies :)Fenner
@JustinMeiners Please don't comment if you have nothing useful to contribute to the conversation. TypeScript is not used by this project. Travis is a CI, not a dependency.Cholera
@SindreSorhus It was little lighthearted, but I think it's important to keep the complexity of these things in perspective. If you don't feel that's constructive, then ditto.Fenner
Z
79

A modern approach to this is to use native standard based URLSearchParams. It's supported by all major browsers, except for IE where polyfills are available.

const paramsString = "site.fwx?position=1&archiveid=5000&columns=5&rows=20&sorting=ModifiedTimeAsc"
const searchParams = new URLSearchParams(paramsString);
searchParams.set('rows', 10);
console.log(searchParams.toString()); // return modified string.
Zachery answered 15/1, 2017 at 15:24 Comment(5)
Would be really nice... but it is not as IE does not support it at all, and using polyfills for such a small thing is totally out of the question.Loup
this also urlencodes the original paramsString in full, so the result looks like site.fwx%3Fposition=1&archiveid=5000&columns=5&rows=10&sorting=ModifiedTimeAsc which is confusing because it's not what you would have built if you did it manually...Fealty
Would be nice to see an example of how to use it. I mean, how to get params string from the current page and how to set it afterwardsWoodwind
@Zachery your answer has a bug, new URLSearchParams("site.fwx?position=1&... should be new URLSearchParams("position=1&... (it only takes the search string, not a path as well). I'd edited to fix but the edit is being rejected? Also @the-godfather const searchParams = new URLSearchParams(location.search); searchParams.set('rows', 10); location.search = searchParams; is the extra info you wanted in this answer.Listel
My favorite solution because it's shortest and native. You can also get params with searchParams.get('param'). Works in Node.Dorcy
P
61

Ben Alman has a good jquery querystring/url plugin here that allows you to manipulate the querystring easily.

As requested -

Goto his test page here

In firebug enter the following into the console

jQuery.param.querystring(window.location.href, 'a=3&newValue=100');

It will return you the following amended url string

http://benalman.com/code/test/js-jquery-url-querystring.html?a=3&b=Y&c=Z&newValue=100#n=1&o=2&p=3

Notice the a querystring value for a has changed from X to 3 and it has added the new value.

You can then use the new url string however you wish e.g using document.location = newUrl or change an anchor link etc

Parochial answered 7/7, 2009 at 8:14 Comment(7)
Isn't it jQuery.param.querystring instead of jQuery.queryString ?Yurikoyursa
TypeError: jQuery.param.querystring is not a functionPeridotite
To avoir 'TypeError' it should be : jQuery.queryString(window.location.href, 'a=3&newValue=100')Immaterialize
you should call jQuery.param.querystring. I guess they have refactored the library.Potvaliant
Neither of these functions exist any more. You want to update window.location.search manually. It gets more difficult if you don't want the page to repaint, since this will cause a page change.Topper
The Ben Alman jQuery BBQ plugin seems to be abandoned. We are considering using Query String as mentioned in the accepted answer.Engraft
@Brylie yeah jquery + its plugins are becoming obsoleteParochial
R
42

This is the modern way to change URL parameters:

function setGetParam(key,value) {
  if (history.pushState) {
    var params = new URLSearchParams(window.location.search);
    params.set(key, value);
    var newUrl = window.location.origin 
          + window.location.pathname 
          + '?' + params.toString();
    window.history.pushState({path:newUrl},'',newUrl);
  }
}
Raynold answered 14/6, 2018 at 15:54 Comment(8)
This solution is currently not supported in Internet Explorer 11: caniuse.com/#search=URLSearchParamsBrandi
The same respons was replied a half year before you by @ZacheryTatyanatau
@WoIIe Using URLSearchParams is the cleanest solution. IMO if business requirements still demand IE11 support in 2020. It's time to find a new business to work for.Charlton
Come on. Businesses don't determine their user base, and a lot of the people still using IE11 are poor and elderly. Literally the sort of people for whom we should NOT be relegating into a bucket of acceptably broken experiences.Boatman
use document.title for history titleTactless
"Internet Explorer will be retired on June 15, 2022" blogs.windows.com/windowsexperience/2021/05/19/…Gay
Nice one. You can change window.location.protocol + "//" + window.location.host + window.location.pathname simply with window.location.originAstrict
works, nice one.Raze
P
28

you can do it via normal JS also

var url = document.URL
var newAdditionalURL = "";
var tempArray = url.split("?");
var baseURL = tempArray[0];
var aditionalURL = tempArray[1]; 
var temp = "";
if(aditionalURL)
{
var tempArray = aditionalURL.split("&");
for ( var i in tempArray ){
    if(tempArray[i].indexOf("rows") == -1){
            newAdditionalURL += temp+tempArray[i];
                temp = "&";
            }
        }
}
var rows_txt = temp+"rows=10";
var finalURL = baseURL+"?"+newAdditionalURL+rows_txt;
Pointsman answered 7/7, 2009 at 8:46 Comment(3)
Nice! I took this and modified into a function. You send in the current url, the parameter name you're looking for, the new value, and a bool telling it if you want to add the parameter to the query string if I don't find it in there currently. Function returns the modified url.Nadbus
Gormer, you must share that function with others :)Berar
Awesome snippet. I too turned it into a function for my own use case. Thanks for sharing! +1Geronto
L
24

Use URLSearchParams to check, get and set the parameters value into URL

Here is the example to get the current URL set new parameters and update the URL or reload the page as per your needs

var rows = 5; // value that you want to set
var url = new URL(window.location);
(url.searchParams.has('rows') ? url.searchParams.set('rows', rows) : url.searchParams.append('rows', rows));

url.search = url.searchParams;
url        = url.toString();

// if you want to append into URL without reloading the page
history.pushState({}, null, url);

// want to reload the window with a new param
window.location = url;
Lodie answered 13/1, 2021 at 12:14 Comment(0)
C
13

2020 Solution: sets the variable or removes iti if you pass null or undefined to the value.

var setSearchParam = function(key, value) {
    if (!window.history.pushState) {
        return;
    }

    if (!key) {
        return;
    }

    var url = new URL(window.location.href);
    var params = new window.URLSearchParams(window.location.search);
    if (value === undefined || value === null) {
        params.delete(key);
    } else {
        params.set(key, value);
    }

    url.search = params;
    url = url.toString();
    window.history.replaceState({url: url}, null, url);
}
Cleanup answered 14/6, 2019 at 7:20 Comment(6)
Note that URLSearchParams does not work in the latest versions of all major browsers (2020)Babbage
still available in major browsers: developer.mozilla.org/en-US/docs/Web/API/URLSearchParams , googlechrome.github.io/samples/urlsearchparams/index.htmlCleanup
It's supported in all major browsers except IE11: caniuse.com/#search=URLSearchParamsRib
Even if it started to be supported, the same answer with URLSearchParams was answered in this question at least 3 times already on answered Jan 15 '17 at 15:24, answered Jun 14 '18 at 15:54 and answered Mar 1 '19 at 12:46 , as if nobody of you was reading replies before postingTatyanatau
all posts have minor issues that needs to be solved. so let the users vote and pick the best one.Cleanup
Why is there a need to check pushState? Is it to check if this is supported?Yaakov
F
10

Would a viable alternative to String manipulation be to set up an html form and just modify the value of the rows element?

So, with html that is something like

<form id='myForm' target='site.fwx'>
    <input type='hidden' name='position' value='1'/>
    <input type='hidden' name='archiveid' value='5000'/>
    <input type='hidden' name='columns' value='5'/>
    <input type='hidden' name='rows' value='20'/>
    <input type='hidden' name='sorting' value='ModifiedTimeAsc'/>
</form>

With the following JavaScript to submit the form

var myForm = document.getElementById('myForm');
myForm.rows.value = yourNewValue;
myForm.submit();

Probably not suitable for all situations, but might be nicer than parsing the URL string.

Foretell answered 7/7, 2009 at 8:22 Comment(1)
That's a clever one.Charmian
G
10

URL query parameters can be easily modified using URLSearchParams and History interfaces:

// Construct URLSearchParams object instance from current URL querystring.
var queryParams = new URLSearchParams(window.location.search);
 
// Set new or modify existing parameter value. 
//queryParams.set("myParam", "myValue");
queryParams.set("rows", "10");
 
// Replace current querystring with the new one.
history.replaceState(null, null, "?"+queryParams.toString());

Alternatively instead of modifying current history entry using replaceState() we can use pushState() method to create a new one:

history.pushState(null, null, "?"+queryParams.toString());

https://zgadzaj.com/development/javascript/how-to-change-url-query-parameter-with-javascript-only

Glyceric answered 6/9, 2020 at 16:42 Comment(0)
P
7

You can use this my library to do the job: https://github.com/Mikhus/jsurl

var url = new Url('site.fwx?position=1&archiveid=5000&columns=5&rows=20&sorting=ModifiedTimeAsc');
url.query.rows = 10;
alert( url);
Pyx answered 19/4, 2013 at 7:35 Comment(0)
C
7

Consider this one:

const myUrl = new URL("http://www.example.com?columns=5&rows=20");
myUrl.searchParams.set('rows', 10);
console.log(myUrl.href); // http://www.example.com?columns=5&rows=10
myUrl.searchParams.set('foo', 'bar'); // add new param
console.log(myUrl.href); // http://www.example.com?columns=5&rows=10&foo=bar

It will do exactly the same thing you required. Please note URL must have correct format. In your example you have to specify protocol (either http or https)

Countermeasure answered 11/4, 2021 at 22:1 Comment(0)
H
3

I wrote a little helper function that works with any select. All you need to do is add the class "redirectOnChange" to any select element, and this will cause the page to reload with a new/changed querystring parameter, equal to the id and value of the select, e.g:

<select id="myValue" class="redirectOnChange"> 
    <option value="222">test222</option>
    <option value="333">test333</option>
</select>

The above example would add "?myValue=222" or "?myValue=333" (or using "&" if other params exist), and reload the page.

jQuery:

$(document).ready(function () {

    //Redirect on Change
    $(".redirectOnChange").change(function () {
        var href = window.location.href.substring(0, window.location.href.indexOf('?'));
        var qs = window.location.href.substring(window.location.href.indexOf('?') + 1, window.location.href.length);
        var newParam = $(this).attr("id") + '=' + $(this).val();

        if (qs.indexOf($(this).attr("id") + '=') == -1) {
            if (qs == '') {
                qs = '?'
            }
            else {
                qs = qs + '&'
            }
            qs = qs + newParam;

        }
        else {
            var start = qs.indexOf($(this).attr("id") + "=");
            var end = qs.indexOf("&", start);
            if (end == -1) {
                end = qs.length;
            }
            var curParam = qs.substring(start, end);
            qs = qs.replace(curParam, newParam);
        }
        window.location.replace(href + '?' + qs);
    });
});
Hesione answered 7/12, 2011 at 5:44 Comment(1)
By far the best solution on this pageGeothermal
K
3

Using javascript URL:

var url = new URL(window.location);
(url.searchParams.has('rows') ? url.searchParams.set('rows', rows) : url.searchParams.append('rows', rows));
window.location = url;
Kirschner answered 30/1, 2021 at 13:10 Comment(0)
B
3
var url = new URL(window.location.href);
var search_params = url.searchParams;
search_params.set("param", value);
url.search = search_params.toString();
var new_url = url.pathname + url.search;
window.history.replaceState({}, '', new_url);
Bonanza answered 5/9, 2021 at 14:51 Comment(0)
N
3

In the URLSearchParams documentation, there's a very clean way of doing this, without affecting the history stack.

// URL: https://example.com?version=1.0
const params = new URLSearchParams(location.search);
params.set('version', 2.0);

window.history.replaceState({}, '', `${location.pathname}?${params}`);
// URL: https://example.com?version=2.0

Similarily, to remove a parameter

params.delete('version')
window.history.replaceState({}, '', `${location.pathname}?${params}`);
// URL: https://example.com?
Nerissanerita answered 7/10, 2021 at 13:26 Comment(0)
O
2

Here I have taken Adil Malik's answer and fixed the 3 issues I identified with it.

/**
 * Adds or updates a URL parameter.
 *
 * @param {string} url  the URL to modify
 * @param {string} param  the name of the parameter
 * @param {string} paramVal  the new value for the parameter
 * @return {string}  the updated URL
 */
self.setParameter = function (url, param, paramVal){
  // https://mcmap.net/q/75486/-change-url-parameters-and-specify-defaults-using-javascript
  var parts = url.split('?');
  var baseUrl = parts[0];
  var oldQueryString = parts[1];
  var newParameters = [];
  if (oldQueryString) {
    var oldParameters = oldQueryString.split('&');
    for (var i = 0; i < oldParameters.length; i++) {
      if(oldParameters[i].split('=')[0] != param) {
        newParameters.push(oldParameters[i]);
      }
    }
  }
  if (paramVal !== '' && paramVal !== null && typeof paramVal !== 'undefined') {
    newParameters.push(param + '=' + encodeURI(paramVal));
  }
  if (newParameters.length > 0) {
    return baseUrl + '?' + newParameters.join('&');
  } else {
    return baseUrl;
  }
}
Otterburn answered 5/9, 2014 at 17:54 Comment(0)
P
2

let url= new URL("https://example.com/site.fwx?position=1&archiveid=5000&columns=5&rows=20&sorting=ModifiedTimeAsc")
url.searchParams.set('rows', 10)
console.log(url.toString())
Polysynthetic answered 1/9, 2022 at 18:37 Comment(0)
B
1

Here is what I do. Using my editParams() function, you can add, remove, or change any parameter, then use the built in replaceState() function to update the URL:

window.history.replaceState('object or string', 'Title', 'page.html' + editParams('sorting', ModifiedTimeAsc));


// background functions below:

// add/change/remove URL parameter
// use a value of false to remove parameter
// returns a url-style string
function editParams (key, value) {
  key = encodeURI(key);

  var params = getSearchParameters();

  if (Object.keys(params).length === 0) {
    if (value !== false)
      return '?' + key + '=' + encodeURI(value);
    else
      return '';
  }

  if (value !== false)
    params[key] = encodeURI(value);
  else
    delete params[key];

  if (Object.keys(params).length === 0)
    return '';

  return '?' + $.map(params, function (value, key) {
    return key + '=' + value;
  }).join('&');
}

// Get object/associative array of URL parameters
function getSearchParameters () {
  var prmstr = window.location.search.substr(1);
  return prmstr !== null && prmstr !== "" ? transformToAssocArray(prmstr) : {};
}

// convert parameters from url-style string to associative array
function transformToAssocArray (prmstr) {
  var params = {},
      prmarr = prmstr.split("&");

  for (var i = 0; i < prmarr.length; i++) {
    var tmparr = prmarr[i].split("=");
    params[tmparr[0]] = tmparr[1];
  }
  return params;
}
Birecree answered 18/6, 2014 at 18:16 Comment(1)
A downvote without a comment? What's wrong with the code? It works fantastic for many situations.Birecree
H
1

My solution:

const setParams = (data) => {
    if (typeof data !== 'undefined' && typeof data !== 'object') {
        return
    }

    let url = new URL(window.location.href)
    const params = new URLSearchParams(url.search)

    for (const key of Object.keys(data)) {
        if (data[key] == 0) {
            params.delete(key)
        } else {
            params.set(key, data[key])
        }
    }

    url.search = params
    url = url.toString()
    window.history.replaceState({ url: url }, null, url)
}

Then just call "setParams" and pass an object with data you want to set.

Example:

$('select').on('change', e => {
    const $this = $(e.currentTarget)
    setParams({ $this.attr('name'): $this.val() })
})

In my case I had to update a html select input when it changes and if the value is "0", remove the parameter. You can edit the function and remove the parameter from the url if the object key is "null" as well.

Hope this helps yall

Hermetic answered 1/3, 2019 at 12:46 Comment(1)
there are already 2 same answers with URLSearchParams before you, as if nobody of you really read answers. Posted on answered Jan 15 '17 at 15:24 , answered Jun 14 '18 at 15:54Tatyanatau
S
1

If you want to change the url in address bar:

const search = new URLSearchParams(location.search);
search.set('rows', 10);
location.search = search.toString();

Note, changing location.search reloads the page.

Succory answered 10/8, 2020 at 9:40 Comment(0)
F
1

Here is a simple solution using the query-string library.

const qs = require('query-string')
function addQuery(key, value) {
  const q = qs.parse(location.search)
  const url = qs.stringifyUrl(
    {
      url: location.pathname,
      query: {
      ...q,
      [key]: value,
      },
    },
    { skipEmptyString: true }
  );
  window.location.href = url
  // if you are using Turbolinks
  // add this: Turbolinks.visit(url)
}
// Usage
addQuery('page', 2)

If you are using react without react-router

export function useAddQuery() {
  const location = window.location;
  const addQuery = useCallback(
    (key, value) => {
      const q = qs.parse(location.search);
      const url = qs.stringifyUrl(
        {
          url: location.pathname,
          query: {
            ...q,
            [key]: value,
          },
        },
        { skipEmptyString: true }
      );
      window.location.href = url
    },
    [location]
  );

  return { addQuery };
}
// Usage
const { addQuery } = useAddQuery()
addQuery('page', 2)

If you are using react with react-router

export function useAddQuery() {
  const location = useLocation();
  const history = useHistory();

  const addQuery = useCallback(
    (key, value) => {
      let pathname = location.pathname;
      let searchParams = new URLSearchParams(location.search);
      searchParams.set(key, value);
      history.push({
        pathname: pathname,
        search: searchParams.toString()
      });
    },
    [location, history]
  );

  return { addQuery };
}

// Usage
const { addQuery } = useAddQuery()
addQuery('page', 2)

PS: qs is the import from query-string module.

Finally answered 26/10, 2020 at 13:43 Comment(0)
L
0

Another variation on Sujoy's answer. Just changed the variable names & added a namespace wrapper:

window.MyNamespace = window.MyNamespace  || {};
window.MyNamespace.Uri = window.MyNamespace.Uri || {};

(function (ns) {

    ns.SetQueryStringParameter = function(url, parameterName, parameterValue) {

        var otherQueryStringParameters = "";

        var urlParts = url.split("?");

        var baseUrl = urlParts[0];
        var queryString = urlParts[1];

        var itemSeparator = "";
        if (queryString) {

            var queryStringParts = queryString.split("&");

            for (var i = 0; i < queryStringParts.length; i++){

                if(queryStringParts[i].split('=')[0] != parameterName){

                    otherQueryStringParameters += itemSeparator + queryStringParts[i];
                    itemSeparator = "&";
                }
            }
        }

        var newQueryStringParameter = itemSeparator + parameterName + "=" + parameterValue;

        return baseUrl + "?" + otherQueryStringParameters + newQueryStringParameter;
    };

})(window.MyNamespace.Uri);

Useage is now:

var changedUrl = MyNamespace.Uri.SetQueryStringParameter(originalUrl, "CarType", "Ford");
Lucier answered 26/10, 2012 at 14:4 Comment(0)
D
0

I too have written a library for getting and setting URL query parameters in JavaScript.

Here is an example of its usage.

var url = Qurl.create()
  , query
  , foo
  ;

Get query params as an object, by key, or add/change/remove.

// returns { foo: 'bar', baz: 'qux' } for ?foo=bar&baz=qux
query = url.query();

// get the current value of foo
foo = url.query('foo');

// set ?foo=bar&baz=qux
url.query('foo', 'bar');
url.query('baz', 'qux');

// unset foo, leaving ?baz=qux
url.query('foo', false); // unsets foo
Doeskin answered 8/2, 2014 at 12:31 Comment(0)
U
0

I was looking for the same thing and found: https://github.com/medialize/URI.js which is quite nice :)

-- Update

I found a better package: https://www.npmjs.org/package/qs it also deals with arrays in get params.

Upbuild answered 24/2, 2014 at 19:29 Comment(0)
W
0

No library, using URL() WebAPI (https://developer.mozilla.org/en-US/docs/Web/API/URL)

function setURLParameter(url, parameter, value) {
    let url = new URL(url);
    if (url.searchParams.get(parameter) === value) {
        return url;
    }
    url.searchParams.set(parameter, value);
    return url.href;
}

This doesn't work on IE: https://developer.mozilla.org/en-US/docs/Web/API/URL#Browser_compatibility

Wyck answered 7/8, 2020 at 13:34 Comment(1)
This should be the answer now! IE who?Minne
J
-1

I know this is an old question. I have enhanced the function above to add or update query params. Still a pure JS solution only.

                      function addOrUpdateQueryParam(param, newval, search) {

                        var questionIndex = search.indexOf('?');

                        if (questionIndex < 0) {
                            search = search + '?';
                            search = search + param + '=' + newval;
                            return search;
                        }

                        var regex = new RegExp("([?;&])" + param + "[^&;]*[;&]?");
                        var query = search.replace(regex, "$1").replace(/&$/, '');

                        var indexOfEquals = query.indexOf('=');

                        return (indexOfEquals >= 0 ? query + '&' : query + '') + (newval ? param + '=' + newval : '');
                    }
Jorin answered 4/12, 2017 at 21:29 Comment(0)
Z
-1

my function support removing param

function updateURLParameter(url, param, paramVal, remove = false) {
        var newAdditionalURL = '';
        var tempArray = url.split('?');
        var baseURL = tempArray[0];
        var additionalURL = tempArray[1];
        var rows_txt = '';

        if (additionalURL)
            newAdditionalURL = decodeURI(additionalURL) + '&';

        if (remove)
            newAdditionalURL = newAdditionalURL.replace(param + '=' + paramVal, '');
        else
            rows_txt = param + '=' + paramVal;

        window.history.replaceState('', '', (baseURL + "?" + newAdditionalURL + rows_txt).replace('?&', '?').replace('&&', '&').replace(/\&$/, ''));
    }
Zoila answered 1/6, 2018 at 15:24 Comment(0)
M
-1

I just wrote a simple module to deal with reading and updating the current url query params.

Example usage:

import UrlParams from './UrlParams'

UrlParams.remove('foo') //removes all occurences of foo=?
UrlParams.set('foo', 'bar') //set all occurences of foo equal to bar
UrlParams.add('foo', 'bar2') //add bar2 to foo result: foo=bar&foo=bar2
UrlParams.get('foo') //returns bar
UrlParams.get('foo', true) //returns [bar, bar2]

Here is my code named UrlParams.(js/ts):

class UrlParams {

    /**
     * Get params from current url
     * 
     * @returns URLSearchParams
     */
    static getParams(){
        let url = new URL(window.location.href)
        return new URLSearchParams(url.search.slice(1))
    }

    /**
     * Update current url with params
     * 
     * @param params URLSearchParams
     */
    static update(params){
        if(`${params}`){
            window.history.replaceState({}, '', `${location.pathname}?${params}`)
        } else {
            window.history.replaceState({}, '', `${location.pathname}`)
        }
    }

    /**
     * Remove key from url query
     * 
     * @param param string
     */
    static remove(param){
        let params = this.getParams()
        if(params.has(param)){
            params.delete(param)
            this.update(params)
        }
    }

    /**
     * Add key value pair to current url
     * 
     * @param key string
     * @param value string
     */
    static add(key, value){
        let params = this.getParams()
        params.append(key, value)
        this.update(params)
    }

    /**
     * Get value or values of key
     * 
     * @param param string
     * @param all string | string[]
     */
    static get(param, all=false){
        let params = this.getParams()
        if(all){
            return params.getAll(param)
        }
        return params.get(param)
    }

    /**
     * Set value of query param
     * 
     * @param key string
     * @param value string
     */
    static set(key, value){
        let params = this.getParams()
        params.set(key, value)
        this.update(params)
    }

}
export default UrlParams
export { UrlParams }
Marzipan answered 22/3, 2020 at 6:41 Comment(1)
There are already 4 same replies as you mentioned posted on, answered Jan 15 '17 at 15:24 , answered Jun 14 '18 at 15:54 , answered Mar 1 '19 at 12:46 and answered Jun 14 '19 at 7:20, as if nobody really of you read answers before postingTatyanatau
H
-2
     // usage: clear ; cd src/js/node/js-unit-tests/01-set-url-param ; npm test ; cd -
     // prereqs: , nodejs , mocha
     // URI = scheme:[//authority]path[?paramName1=paramValue1&paramName2=paramValue2][#fragment]
     // call by: uri = uri.setUriParam("as","md")
     String.prototype.setUriParam = function (paramName, paramValue) {
        var uri = this
        var fragment = ( uri.indexOf('#') === -1 ) ? '' : uri.split('#')[1]
        uri = ( uri.indexOf('#') === -1 ) ? uri : uri.split('#')[0]
        if ( uri.indexOf("?") === -1 ) { uri = uri + '?&' }
        uri = uri.replace ( '?' + paramName , '?&' + paramName)
        var toRepl = (paramValue != null) ? ('$1' + paramValue) : ''
        var toSrch = new RegExp('([&]' + paramName + '=)(([^&#]*)?)')
        uri = uri.replace(toSrch,toRepl)
        if (uri.indexOf(paramName + '=') === -1 && toRepl != '' ) {
           var ampersandMayBe = uri.endsWith('&') ? '' : '&'
           uri = uri + ampersandMayBe + paramName + "=" + String(paramValue)
        }
        uri = ( fragment.length == 0 ) ? uri : (uri+"#"+fragment) //may-be re-add the fragment
        return uri
     }

     var assert = require('assert');
     describe('replacing url param value', function () {

        // scheme://authority/path[?p1=v1&p2=v2#fragment
        // a clean url
        it('http://org.com/path -> http://org.com/path?&prm=tgt_v', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ? with num value
        it('http://org.com/path?prm=src_v -> http://org.com/path?&prm=tgt_v', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?bid=57'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ? but string value
        it('http://org.com/path?prm=src_v -> http://org.com/path?&prm=tgt_v', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?bid=boo-bar'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=boo-bar-baz'
           var uriActual = uri.setUriParam("bid","boo-bar-baz")
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ?& but string value
        it('http://org.com/path?&prm=src_v -> http://org.com/path?&prm=tgt_v', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=5'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ? with other param
        it('http://org.com/path?prm=src_v&other_p=other_v -> http://org.com/path?&prm=tgt_v&other_p=other_v', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?bid=5&other_p=other_v'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10&other_p=other_v'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ?& with other param
        it('http://org.com/path?&prm=src_v&other_p=other_v -> http://org.com/path?&prm=tgt_v&other_p=other_v', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=5&other_p&other_v'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10&other_p&other_v'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ? with other param with fragment
        it('http://org.com/path?prm=src_v&other_p=other_v#f -> http://org.com/path?&prm=tgt_v&other_p=other_v#f', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?bid=5&other_p=other_v#f'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10&other_p=other_v#f'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // has the url param existing after the ?& with other param with fragment
        it('http://org.com/path?&prm=src_v&other_p=other_v#f -> http://org.com/path?&prm=tgt_v&other_p=other_v#f', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=5&other_p&other_v#f'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=10&other_p&other_v#f'
           var uriActual = uri.setUriParam("bid",10)
           assert.equal(uriActual, uriExpected);
        });

        // remove the param-name , param-value pair
        it('http://org.com/path?prm=src_v&other_p=other_v#f -> http://org.com/path?&prm=tgt_v&other_p=other_v#f', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?bid=5&other_p=other_v#f'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&other_p=other_v#f'
           var uriActual = uri.setUriParam("bid",null)
           assert.equal(uriActual, uriExpected);
        });

        // remove the param-name , param-value pair
        it('http://org.com/path?&prm=src_v&other_p=other_v#f -> http://org.com/path?&prm=tgt_v&other_p=other_v#f', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?&bid=5&other_p=other_v#f'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&other_p=other_v#f'
           var uriActual = uri.setUriParam("bid",null)
           assert.equal(uriActual, uriExpected);
        });

        // add a new param name , param value pair
        it('http://org.com/path?prm=src_v&other_p=other_v#f -> http://org.com/path?&prm=tgt_v&other_p=other_v#f', function (){
           var uri = 'http://site.eu:80/qto/view/devops_guide_doc?&other_p=other_v#f'
           var uriExpected = 'http://site.eu:80/qto/view/devops_guide_doc?&other_p=other_v&bid=foo-bar#f'
           var uriActual = uri.setUriParam("bid","foo-bar")
           assert.equal(uriActual, uriExpected);
        });

     });
Henriettehenriha answered 5/2, 2019 at 14:43 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.