I'm working on a script, where you pass it a url like /search?filter1=question-1&filter2=question2, and when either question-1 or question-2 is changed, it will take the url, and replace the question-x with the question value.
One thing I want to build in, is if the value is empty, I want it to remove the query string part. So for example, if question-1 has a value of something, but 2 doesn't have a value yet, the url will be /search?filter1=something.
What I thought would work would be something like this
$url.match('/([^?&]*)' + name.toSearch + '/g') // toSearch is a value like question-1
But that returns null. Can anybody help me figure out what I need to change to get the output I'm after?
Given the url /search?filter=question-1, I need to see if the element with the name question[1] has a value, if it does, replace question-1 with the value, and if it doesn't have one, remove the total filter=question-1 string.
Knowing your requirements better from the comments, I completely rewrote my answer using parts of my original answer and some of your code:
// Given url
var url = '/search?filter1=question-1&filter2=question-2';
// Specify the filters so no extra query string noise enters the final url
var filters = ["filter1", "filter2", "filter3"];
// Split the query string parts
var urlParts = url.split(/([&?])/);
var reassembled = [];
// Break the url parts into key:value pairs
var qs = (function(a) {
if (a === "") return {};
var b = {};
for (var i = 0; i < a.length; ++i)
{
var p=a[i].split('=', 2);
if (p.length == 1)
b[p[0]] = "";
else
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return b;
})(urlParts);
// This include a param:value in the reassembled array
function includeQSParam(param, value) {
if(qs[param]) {
reassembled.push(param + "=" + value);
}
}
// Run through the filters
for(var ind in filters) {
var filter = filters[ind];
// Check that the filter exists and the supplied value is of type question-
if(qs[filter] && qs[filter].indexOf("question-") >= 0) {
// Turns question-number into question[number] so it's a valid selector.
var inputSelector = "question["+(qs[filter]).replace(/\D/g, "")+"]";
// Get the input, and the value (author-supplied code)
var $input = $('[name="' + inputSelector + '"]');
// TODO: confirm this is how you get the value
var value = $input.closest('.question').val();
if($input.length > 0 && (value !== '' && value !== undefined)) {
// Replace the parameter's original value with the question value
includeQSParam(filter, value);
} else {
// Nothing to do. This filter will be removed automatically
}
}
}
// Reassemble the URL
var fixedUrl = urlParts[0] + (reassembled.length > 0 ? "?"+reassembled.join("&") : "");
Again, this was reworked from my original answer so there will be some bloat, but I didn't want to abandon the question on you.
Whilst Drakes answer is a good one, it didn't quite fit into my needs. I've ended up with this, which works well so far, but I'm still testing it.
var $url = '/search?filter1=question-1&filter2=question-2';
// Break the url into parts.
var $split = $url.split(/([&?])/);
$.each($split, function(indexToRemove, part){
// If the part is a question.
if(typeof part == 'string' && part.indexOf('question-') > -1){
var $number = part.split('=');
// Turns question-number into question[number] so it's a valid selector.
$inputSelector = String($number[1]).replace('-', '[') + ']';
// Get the input, and the value.
var $input = $('[name="' + $inputSelector + '"]');
var $value = getValue($input.closest('.question'));
// If there is an element, and there is a value.
if($input.length > 0 && ($value != '' && $value != undefined)){
$split[indexToRemove] = part.replace($number[1], $value);
} else {
$split.splice(indexToRemove, 1);
}
}
});
$url = $split.join('');
// If for example question-1 has a value of 'Test', and question-2 has no value, $url will now be '/search?filter1=Test'.
Related
I've read some question but I still can't figure out how to do it
I have a url example.com/event/14aD9Uxp?p=10
Here I want to get the 14aD9Uxp and the value of p
I've tried using split('/'+'?p=') but it doesn't work
I want to use regex but I dont really understand how to use it
var URL='example.com/event/14aD9Uxp?p=10';
var arr=URL.split('/');//arr[0]='example.com'
//arr[1]='event'
//arr[2]='14aD9Uxp?p=10'
var parameter=arr[arr.length-1].split('?');//parameter[0]='14aD9Uxp'
//parameter[1]='p=10'
var p_value=parameter[1].split('=')[1];//p_value='10';
I've created a generalized function (restricted in some ways) that will return the GET value given the parameter. However this function will only work correctly provided that you do not Rewrite the URL or modify the URL GET SYNTAX.
//Suppose this is your URL "example.com/event/14aD9Uxp?p=10";
function GET(variable) {
var str = window.location.href;
str = str.split("/");
// str = [example.com, event, 14aD9Uxp?p=10]
//Get last item from array because this is usually where the GET parameter is located, then split with "?"
str = str[str.length - 1].split("?");
// str[str.length - 1] = "14aD9Uxp?p=10"
// str[str.length - 1].split("?") = [14aD9Uxp, p=10]
// If there is more than 1 GET parameter, they usually connected with Ampersand symbol (&). Assuming there is more, we need to split this into another array
str = str[1].split("&");
// Suppose this is your URL: example.com/event/14aD9Uxp?p=10&q=112&r=119
// str = [p=10, q=112, r=119]
// If there is only 1 GET parameter, this split() function will not "split" anything
//Remember, there might only be 1 GET Parameter, so lets check length of the array to be sure.
if (str.length > 1) {
// This is the case where there is more than 1 parameter, so we loop over the array and filter out the variable requested
for (var i = 0; i < str.length; i++) {
// For each "p=10" etc. split the equal sign
var param_full_str = str[i].split("=");
// param_full_str = [p, 10]
//Check if the first item in the array (your GET parameter) is equal to the parameter requested
if (param_full_str[0] == variable) {
// If it is equal, return the second item in the array, your GET parameter VALUE
return param_full_str[1];
}
}
} else {
// This is the case where there is ONLY 1 GET parameter. First convert it to a String Type because Javascript decided that str was no longer a String
// Now split it with the equal sign.
str = str.toString().split("=");
return str[1];
}
}
document.write(GET("p"));
function $_GET(param) {
var vars = {};
window.location.href.replace(
/[?&]+([^=&]+)=?([^&]*)?/gi, // regexp
function( m, key, value ) { // callback
vars[key] = value !== undefined ? value : '';
}
);
if ( param ) {
return vars[param] ? vars[param] : null;
}
return vars;
}
I have collected this from here:
http://www.creativejuiz.fr/blog/javascript/recuperer-parametres-get-url-javascript
It works great.
To use it just grab your parameter like:
var id = $_GET('id');
const url = new URL('http://example.com/event/14aD9Uxp?p=10');
const [,, eventId ] = url.pathname.split('/');
const p = url.searchParams.get('p');
Browser support:
https://caniuse.com/#feat=url
https://caniuse.com/#feat=urlsearchparams
Simple no-regex way
var s = "example.com/event/14aD9Uxp?p=10";
var splitByForwardSlash = s.split('/');
// To get 14aD9Uxp
splitByForwardSlash[splitByForwardSlash.length-1]
// To get p=10
splitByForwardSlash[splitByForwardSlash.length-1].split('?')[1]
I think you know how to go from here :-)
This is my first question here, hoping you can help. Currently I am trying to loop through an API list of 100 arrays all of which contain one string of data. My loop filters through for numerical data and prints it to a div id. However when I hit data with "#N/A" instead of digits, it breaks my loop. I have tried nesting an if statement that would check if data is null or not, but as it treats null data as an object, this does not work. I have included commented out code to show the things I have tried:
var xhr = new XMLHttpRequest();
var URL = "https://spreadsheets.google.com/feeds/list/0AhySzEddwIC1dEtpWF9hQUhCWURZNEViUmpUeVgwdGc/1/public/basic?alt=json";
xhr.open("GET", URL, false);
xhr.send();
var statusResponseStringify = JSON.stringify(xhr.responseText, "", 2);
var statusResponseParse = JSON.parse(xhr.responseText);
var Find = statusResponseParse.feed.entry;
for (var i = 0; i < Find.length; i++) {
var FTSEContent = statusResponseParse.feed.entry[i].content.$t;
document.getElementById("FTSEName").innerHTML+=FTSEContent + "<br><br>";
var text = FTSEContent;
var value = text.match(/(\d[\d\.]*)/g);
//var price = value[0];
//var change = value[1];
console.log(value);
/*if (typeof value === "number") {
document.getElementById("Change").innerHTML+=value + "<br>";
}
else if (typeof value === null) {
document.getElementById("Change").innerHTML+="N/A" + "<br>";
}
else if (typeof value === "object") {
document.getElementById("Change").innerHTML+="Smell" + "<br>";
}
else {
document.getElementById("Change").innerHTML+="poo" + "<br>";
};*/
if (typeof value == "undefined") {
document.getElementById("Print").innerHTML+="N/A" + "<br>";
}
else {
document.getElementById("Print").innerHTML+=value[0] + "<br>";
};
};
This is the console I get back when I run this code
Could anyone help me with some code ideas to circumvent the null responses when looping. I would ideally like to print the numbers and print an N/A whenever there is a null or #N/A within the API data.
Thank you all!
Rewrite your check: instead of if (typeof value == "undefined") it should be...
if (value === null) { ... }
... as .match() returns null on non-matching, and not undefined.
As a sidenote, your code can be simplified a bit. First, you don't have to repeat the whole statusResponseParse.feed.entry... expression in FTSEContent, use Find instead:
var FTSEContent = Find[i].content.$t;
Second, my understanding is that you check for number in that content string. In this case, you can adjust your pattern a bit:
var value = FTSEContent.match(/(\d+(?:\.\d+)?)/);
... so it won't consume such illegal numbers as '3..' and '3.14.15' (in the last case, only 3.14 will be matched), and doesn't have to match globally (you only process the first result anyway).
I have to use regular expressions to replace or append a query to a url with the function adjustUrlParameter(url, param). If the same query exists in the URL, it should replace the query with param (i.e. ID=501 should replace ID=200 in google.com?ID=200). If no query exists, it should simply append the query to the end of the url. Finally, if a query does exist but of a different type, it should append the query and separate it from the pre-existing query with a '&'. Here's an example:
adjustUrlParameter('google.com?ID=501', 'TYPE=444') // => 'google.com?ID=501&TYPE=444'
My code isn't replacing the same query type. It is returning 'google.com?ID=501&ID=200' instead of returning 'google.com?ID=200'. Here's my code:
var adjustUrlParameter = function(url, param) {
var urlQuery = url.match(/\w+\W+/g);
for (var i = 0; i < urlQuery.length; i++) {
if (param === urlQuery[i]) {
return url.replace(/\?.+$/, '?' + param);
}
}
if (url.match(/\?/)) {
return url + "&" + param;
} else {
return url + "?" + param;
}
};
How do I get adjustUrlParameter('google.com?ID=501', 'ID=201') to return the proper result ('google.com?ID=201')?
The problem is that the if statement never returns true. Put some console.logs in the for loop and watch it. You'll see when urlQuery[i] returns "ID=" param returns "ID=444". They are not equal.
console.log("parameter:"+param); //parameter:ID=444
console.log("url_query: "+urlQuery[i]); //url_query: ID=
If you change your for loop like below it replaces the query parameter with the same type:
for (var i = 0; i < urlQuery.length; i++) {
console.log("parameter:"+param);
console.log("url_query: "+urlQuery[i]);
var paramType = param.split("=");
console.log("paramType"+paramType);
var tmp = paramType[0]+"="; //since urlQuery[i] always has a character at the end
console.log(tmp);
if (tmp === urlQuery[i]) {
return url.replace(/\?.+$/, '?' + param);
}
}
When you run adjustUrlParameter('google.com?ID=501', 'ID=444') the output is "google.com?ID=444"
You want to compare the names of the queries, not the values they contain too.
Say you pass in id=200 as param, you want to find and replace from id in the existing url. That means that we don't care about the value of id. If that is the case, we can split by ? or & to get a list of all of the queries. We start looping at 2 because 0 and 1 are the base url and the ?. We also jump 2 with every iteration to skip the preceding &. Lastly, we make sure to split each query with = and use [0] or the first half to get that name that we care about.
You could do something like this:
var adjustUrlParameter = function(url, param) {
var urlQuery = url.split(/(\?|\&)/)
, thisQuery = param.split(/\=/)[0]
for (var i = 2; i < urlQuery.length; i = i + 2) {
if (thisQuery === urlQuery[i].split(/\=/)[0]) {
return url.replace(/(\?|\&).*$/, '?' + param);
}
}
if (url.match(/\?/)) {
return url + "&" + param;
} else {
return url + "?" + param;
}
};
I want to get values of all fields in a variable separated by a comma. For example: 1,2,3
The following code will work fine, but it only adds the comma at end of the last value also. How can I remove that?
fields = $('.wrap').find('.text');
var data = '';
fields.each(function() {
var value = $(this).val();
if ( value != '' ) {
data += ' ' + value + ',';
}
});
alert(data);
JSFiddle:
http://jsfiddle.net/cn5Gt/
I always use arrays for these kind of things:
var fields = $('.wrap').find(".text[value!='']");
var data = [];
fields.each(function() {
data.push($(this).val());
});
alert(data.join(','));
You can push elements on array than just use join() method.
fields = $('.wrap').find('.text');
var data = [];
fields.each(function() {
var value = $(this).val();
if ( value != '' ) {
data.push(value);
}
});
alert(data.join());
Try the code below, using the i which is the loop index and test against the length of the jQuery object.
fields = $('.wrap').find('.text');
var length = fields.length;
var data = '';
fields.each(function(i) {
var value = $(this).val();
if ( value != '' ) {
if(i === length-1) { //The last one
data += ' ' + value;
} else {
data += ' ' + value + ',';
}
}
});
Updated fiddle
You could just remove the final character afterwards?
data = data.substr(0, data.length - 1);
http://jsfiddle.net/cn5Gt/3/
Simplest of all:just replace your last line with the below line
alert(data.slice(0,-1));//where data is string
http://jsfiddle.net/cn5Gt/7/
DOC MDN : slice
How about something like this:
var data = $('.wrap').find('.text')
.map(function(i,el){ return el.value || null; })
.get().join(", ");
Demo: http://jsfiddle.net/cn5Gt/11/
jQuery's .map() method will "Pass each element in the current matched set through a function, producing a new jQuery object containing the return values." You can still include your if ( value != '' ) { test in the callback function because if your function returns null or undefined then .map() will not use that particular value. (I've used || null above as a shortcut to an if/else structure.)
Call .get() (or .toArray()) on the result and you'll have an actual array, which means you can then use the Array .join() method to form a string with the values comma separated.
If you need to do other processing on each item besides just getting the value you could stick with the .each() loop and add the values to an array that you then join after the loop (like some of the other answers), or just use the string .slice() method to remove the trailing comma and space characters.
Try this:
Using the length function to determine the position of the each
var fields = $('.wrap').find('.text');
var len = fields.length;
var data = '';
fields.each(function(index, element) {
var value = $(this).val();
if ( value != '' ) {
data += ' ' + value;
if (index != len - 1) {
data += ',';
}
}
});
alert(data);
I have multiple checkbox in my page. i want to retrieve its values if checked.
Here is HTML Code..
<input name="ctl1189" type="checkbox" id="chkTicket_189310" class=" chkTicket" value="189310">
<input name="ctl1190" type="checkbox" id="chkTicket_189311" class=" chkTicket" value="189311">
And So on..
Javascript Code:
function updateTicketAction() {
var allUpdatedVendorTickets = $('.chkTicket').filter(function() { return this.value != $input.is(':unchecked'); });
var sFinalUpdateList = '';
allUpdatedVendorTickets.each(function() {
var ids = $(this).attr('id').split('_')[1];
sFinalUpdateList += ((sFinalUpdateList == '') ? '' : '|') + ids + ',' + $(this).val();
});
alert(sFinalUpdateList);
}
function updateTicketAction() {
var sFinalUpdateList = '';
$("input.chkTicket:checked").each(
function() {
var ids = $(this).attr('id').split('_');
var id = ids[1];
sFinalUpdateList += ((sFinalUpdateList == '') ? '' : '|') + id + ',' + $(this).val();
}
);
alert(sFinalUpdateList);
}
http://jquery-howto.blogspot.com/2008/12/how-to-check-if-checkbox-is-checked.html
I just created a fiddle. Look in the JavaScript console for the resulting object, which you can then further process.
Code:
var checkedCheckboxes = $('.chkTicket:checked'),
results = {};
checkedCheckboxes.each(function () {
var key = $(this).attr('id').split('_')[1];
results[key] = $(this).val();
});
function alertResults(results) {
var text = '', sep = '';
$.each(results, function (key, value) {
text += sep + key + '=' + value;
sep = '|';
});
alert(text);
}
alertResults(results);
console.log(results);
try this code
var collect='';
$('input:checked').each(function(i,e){
collect+=(collect===''? $(e).attr('name')+'='+$(e).val():','+$(e).attr('name')+'='+$(e).val());
alert(collect);
})
Here is a jsfiddle snippet that returns all checked inputs..
One question though, why do you split your id-attribute when you have your id stored in value-attribute? Anyways, hope this works for you!
function updateTicketAction() {
var allUpdatedVendorTickets = $('.chkTicket:checked');
var sFinalUpdateList = '';
allUpdatedVendorTickets.each(function () {
sFinalUpdateList += ((sFinalUpdateList == '') ? '' : '|') + $(this).val();
});
alert(sFinalUpdateList);
}
Or you can use map():
var el = $('input[type=checkbox]:checked').map(function(i,e){
var id = $(e).attr('id').replace('chkTicket_', '');
var val = $(e).val();
return {
'id' : id,
'value' : val
}
});
console.log(el[0].id);
Your filter function is wrong.
this.value != $input.is(':unchecked');
You're comparing a .value property (string) to the return value of the .is jQuery method (boolean). It's similar to:
'value' != !true //checked
'value' != !false //unchecked
Both will always return true - unless value is 0 or an empty string which evaluates to a falsy value and the right side of the expression evaluates to false, for which the != different operator will return false.
So, your filter's callback doesn't filter anything at all, except taking out checked boxes with value 0 or no value (which is unintentional).
You can avoid using a filter function by using the :checked selector:
var allUpdatedVendorTickets = $('.chkTicket:checked');
Now you'll have a jQuery object containing only the checked .chkTicket, much better.
Next thing, you're making bad use of strings.
"189310,189310|189311,189311"
That's what your function is generating. Every time you need to manipulate those results, you'll have to split the string at |, creating a new array. It's much better to store it as an array already.
var sFinalUpdateList = [];
Assuming your keys and values are always the same as in your example, you should store them only once as well.
allUpdatedVendorTickets.each(function() {
sFinalUpdateList.push(this.value);
});
This will generate a much more clean and maintainable array with only the checked boxes' values:
sFinalUpdateList =>
[0] -> "189310"
[1] -> "189311"
You can obtain their IDs by appending chkTicket_ to those values.
jsFiddle