remove parameter from url via regex - javascript

I have a function for removing the parameter from url.
this is my function :
function removeParameter(key) {
let parameters = document.location.search;
const regParameter = new RegExp('[?|&]' + key + "=([a-zA-Z0-9_-]+)");
if (regParameter.test(parameters)){
parameters = parameters.replace(regParameter , '')
}
window.history.pushState({}, '', parameters)}
when I call this function for the url like this
http://example.com/products?color=4&brand=apple
first call function for removing the brand is correct result
removeParameter('brand')
but another call this function for removing the color doesn't work correctly.
actually when i want to removing the first parameter(key come's after ? mark) this function doesn't work...

The third argument to pushState() is the entire URL. Your function is sending only the location.search i.e. query parameter part of the URL. So you'll need to do
window.history.pushState({}, '', location.pathname + parameters)}
on your function's last line. Also, your code is currently not handling the edge cases i.e. if you remove first parameter, it removes the ? and not the trailing &. So you end up with http://example.com/products&brand=apple which isn't a valid URL. And finally, I simplified your expression a bit.
const reg = new RegExp('[?&](' + key + '=[\\w-]+&?)');
let matches = reg.exec(parameters);
if (matches){
parameters = parameters.replace(matches[1], '');
}
This still doesn't handle more complex cases (params without values, hash etc). There are a couple of other options:
Dump the regex and go with a split('&') based solution. More code, but a lot more readable and less error-prone.
If you don't need IE support, use URLSearchParams. Then your entire function can be reduced to this:
var params = new URLSearchParams(location.search);
params.delete(key);
window.history.pushState({}, '', location.pathname + "?" + params.toString());

Correct me if I'm wrong,
I made a working snippet out of your code, and it seems to work correctly.
If you run the snippet on a fresh new tab, it will add 2 urls in the tab history.
I also modified your regex to make it easier.
function removeParameter(key) {
var parameters = url; // document.location.search; // TAKIT: modified for test
const regParameter = new RegExp('[?|&]' + key + "=([^&]+)"); // TAKIT: Simplified regex
if (regParameter.test(parameters)) {
parameters = parameters.replace(regParameter, '')
}
window.history.pushState({}, 'Test 1', parameters);
return parameters; // TAKIT: Added
}
// Output
var url = "https://stacksnippets.net/js?color=4&brand=apple";
console.log(url);
url = removeParameter("brand");
console.log(url);
url = removeParameter("color");
console.log(url);
Hope it helps.

This function can be used, i modified #Takit Isy answer
function removeParameter(key) {
var parameters = url; // document.location.search; // TAKIT: modified for test
const regParameter = new RegExp(key + "=([a-zA-Z0-9_-]+[&]{0,1})");
if (regParameter.test(parameters)) {
parameters = parameters.replace(regParameter, '')
if(parameters.substring(parameters.length-1)=='?' || parameters.substring(parameters.length-1)=='&'){
parameters = parameters.slice(0, -1);
}
}
return parameters; // TAKIT: Added
}

Related

Javascript that removes part of string / url query parameters

