Generating a comma delimited string, from select element in jQuery - javascript

Here's what's going on. I have a select element, for which I need to get a comma delimited string of all its options, regardless of whether or not it's selected.
How can I, in jQuery/javascript take this:
<select id="currentTags" multiple>
<option>Nature</option>
<option>Cats</option>
<option>Space</option>
</select>
and turn it into this:
"Nature, Cats, Space"
I tried to find ways of doing this and couldn't... I'm still learning javascript, and my limited knowledge is stopping me in my tracks.
Any help would be appreciated, even if it's just to guide me in the right direction.
Thank you for your time.

With jQuery:
var result = $('#currentTags option').map(function(i, opt) {
return $(opt).text();
}).toArray().join(', ');
In plain JavaScript you can do something similar like this:
// Convert pseudo-arrays to real arrays
var __slice = Array.prototype.slice;
// Get select options as real array
var opts = __slice.call(document.querySelectorAll('#currentTags option'));
// Map the text of each option
var result = opts.map(function(x) {
return x.textContent;
}).join(', ');
console.log(result); //=> "Nature, Cats, Space"
The advantage of abstracting elements into collections instead of looping is that you maintain a consistent API (like jQuery), and you don't need to create extra variables to loop pseudo-arrays, as real arrays can use all array methods.
See the MDN to learn more about the DOM and the methods and properties you can use, like querySelectorAll, children, textContent and more.
Edit: This should work in IE9+ and all modern browsers.

The plain old javascript (POJS) way is to get the select's options collection, then loop over it to get the values and generate a string with the required format, e.g.
var options = document.getElementById('currentTags').options;
var values = [];
for (var i=0, iLen=options.length; i<iLen; i++) {
values.push(options[i].text);
}
alert(values.join(','));
You can write that in much more concise form but performance may suffer and depending on features used, may fail in some browsers. The above puts a premium on clarity and maintainability of code, performance will be at least as fast as any alternative.

How about just:
var tags = [];
$('#currentTags option').each(function() {
tags.push($(this).val());
});
console.log(tags.join(', ')); // 'Nature, Cats, Space'
http://jsfiddle.net/wN2Dk/

Here is a simple jQuery example:
var arr = []; // create array
$('#currentTags').children().each(function() {
arr.push($(this).text()); // add option text to array
});
alert(arr.join(', ')); // Nature, Cats, Space
If you want the option value, switch text() to val() ;)

A simple solution would be:
// Initialize your string
var output_string = "";
// For each 'option' tag, append its value to the string with the comma
$('#currentTags option').each(function() {
output_string = output_string+this.text;
});
// Removing the last ', ' which were added during the loop
output_string = output_string.substr(0, output_string.length-2);
Here's a Fiddle to see it into action :)

Related

How can I select elements on dom (with jQuery) that has some data attribute that ends with "created"?

I have all my elements, on a project, that are being transferred with data attributes so the javascript can know what to do.
But I have one problem, one part of the application must get all the created variables to compare time, and I have they saved like (data-product-created, data-category-created, data-link-created, etc...). It would be a huge headache if I had to put them manually on the jQuery selector...
Do jQuery has some method to search custom data attributes existence?
Like: element[data-(.*)-created]
You could create a low level Javascript method to loop through elements and pull their created values:
var getCreateds = function($els) {
var returnSet = [];
$els.each(function(i, el){
var elDict = {'el': el};
$.each(el.attributes, function(i, attr){
var m = attr.name.match(/data\-(.*?)\-created/);
if (m) elDict[m[1]] = attr.value;
});
returnSet.push(elDict);
});
return returnSet;
};
See demo
Based on mVChr answer (THANK YOU), i've rewritten the code on a simple, better and clean code:
jQuery('div').filter(function(){
for( var i in this.attributes ){
if(typeof this.attributes[i] !== 'object') continue;
if(this.attributes[i].name.match(/data\-(.*?)\-created/)) return true;
}
return false;
})
Changes:
+ Verifying attribute type... some attributes are browser internal functions or callbacks.
~ Using filter handler from jQuery, its better and cleaner way.
~ Using for instead of $.each, faster indeed.

Javascript Remove Form Data

