user7055375
user7055375

Reputation:

How to add or replace a query parameter in a URL using Javascript/jQuery?

I'm using jQuery 1.12. I want to replace a query string parameter in my window's URL query string, or add the parameter if doesn't exist. I tried the below:

new_url = window.location.href.replace( /[\?#].*|$/, "?order_by=" + data_val )  
window.location.href = new_url 

but what I'm discovering is that this wipes out all previous parameters in the query string, which I don't want. If the query string is:

?a=1&b=2

I would want the new query string to be:

?a=2&b=2&order_by=data

and if the query string was:

?a=2&b=3&order_by=old_data

it would become:

?a=2&b=3&order_by=data

Upvotes: 11

Views: 26764

Answers (11)

grizzthedj
grizzthedj

Reputation: 7505

You could use a jQuery plugin to do the all the heavy lifting for you. It will parse the query string, and also reconstruct the updated query string for you. Much less code to deal with.

Plugin Download Page
Github Repo

// URL: ?a=2&b=3&order_by=old_data

var order_by = $.query.get('order_by');
//=> old_data

// Conditionally modify parameter value
if (order_by) { 
  order_by = 'data';
}

// Inject modified parameter back into query string
var newUrl = $.query.set('order_by', order_by).toString();
//=> ?a=2&b=3&order_by=data

For those using Node.js, there is a package for this available in NPM.

NPM Package
Github Repo

var queryString = require('query-string');
var parsed = queryString.parse('?a=2&b=3&order_by=old_data');  // location.search

// Conditionally modify parameter value
if (parsed.order_by) {
  parsed.order_by = 'data';
}

// Inject modified parameter back into query string
const newQueryString = queryString.stringify(parsed);
//=> a=2&b=3&order_by=data

Upvotes: 5

function myFunction() {
  var str = "https://www.citicards.com/cards/credit/application/flow.action?app=UNSOL&HKOP=828cca70910b4fe25e118bd0b59b89c3c7c560df877909495d8252d20026cf8d&cmp=afa|acquire|2003|comparecards&ranMID=44660&ranEAID=2759285&ProspectID=516511657A844EF3A6F0C2B1E85FEFB0&ID=3000";
  var res = str.split("&");
  var myKey;
  if (!str.includes("ranSiteID")) {

    console.log("key not found ");
    res.push('ranSiteID=samplearsdyfguh.090-nuvbknlmc0.gvyhbjknl')
    console.log(res.join("&"));

  } else {

    res.map(function(key) {
      console.log("my keys", key);

      if (key.includes("ranSiteID")) {
        console.log("my required-->key", key);
        mykey = key.split("=");
        console.log(mykey);

      }
    })
  }

  document.getElementById("demo").innerHTML = res;
}
<!DOCTYPE html>
<html>

<body>
  <p>Click the button to display the array values after the split.</p>
  <button onclick="myFunction()">Try it</button>
  <p id="demo"></p>
</body>

</html>

Upvotes: 0

john Smith
john Smith

Reputation: 17936

Based on AVAVT´s answer I improved it so it takes any key, and I also fixed the missing "?" if there was no querystring

function addOrReplace(key, value) {
  var stringToAdd = key+"=" + value;
  if (window.location.search == "")
    return window.location.href + '?'+stringToAdd;

  if (window.location.search.indexOf(key+'=') == -1)
    return window.location.href + stringToAdd;

  var newSearchString = "";
  var searchParams = window.location.search.substring(1).split("&");
  for (var i = 0; i < searchParams.length; i++) {
    if (searchParams[i].indexOf(key+'=') > -1) {
      searchParams[i] = key+"=" + value;
      break;
    }
  }
  return window.location.href.split("?")[0] + "?" + searchParams.join("&");
}

usuage:

window.location.href = addOrReplace('order_by', 'date_created');

if you would not want to reload the page you can use pushState Api

if (history.pushState) {
    var newurl =  addOrReplace('order_by', 'date_created');
    window.history.pushState({path:newurl},'',newurl);
}

Upvotes: 0

Georgiy Dubrov
Georgiy Dubrov

Reputation: 410

something like this?

let new_url = "";

if (window.location.search && window.location.search.indexOf('order_by=') != -1) {
  new_url = window.location.search.replace( /order_by=\w*\d*/, "order_by=" + data_val);
} else if (window.location.search) {
  new_url = window.location.search + "&order_by=" + data_val;
} else {
  new_url = window.location.search + "?order_by=" + data_val;
}
window.location.href = new_url;

Upvotes: 4

MohaMad
MohaMad

Reputation: 2855

To use Regex pattern, I prefer this one:

var oldUrl = "http://stackoverflow.com/";
var data_val = "newORDER" ;
var r = /^(.+order_by=).+?(&|$)(.*)$/i ;
var newUrl = "";

var matches = oldUrl.match(r) ;
if(matches===null){
  newUrl = oldUrl + ((oldUrl.indexOf("?")>-1)?"&":"?") + "order_by=" + data_val ;
}else{
  newUrl = matches[1]+data_val+matches[2]+matches[3] ;
}
conole.log(newUrl);

If no order_by exist, matches is null and order_by=.. should come after ? or & (if other parameters exist, new one needs &).

If order_by exist, matches has 3 items, see here

Upvotes: 1

gtrenco
gtrenco

Reputation: 375

Maybe you could try tweaking the regular expression to retrieve only the values you're looking for, then add or update them in a helper function, something like this:

function paramUpdate(param) {

  var url = window.location.href,
      regExp = new RegExp(param.key + '=([a-z0-9\-\_]+)(?:&)?'),
      existsMatch = url.match(regExp);

  if (!existsMatch) {
      return url + '&' + param.key + '=' + param.value
  }

  var paramToUpdate = existsMatch[0],
      valueToReplace = existsMatch[1],
      updatedParam = paramToUpdate.replace(valueToReplace, param.value);

  return url.replace(paramToUpdate, updatedParam);
}

var new_url = paramUpdate({
    key: 'order_by',
    value: 'id'
});
window.location.href = new_url;

Hope it works well for your needs!

Upvotes: 1

user2560539
user2560539

Reputation:

This small function could help.

function changeSearchQueryParameter(oldParameter,newParameter,newValue) {
var parameters = location.search.replace("?", "").split("&").filter(function(el){ return el !== "" });
var out = "";
var count = 0;
if(oldParameter.length>0) {
if(newParameter.length>0 && (newValue.length>0 || newValue>=0)){
	out += "?";
	var params = [];
	parameters.forEach(function(v){
		var vA = v.split("=");
		if(vA[0]==oldParameter) {
			vA[0]=newParameter;
			if((newValue.length>0 || newValue>=0)) {
			vA[1] = newValue;			
			}
		} else {
			count++;
		}
		params.push(vA.join("="));	
	});
	if(count==parameters.length) {
		params.push([newParameter,newValue].join("="));
	}
  params = params.filter(function(el){ return el !== "" });
  if(params.length>1) {
  out += params.join("&");
  } 
  if(params.length==1) {
  out += params[0];
  }	
 }
} else {
if((newParameter.length>0) && (newValue.length>0 || newValue>=0)){
if(location.href.indexOf("?")!==-1) {
var out = "&"+newParameter+"="+newValue;	
} else {
var out = "?"+newParameter+"="+newValue;	
}
}
}
return location.href+out;
}
// if old query parameter is declared but does not exist in url then new parameter and value is simply added if it exists it will be replaced
console.log(changeSearchQueryParameter("ib","idx",5));
// add new parameter and value in url
console.log(changeSearchQueryParameter("","idy",5));
// if no new or old parameter are present url does not change
console.log(changeSearchQueryParameter("","",5));
console.log(changeSearchQueryParameter("","",""));

Upvotes: 1

Steve Chambers
Steve Chambers

Reputation: 39464

A good solution ought to handle all of the following:

  1. A URL that already has an order_by query parameter, optionally with whitespace before the equals sign. This can be further divided into cases where the order_by appears at the start, middle or end of the query string.
  2. A URL that doesn't already have and order_by query parameter but does already have a question mark to delimit the query string.
  3. A URL that doesn't already have and order_by query parameter and doesn't already have a question mark to delimit the query string.

The following will handle the cases above:

  if (/[?&]order_by\s*=/.test(oldUrl)) {
    newUrl = oldUrl.replace(/(?:([?&])order_by\s*=[^?&]*)/, "$1order_by=" + data_val);
  } else if (/\?/.test(oldUrl)) {
    newUrl = oldUrl + "&order_by=" + data_val;
  } else {
    newUrl = oldUrl + "?order_by=" + data_val;
  }

as demonstrated below:

getNewUrl("?a=1&b=2");
getNewUrl("?a=2&b=3&order_by=old_data");
getNewUrl("?a=2&b=3&order_by = old_data&c=4");
getNewUrl("?order_by=old_data&a=2&b=3");
getNewUrl("http://www.stackoverflow.com");

function getNewUrl(oldUrl) {
  var data_val = "new_data";
  var newUrl;
  if (/[?&]order_by\s*=/.test(oldUrl)) {
    newUrl = oldUrl.replace(/(?:([?&])order_by\s*=[^?&]*)/, "$1order_by=" + data_val);
  } else if (/\?/.test(oldUrl)) {
    newUrl = oldUrl + "&order_by=" + data_val;
  } else {
    newUrl = oldUrl + "?order_by=" + data_val;
  }
  console.log(oldUrl + "\n...becomes...\n" + newUrl);
}  

Upvotes: 5

Maciej Kozieja
Maciej Kozieja

Reputation: 1865

Try this:

For reading parameters:

const data = ['example.com?var1=value1&var2=value2&var3=value3', 'example.com?a=2&b=2&order_by=data']

const getParameters = url => {
  const parameters = url.split('?')[1],
        regex = /(\w+)=(\w+)/g,
        obj = {}
  let temp
  while (temp = regex.exec(parameters)){
    obj[temp[1]] = decodeURIComponent(temp[2])
  }
  return obj
}

for(let url of data){
  console.log(getParameters(url))
}

For placing only this parameters:

const data = ['example.com?zzz=asd']
const parameters = {a:1, b:2, add: "abs"}

const setParameters = (url, parameters) => {
  const keys = Object.keys(parameters)
  let temp = url.split('?')[0] += '?'
  for (let i = 0; i < keys.length; i++) {
    temp += `${keys[i]}=${parameters[keys[i]]}${i  == keys.length - 1 ? '' : '&'}`
  }
  return temp
}

for (let url of data){
  console.log(setParameters(url, parameters))
}

And finaly for inserting (or replace while exists)

const data = ['example.com?a=123&b=3&sum=126']
const parameters = {order_by: 'abc', a: 11}
const insertParameters = (url, parameters) => {
  const keys = Object.keys(parameters)
  let result = url
  for (let i = 0; i < keys.length; i++){
    if (result.indexOf(keys[i]) === -1) {
      result += `&${keys[i]}=${encodeURIComponent(parameters[keys[i]])}`
    } else {
      let regex = new RegExp(`${keys[i]}=(\\w+)`)
      result = result.replace(regex, `&${keys[i]}=${encodeURIComponent(parameters[keys[i]])}`)
    }
  }
  return result
}

for (let url of data){
  console.log(insertParameters(url, parameters))
}

Hope this works for you ;) After using function just replace window.location.href

Upvotes: 1

AVAVT
AVAVT

Reputation: 7143

function addOrReplaceOrderBy(newData) {
  var stringToAdd = "order_by=" + newData;

  if (window.location.search == "")
    return window.location.href + stringToAdd;

  if (window.location.search.indexOf('order_by=') == -1)
    return window.location.href + stringToAdd;

  var newSearchString = "";
  var searchParams = window.location.search.substring(1).split("&");
  for (var i = 0; i < searchParams.length; i++) {
    if (searchParams[i].indexOf('order_by=') > -1) {
      searchParams[i] = "order_by=" + newData;
      break;
    }
  }
  return window.location.href.split("?")[0] + "?" + searchParams.join("&");
}

window.location.href = addOrReplaceOrderBy("new_order_by");

A little long but I think it works as intended.

Upvotes: 3

Artem Bozhko
Artem Bozhko

Reputation: 1854

You can remove parameter from query string using URLSearchParams https://developer.mozilla.org/ru/docs/Web/API/URLSearchParams?param11=val

It is not yet supported by IE and Safari, but you can use it by adding polyfill https://github.com/jerrybendy/url-search-params-polyfill

And for accessing or modifying query part of the URI you should use "search" property of the window.location.

Working code example:

  var a = document.createElement("a")
  a.href = "http://localhost.com?param1=val&param2=val2&param3=val3#myHashCode";
  var queryParams = new URLSearchParams(a.search)
  queryParams.delete("param2")
  a.search = queryParams.toString();
  console.log(a.href);

Upvotes: 4

Related Questions