i use the code below to format some links. Where it can add either a suffix or a prefix to the link. But i have been researching how to remove part of the link.
Example, this link below.
https://www.torrid.com/product/boyfriend-straight-jean---vintage-stretch-medium-wash/14478822.html?cgid=Clothing_Jeans_Straight_Boyfriend#promo_id=210802_Jeans&promo_name=BoyfriendStraight_BoyfriendStraight&promo_creative=2107_FG_Denim_Boyfriend_Straight_277x702&promo_position=Jeans_Slide3&start=1
It has superfluous data, everything after
https://www.torrid.com/product/boyfriend-straight-jean---vintage-stretch-medium-wash/14478822.html
Isn't needed, how can i remove everything past that point when formatting the links, before adding the suffix or prefix. Thanks in advance for any help!
$("#btnGenerateLinks").on("click", function() {
var valNeed = $("#strngtime").val();
// if (valNeed.trim().length) { // For filter blank string
$('input[name="linktype1"]').each(function() {
$(this).val($(this).data("link") + valNeed);
});
$('input[name="linktype2"]').each(function() {
$(this).val(valNeed + $(this).data("link"));
});
// }
});
Update - Yes all query parameters
Update - Going with a simple split for now
var myArr = valNeed.split("?")[0];
you can use the URL constructor API
let url = "https://www.torrid.com/product/boyfriend-straight-jean---vintage-stretch-medium-wash/14478822.html?cgid=Clothing_Jeans_Straight_Boyfriend#promo_id=210802_Jeans&promo_name=BoyfriendStraight_BoyfriendStraight&promo_creative=2107_FG_Denim_Boyfriend_Straight_277x702&promo_position=Jeans_Slide3&start=1"
let instance = new URL(url);
let cleanURL = instance.origin + instance.pathname;
console.log(cleanURL);
// https://www.torrid.com/product/boyfriend-straight-jean---vintage-stretch-medium-wash/14478822.html

how to prevent new element being appended repeatedly in javascript function?