I have a form that I want to only submit post data for value which have changed.
So the way I have been doing this is like this:
function submit_form(){
var hd = [];
// hd is a big array that is defined here
// hd ['some id_number'] = 'some value'
// main function
for (var id_number in hd ){
var x=document.getElementById(id_number).selectedIndex;
var y=document.getElementById(id_number).options;
selector_text = y[x].text;
if (hd[id_number] == selector_text){
$(id_number).remove();
}
}
document.forms["my_form"].submit()
}
So the goal is that if the selector equals what is in the array, then don't POST the data.
To do this I have been doing the remove function. Everything up to the remove function works as expected. However when I look at the post data I still get the selected value for the id_numbers that mach the value in hd.
Is there a better way to remove to prevent it from going to the POST data? The id.parent.removeChild(id) method didn't work either.
The jQuery id selector should begin with a #, but yours appears not to:
$('#' + id_number).remove();
Your for-in loop should be a regular incremental for loop, which is the proper way to iterate an array in JavaScript. for-in loops are typically used for iterating object properties rather than array elements.
for (var i=0; i<hd.length; i++) {
// Access hd[i] in the loop
var x=document.getElementById(hd[i]).selectedIndex;
var y=document.getElementById(hd[i]).options;
selector_text = y[x].text;
if (hd[i] == selector_text){
$('#' + hd[i]).remove();
}
}
Since you aren't really using jQuery here except for that line, instead the plain JS version is:
var removeMe = document.getElementById(hd[i]);
removeMe.parentNode.removeChild(removeMe);

how to collect form ids using jQuery

A jQuery selector $(".thumb_up") returns a collection of forms like this:
[<form id="like_post_78" ...</form> <form id="like_post_79"> ... </form>]
Ultimately I want to generate a string consisting of the numerical ending portion of the form ids.
"78,79"
What's the most efficient way of getting this?
The easiest way is probably:
var form_ids = $('form').map(function(){return this.id.replace(/[a-z_]/gi,'');}).get().join(', ');
console.log(form_ids); // or alert() or whatever...
JS Fiddle demo.
I've just updated the regex portion of the above, from /[a-z_]/gi to /\D/g (which basically greedily (g) replaces any non-digit characters (\D) with 'nothing'), to give the following code:
var form_ids = $('form').map(function(){return this.id.replace(/\D/g,'');}).get().join(', ');
console.log(form_ids);
JS Fiddle demo.
Edited after thinking on #James Hill's accurate observation (below) that easiest != most efficient:
keep in mind that the OP asks for the most efficient method, not the easiest.
Therefore, using plain JavaScript (which should, to the best of my knowledge, be available cross-browser):
var form_ids = [];
var forms = document.getElementsByTagName('form');
for (var i=0; i<forms.length; i++){
form_ids.push(forms[i].id.replace(/\D/g,''));
}
console.log(form_ids.join(', '));
JS Fiddle demo.
With a comparison of the two over at JS Perf, showing that JavaScript tends to be the faster (which implies it's more efficient, presumably because it's running native JavaScript/ECMAscript, rather than abstracted code that then calls native JavaScript/ECMAscript...)).
References:
map().
get().
join() at the MDN.
replace() at the MDN.
Option 1
Use jQuery's each() function in combination with the class selector:
var aryIDs = [];
$(".thumb_up").each(function(){
//Add ID to the array while stripping off all non-numeric data using RegEx
aryIDs.push(this.id.replace(/\D/g, ""));
});
//Get the ids
var csvIDs = aryIDs.toString();
Option 2
Grab the elements with jQuery and then use a plain old for loop:
var aryIDs = [];
var divs = $(".thumb_up");
for(var i= 0; i < divs.length; i++)
{
aryIDs.push(divs[i].id.replace(/\D/g, ""));
}
var csvIDs = aryIDs.toString();
Here's a working jsFiddle of the latter example.
Performance
As for performance, the for loop should be faster every time. Check out a simple jsPerf I created to compare the performance of .each(), .map(), and a standard for loop.
var str = "";
$(".thumb_up").each(function(){
var id = $(this).attr('id').split('like_post_');
str += id[1] + ',';
});
You'll end up with an extra "," at the end, but you can get to what you want with this basic example.
Just for the record, there is a document.forms collection that is every form in the document, so getting an array of all form ids is as simple as:
var ids = [];
var forms = document.forms;
for (var i = forms.length; i;) {
ids[--i] = forms[i].id;
}
If your definition of "efficiency" means fastest, the above should run rings about any of the jQuery answers (it does). If you only want forms with a particular class, it wouldn't be hard to filter them out with test of the form's className property in the loop.

