jQuery .each: Do not add comma in last field - javascript

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);

Related

How can I remove certain elements of a query string?

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'.

Passing multiple checkbox values in AJAX call

I use a ternary operator to check which checkboxes in a form have been selected. If a value has been selected, I affix the name-value pair to a query string which is then passed in an AJAX call. If not, I attach a name with an empty string value.
It works fine, I'm just wondering if there's a more compact/elegant way to do this as it seems somewhat verbose. I'm wondering if it's possible to use a for loop. The reason I'm not sure if this would work is it would involve dynamically assigning variable names within the loop based on the index.
var fields = $('input[name="apn"]').serializeArray();
var apn1 = fields[0] ? fields[0]["value"] : ''
query += '&apn1=' + apn1;
var apn2 = fields[1] ? fields[1]["value"] : ''
query += '&apn2=' + apn2;
var apn3 = fields[2] ? fields[2]["value"] : ''
query += '&apn3=' + apn3;
var apn4 = fields[3] ? fields[3]["value"] : ''
query += '&apn4=' + apn4;
var apn5 = fields[4] ? fields[4]["value"] : ''
query += '&apn5=' + apn5;
...
Map the values and indices to an array of objects, and just pass that directly to $.ajax, jQuery will use $.param on it for you :
var fields = $.map($('input[name="apn"]'), function(el, i) {
var o = {};
o['apn' + i] = el.value;
return o;
});
If its just checkboxes:
$('input[name="apn"]').each(function (i, el) {
if($(el).is(':checked')) {
query += '&apn'+i+'=' + el.value;
}
});
You can simply serialize the form:
var query = $("#FormId").serialize();

Getting undefined in dropdown from json content

EDIT 2
Check the fiddle - http://jsfiddle.net/SN5zT/2/
Following is the fiddle for which I am not sure why I am getting undefined in dropdown.
My fiddle - http://jsfiddle.net/z6GDj/
var res = '{"allSportPosition":{"25":"Forwards (Strickers)","27":"Fullbacks (Defenders)","28":"Goalkeeper ","26":"Midfielders"}}';
try {
var sportPositionOptions = '';
var parsedJson = JSON.parse(res);
var allSportPosition = parsedJson.allSportPosition;
var values = new Array();
$.each(allSportPosition, function (index, value) {
values[index] = value;
});
//alert(values.length);
values.sort();
$.each(values, function (atIndex, atValue) {
sportPositionOptions = sportPositionOptions + '<option value="' + atIndex + '">' + atValue + '</option>';
});
$(sportPositionOptions).appendTo("#player");
} catch (e) {
alert("Parsing error:" + e);
}
$.each is automatically sorting keys to 25,26,27,28 for res.
Please explain the reason of this and why I am getting undefined ?
Let me know If i need to explain it more, I will surely do it :)
EDIT
Please explain the reason why it is getting sorted automatically http://jsfiddle.net/SN5zT/
Try
values.push(value);
instead of
values[index] = value;
Fiddle Link
The following script is working, I also figured out where the "undefineds" came from.
http://jsfiddle.net/z6GDj/3/
var res = '{"allSportPosition":{"25":"Forwards (Strickers)","27":"Fullbacks (Defenders)","28":"Goalkeeper ","26":"Midfielders"}}';
try{
var sportPositionOptions = '';
var parsedJson = JSON.parse(res);
var allSportPosition = parsedJson.allSportPosition;
var values = allSportPosition;
//$.each(allSportPosition, function(index, value) {
// values[index] = value;
//});
//alert(values.length);
$.each(values,function(atIndex, atValue){
sportPositionOptions = sportPositionOptions+'<option value="'+atIndex+'">'+atValue+'</option>';
});
$(sportPositionOptions).appendTo("#player");
}
catch(e){
alert("Parsing error:"+ e);
}
The array is sorted automatically, because the keys are set correctly.
see http://www.w3schools.com/js/js_obj_array.asp. "An array can hold
many values under a single name, and you can access the values by
referring to an index number."
Or: Change the index, and you´re changing the order. (index indicates the order).
The undefined values are created by javascript default, check the last answer in here (How to append something to an array?)
"Also note that you don't have to add in order and you can actually
skip values, as in
myArray[myArray.length + 1000] = someValue;
In which case the values in between will have a value of undefined."
Since you are passing an object to each(), jquery passes the key as the index parameter. In your object, the keys are ranged from 25 to 28. Setting the array using the values[25] on an empty array will expand the array to index 25, with the first 25 elements undefined. Using values.push(value) will append the value at the end of the array.
$.each is doing the following assignment that is why you are getting so many undefined
values[25] = "Forwards (Strickers)"
values[26] = "Midfielders"
values[27] = "Fullbacks (Defenders)"
values[28] = "Goalkeeper"
During $.each browsers will automatically sort the keys if the keys are integer, one way to avoid this is use non integer keys
What you need to do is define your options before you sort them , and then append them to your select:
var res = '{"allSportPosition":{"25":"Forwards (Strickers)","27":"Fullbacks (Defenders)","28":"Goalkeeper ","26":"Midfielders"}}';
try {
var sportPositionOptions = '',
parsedJson = JSON.parse(res),
allSportPosition = parsedJson.allSportPosition,
options = new Array();
$.each(allSportPosition, function (index, value) {
options[index] = $('<option></option>', {
value: index,
text: value
});
});
$.each(options, function (index) {
$('#player').append(options[index]);
});
} catch (e) {
alert("Parsing error:" + e);
}
jsfiddle: http://jsfiddle.net/z6GDj/11/