Currently I have a JavaScript function like this:
<script type="text/javascript">
function select_device(device)
{
var mylink = window.location.href + "&name=" + device.value;
window.location.replace(mylink);
window.history.back
}
</script>
When a variable pass in, it will add as a new element into the url. Is there any way that I could possibly pass the variable in smartly as it will not just append repeatedly to the existing address?
I have tried to do it like
const url = window.location
window.location.replace(url.hostname + url.pathname + url.search + "&name=" + device.value)
But it doesn't solve the problem.
Since it sounds like you have multiple search parameters, not just name (since you're using &, not ? at the beginning), use URLSearchParams from the search string, set the new name, and then turn it back into a string:
function select_device(device) {
const { pathname, search } = window.location;
const params = new URLSearchParams(search);
params.set('name', device);
window.location.replace(pathname + '?' + String(params))
}

Way to get full param value from an URL

I am try to get the data from the param in the URL
http://localhost:8080?test=1&redirectURL=http://localhost:8082/#/abc?param=1
I did
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const redirectURL = urlParams.get('redirectURL'); // result: http://localhost:8082
but currently, the URL contain the hash code inside URL so the value return just http://localhost:8082
Is there any way to get full url http://localhost:8082/#/abc?param=1 by getting the param redirectURL
Thank you very much
I hope the following is useful for you.
var url_string = window.location.href;
var url = new URL(url_string);
var paramsTest = url.searchParams.get("test");
var paramsRedirectURL = url.searchParams.get("redirectURL");
console.log(paramsRedirectURL)
console.log(paramsTest)
Example here: https://codepen.io/yasgo/pen/dypWKoM
Maybe this can work for you
var afterHash = window.location.hash;
var beforeHash = window.location.href;
var fullURL = beforeHash ;
if(afterHash != '') // if there is something after hash and hash is exists in url then add the afterHash value in full url
{
var fullURL = beforeHash +"#"+ afterHash ;
}
console.log(fullURL);
I think the biggest issue here is that your redirectURL is not encoded. It should be encoded before it ends up in the URL, because otherwise the params and hashes from the nested URL are going to spill into the parent URL.
I obviously don't know if it would make sense for your project, but I think I would use domurl.
Maybe you should just use encodeURIComponent and possibly decodeURIComponent later, but I wanted to point out that domurl handles encoding and decoding automatically. Just as an example:
var url = new Url("http://localhost:8080?test=1");
url.query.redirectURL = 'http://localhost:8082/#/abc?param=1';
console.log( url.toString() );
// http://localhost:8080/?test=1&redirectURL=http%3A%2F%2Flocalhost%3A8082%2F%23%2Fabc%3Fparam%3D1
So again, what the encoded URL does is it prevents params from spilling from the nested URL to the parent URL and enables you to read redirectURL as a single string that you can then parse again to see/edit whatever params it has. The other important point is that I'm removing the hashtag with replace('/#/','/') in order to read the params from redirectURL:
Here's a slimmer jsfiddle where I'm just extracting the param and leave everything else out.
You'll definitely want to check dev tools consode log instead of the one stackoverflow offers, to make any sense of the objects.
console.log('');
// I'm encoding the redirectURL here, but in the real world it should be encoded before it's added as a parameter.
var url = new Url("http://localhost:8080?test=1&redirectURL="+ encodeURIComponent("http://localhost:8082/#/abc?param=1"));
console.log('url', url);
// So now that I've separated `url.query.redirectURL`, I can read that URL and its params separately...
var redirectUrl = new Url( url.query.redirectURL.replace('/#/', '/') ); // The hashtag is removed
console.log('redirectUrl:', redirectUrl );
console.log('redirectUrl - (param):', redirectUrl.query.param );
console.log('redirectUrl - path:', redirectUrl.path );
// If you need to use redirectURL without modifications you can just take the url param as is:
console.log( 'redirectUrl - no edits:', url.query.redirectURL );
// If you need to edit the params, you could do that and put just back the hashtag
redirectUrl.query.param = 'changed the param';
redirectUrl.path = '/#' + redirectUrl.path
console.log('redirectUrl - edited:', redirectUrl.toString() );
<script src="https://cdn.jsdelivr.net/npm/domurl#2.3.4/url.min.js"></script>

Trying to use .split with two different page URL structures

My intention
pull out language code from my two type of URL strings
My question
How do I make a split between two different URL structures? I have two URL strucutres, listed as examples below under the code.
My problem
I can't figure out how I should split the two different variables separately or together in one line with cc =... using custom javascript with Google Tag Manager
Code
function() {
cc = {{Page Path}}.split("/")[1].toLowerCase();
cc = {{virtualURL}}.split("/#/")[1].toLowerCase();
if(cc.length == 2) {
cc = cc;
} else {
cc = 'other';
}
return cc;
}
Example of {{Page Path}} - https://www.example.com/en/.....
Example of {{virtualURL}} - https://www.booking.example.com/#/en/........
Note
In both examples I want to be able to pull out en successfully.
Any solution here is likely to be fragile, you could have https://example.com/xy/ where xy isn't meant to be a language code.
But allowing for that, and allowing only two-character language codes:
var rexGetLang = /\/([a-z]{2})\//;
function getLang(url) {
var match = rexGetLang.exec(url);
return match ? match[1] : "other";
}
console.log(getLang("https://www.example.com/en/....."));
console.log(getLang("https://www.booking.example.com/#/en/........"));
Or if you want to allow for en-GB and such:
var rexGetLang = /\/([a-z]{2}(?:-[A-Z]{2})?)\//;
function getLang(url) {
var match = rexGetLang.exec(url);
return match ? match[1] : "other";
}
console.log(getLang("https://www.example.com/en/....."));
console.log(getLang("https://www.booking.example.com/#/en/........"));
console.log(getLang("https://www.booking.example.com/........"));
console.log(getLang("https://www.example.com/en-GB/....."));
console.log(getLang("https://www.booking.example.com/#/en-US/........"));
We can take out the language code simply by splitting the URL by /. Let's see what we get when we split the two URL's given as the example:
https://www.example.com/en/ - ["https:", "", "www.example.com", "en", ""]
https://www.booking.example.com/#/en/ - ["https:", "", "www.booking.example.com", "#", "en", ""]
In the above examples we can see that language code is either coming at 3rd index (1st example) or at the 4th index (2nd example) which can be taken care by an if condition. Let's see how:
let url = 'https://www.booking.example.com/#/en/';
let urlTokens = url.split('/');
let languageCode = urlTokens[3] === '#' ? urlTokens[4] : urlTokens[3];
console.log(languageCode);
// Web API for handling URL https://developer.mozilla.org/en-US/docs/Web/API/URL
const url = new URL('https://www.example.com/en/website');
url.hostname; // 'example.com'
url.port; // ''
url.search; // ''
url.pathname; // '/en/website'
url.protocol; // 'https:'
// RegEx to see if /en/ exists https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
new RegExp(/\/en\//).test(url.pathname) // true
function getLanguage(url) {
var rgx = /^https:\/\/[^\/]+\/(?:#\/)?([a-z]+)/;
var language = url.match(rgx)[1];
return language;
}
var url = 'https://www.booking.example.com/#/en/';
var language = getLanguage(url);

Add a variable in URL instead of replacing one

I'm facing a little issue with a javascript script. I'm trying to make my website multi languages. All is set in database, and my select works on pages where the URLs don't have variables. Here is my script:
<script type="text/javascript">
function submitForm() {
var thelang = document.getElementById('lang').options[document.getElementById('lang').selectedIndex].value;
window.location.href = window.location.pathname + '?lang=' + thelang;
}
</script>
In the homepage case, it works, and change http://localhost/ by http://localhost/?lang=en
But when I have an URL with a variable already set, it replaces it. From http://localhost/modules/product/product.php?id=1 I have http://localhost/modules/product/product.php?lang=en and the result I'd like is:
http://localhost/modules/product/product.php?id=1&lang=en
How to fix the script to make it works in both cases, or add the varibale, or glue it with an existing one?
Try checking to see if querystring params already exist in the URL.
function submitForm() {
var thelang = document.getElementById('lang').options[document.getElementById('lang').selectedIndex].value;
if (window.location.href.indexOf('?') >= 0) {
// There are already querystring params in the URL. Append my new param.
window.location.href = window.location.href + '&lang=' + thelang;
} else {
// There are not querystring params in the URL. Create my new param.
window.location.href = window.location.href + '?lang=' + thelang;
}
}
Update: Account for Subsequent Lang Changes
This assumes that the lang value will always be two characters.
function submitForm() {
var thelang = document.getElementById('lang').options[document.getElementById('lang').selectedIndex].value;
var newUrl = window.location.href;
var langIndex = newUrl.indexOf('lang=');
if (langIndex >= 0) {
// Lang is already in the querystring params. Remove it.
newUrl = newUrl.substr(0, langIndex) + newUrl.substring(langIndex + 8); // 8 is length of lang key/value pair + 1.
}
// Remove the final '?' or '&' character if there are no params remaining.
newUrl = newUrl.endsWith('?') || newUrl.endsWith('&') ? newUrl.substr(0, newUrl.length - 1) : newUrl;
newUrl = newUrl.indexOf('?') >= 0
? newUrl + '&lang=' + thelang // There are already querystring params in the URL. Append my new param.
: newUrl + '?lang=' + thelang; // There are not querystring params in the URL. Create my new param.
window.location.href = newUrl;
}
If I understand you correctly you want to add ?lang=en at the end. Unless there is already an id=1(or similar) there.
So you could just add an if statement, looking if there is .php writen at the end.
Not a very pretty solution but you are alreaady adding strings together so it doesn't matter
You can use the "search" element of window.location. See here for compatibility. You can then, concat the result with your desired parameter. BUT, you can do something way more complex (and secure) and check if there's already a parameter with that ID using a for + URLSearchParams.
const params = new URLSearchParams(window.location.search);
const paramsObj = Array.from(params.keys()).reduce(
(acc, val) => ({ ...acc, [val]: params.get(val) }), {}
);
This should fix it:
var currentUrl = window.location.origin + window.location.pathname;
var newUrl = currentUrl + (currentUrl.includes('?') ? ('&lang=' + thelang) : ('?lang=' + thelang));
window.location.href = newUrl;

Categories