JS - Splitting a string and looping through results

In JS, I'm having trouble working out how to split a string coming from an AJAX call.
This is what I have so far:
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
feedUpdateResponse = xmlhttp.responseText;
/////...split script.../////
}
}
xmlhttp.open("GET","https://myDomain.com/myScript.aspx",true);
xmlhttp.send();
Where you have /////...split script...///// in my script above, I need to add a little function that splits the string returned from my AJAX call.
The string simply contains names of DIVs, like this:
feedUpdateResponse = "div1/div2/div3/div4"
I would like to first split the string by its slashes (/) and run a loop through the different values and do stuff to those elements on my page.
To give an idea of what I need to achieve, I have given this example which is a mix of ASP & JS - it's the only way I can possibly describe it (and show that I've had an attempt) :)
MyArray = Split(feedUpdateResponse,"/")
For Each X In MyArray
documentGetElementById('updateAvailable_'+x).style.visibility="visible";
Next
On my page I have an ASP script that produces jquery carousels, all contained by separate DIVs. The DIVs are named DIV1, DIV2 etc. Inside DIV1, for example, is a text element called updateAvailable_div1 which will alert the user "There are new photos available for this feed, please click the refresh button".
Could somebody please explain to me how I can change my example above to work in JS? Just need to split the string into an array and loop through the split values...
You can use .split() to split a string on a specified character with the results returned as an array. So then it's just a matter of looping through the array:
// given your existing variable
// feedUpdateResponse = "div1/div2/div3/div4" as set in the
// code in the question, add this:
var a = feedUpdateResponse.split("/"),
i;
for (i = 0; i < a.length; i++) {
document.getElementById("updateAvailable_" + a[i]).style.visibility
= "visible";
}
Get your array via string.split("/"). Iterate your array using your method of choice. I prefer Array.forEach():
feedUpdateResponse.split("/").forEach(function (item) {
document.getElementById(item).style.visibility = "visible";
});
See the compatibility notes for using .forEach() in older browsers.
As an alternative:
for(element of feedUpdateResponse.split("/")){
do_your_thing();
}
Using for..in will end up giving you the indices on the array (keys), while for..on will give you the elements of the array (values).
You can also do:
for ([index, element] of Object.entries(feedUpdateResponse.split("/"))) {
do_your_thing();
}
In the event that you need the index.
The disadvantage is it not being compatible with IE, but for personal projects or a quick automation script it usually does me plenty fine.
Try this code:
var a = feedUpdateResponse.split("/");
for (i in a) {
document.getElementById("updateAvailable_" + a[i]).style.visibility
= "visible";
}
var feedUpdateResponse = "div1/div2/div3/div4";
var feedUpdateSplit = feedUpdateResponse.split("/");
for (var x = 0; x < feedUpdateSplit.length; x++) {
document.getElementById("updateAvailable_" + feedUpdateSplit[x]).style.visibility = "visible";
}

Parsing every element of an array as an integer

I have a string which I need to split into an array and then perform mathematical functions on each element of the array.
Currently I am doing something like this. (Actually, I am doing nothing like this, but this is a very simple example to explain my question!
var stringBits = theString.split('/');
var result = parseInt(stringBits[0]) + parseInt(stringBits[3]) / parseInt(stringBits[1]);
What I would like to know is if there is a way I can convert every element of an array into a certain type that would stop me from having to explicitly parse it each time.
An easier method is to map to the Number object
result= stringBits.map(Number);
javascript 1.6. has map() ( https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Objects/Array/Map ), so you can do something like
intArray = someArray.map(function(e) { return parseInt(e) })
You can just loop through it:
for(var i = 0; i < stringBits.length; i++) {
stringBits[i] = parseInt(stringBits[i]);
}
["1","2"].map(Number)
result: [1,2]
If you add a plus (+) sign in front of your strings they should be converted to numeric.
For example, this will print 3:
var x = "1";
var y = "2";
alert((+x) + (+y));
But I am not sure if this is portable to all browsers.
Your code will become:
var stringBits = theString.split('/');
var result = (+stringBits[0]) + (+stringBits[3]) / (+stringBits[1]);
But this is just a hack, so use with care.
I think the parseInt states better what you are trying to do, but you should delegate this responsibility to another method that returns the final data that you need to process. Convert and then process, don’t convert while processing. Your code will be easier to read.

Categories

Resources