Return Multiple CheckBox Values if Checked in jQuery

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

Remove a value from string in hidden field with jQuery

I have a hidden field that stores all of the id's of images that have been uploaded for a specific post.
The hidden field HTML looks something like this:
<input type="hidden" id="post_images" name="post_images" value="1,2,3,4,5" />
When an image is deleted from the post, I need to remove it's image_id from that hidden field. So if I delete image_id 4 from the post, the hidden field needs to update to be value="1,2,3,5"
I'm open to changing the way I store the image_id's for the post to a different format if there is a better way of doing this.
While you could use this dirty regex:
$("#post_images").val(function(i, v) {
return v.replace( new RegExp('(?=(?:^|,))(,?)' + id + '(?=(?:,|$)),?'), '$1' );
});
Here's the fiddle: http://jsfiddle.net/43hhs/
A more sane way would be to use array splicing:
$("#post_images").val(function(i, v) {
var values = v.split(','),
i = $.inArray(id.toString(), values);
if ( i != -1 ) {
values.splice(i, 1);
return values.join(',');
}
else {
return v;
}
});
Here's the fiddle: http://jsfiddle.net/khHPq/
jsFiddle: http://jsfiddle.net/4Mwsu/15/
$(".imageRemove").click( function()
{
$(this).hide();
var values = $("#post_images").val().split(",");
var newValue = "";
for ( var i = 0 ; i < values.length ; i++ )
{
if ( $(this).attr("id") != values[i] )
{
newValue = newValue + values[i] + ",";
}
}
$("#post_images").val( newValue );
});​
You might consider using jQuery's data method instead, which lets you store true arrays. If you need data to be passed in the value of the elements, you can convert back and forth at your convenience, such as in an .on('submit', ...) handler.
The following code is a bit cumbersome, but I think it communicates the idea.
$pi = $('#post_images');
$pi.data('values', $pi.val().split(',') );
// now .data('values') is a true JS array
console.log($pi.data('values').indexOf("3")); // 2
$pi.data('values').splice(2,1); // removes the third element
console.log($pi.data('values')); // ["1","2","4","5"]
$pi.val( $pi.data('values').join(',') );
console.log($pi.val()); // "1,2,4,5"​​​​​​​​
http://jsfiddle.net/mblase75/vx3XL/2/
using that, to me easiest way to go would be to have the value start and end in ',', then you can just do a
$("#post_images").val($("#post_images").val().replace("," + idtoremove + ",", ",")
var theVals = $(':input').val().split(','); //split the values into an array
var myVal = '4'; //this should be the ID of the element you want to remove
if($.inArray(myVal, theVals)){ //is the item in the array
index = theVals.indexOf(myVal); //if it is, then get the index position
theVals.splice(index, 1); //starting at the index of the element in the array, remove 1 element
$(':input').val(theVals); //update the input with the new array of IDs
}
console.log($(':input').val()); //general purpose to visualize this output
a working jsFiddle

Categories