How can I create an array from inside of the '.each loop' and use it outside of the loop?
My .each loop:
// Loop through all but button with class .apply
$('.profile-nav ul li a').not('.apply').each( function() {
// if currently loop through element has .cur class
if( $(this).hasClass('cur') ) {
//Get the first class of the match element
var ClassesToApply = $(this).prop('class').split(' ')[0];
}
//How can I create an array from all ClassesToApply?
//var arr = jQuery.makeArray(ClassesToApply);
// This will create an array, but with one element only
});
How can I create an array from all var = ClassesToApply?
And than how can I do something with this array?
e.g
$( allClasses from an array as a selectors).doStuff();
If you declare a variable outside of the each, it will be accessible inside the each:
var yourArray = [];
$('.profile-nav ul li a').not('.apply').each(function() {
if($(this).hasClass('cur')) {
yourArray.push($(this).prop('class').split(' ')[0]);
}
});
//Here, yourArray will contain the strings you require.
Although as others have shown, there are ways to shorten your code significantly.
fxnReqValidation = function () {
var InputTagArray = new Array;
InputTagArray = document.getElementsByTagName("input");
for (var iCnt = 1; iCnt <= InputTagArray.length; iCnt++) {
if ((g_Json[InputTagArray[iCnt].name].required == true) && (InputTagArray[iCnt].value == "")) {
$("#errormsg").text("please enter all required fields");
}
return false;
}
}
You could do:
var arr = $( 'a.cur:not(.apply)', '.profile-nav' ).map( function () {
return $( this ).prop( 'class' ).split( ' ' )[0];
}).get();
var list = $(".profile-nav ul li a.cur:not(.apply)");
list.each(function(){
// do your thing!
});
var arraySelectors = $('.profile-nav ul li a.cur:not(.apply)')
.toArray()
.map(e => '.' + Array.from(e.classList).join('.'));
This snippet is probably not the most elegant but it tries to accomodate to the objective the OP was describing.
I prefer not splitting a className because you never know how many consecutive spaces there is.
Exiting from the jQuery array and getting to a native array seems to be the best solution.
Array.from() is ES6 circa 2015
jQuery.toArray() appeared in jQuery 1.4
Related
I'm using the Dragsort plugin and we want to tag IDs in an array and print them.
My Html Code Is:
<ul id="list1">
<li class="ss"><div>1</div></li>
<li><div>2</div></li>
<li><div>3</div></li>
<li><div>4</div></li>
<li><div>5</div></li>
<li><div>6</div></li>
<li><div>7</div></li>
<li><div>8</div></li>
<li><div>9</div></li>
</ul>
<p id="demo"></p>
and my jQyery codes is
$("#list1, #list2").dragsort({ dragSelector: "div", dragBetween: true, dragEnd: saveOrder, placeHolderTemplate: "<li class='placeHolder'><div></div></li>" });
function saveOrder() {
var data = $("#list1 li").map(function() { return $(this).children().html(); }).get();
$("input[name=list1SortOrder]").val(data.join("|"));
};
$( "#list1 li" ).each(function( index ) {
let items = [];
items = [ index + 1];
console.log(items.map(() => index));
$(this).attr("id",items);
});
$('#hamid').click(function () {
$( "#list1 li" ).each(function() {
its = [ $(this).attr('id')];
});
});
When I want to return id <li> return last of them
You may want to change the line
its = [ $(this).attr('id')];
//this will only create an instance of an array with one element.
change the last function to something like:
$('#hamid').click(function () {
var ids = [];
$( "#list1 li" ).each(function() {
ids.push( $(this).attr('id') );
});
console.log(ids);
// this will print an array with all ids inside
// then you can return it or do whatever you want with it
});
I guess your issue is that you want to get all the IDs of the elements that matches #list1 li, as seen in the last 5 lines of your code. The reason why it is not working is because you are reassigning a brand new array to the its variable. I suggest doing one of the two:
Solution 1: Push into the array instead of reassigning it
Solution 2: Use .map() + .get() to return an array of all IDs
Solution 1 (basic)
Use Array.prototype.push() to append IDs to a pre-existing array. Remember that instead of converting this into a jQuery object and then accessing its ID via the .attr() method (by doing $(this).attr('id')), you can easily do this.id:
$('#hamid').click(function () {
var its = [];
$('#list1 li').each(function() {
its.push(this.id);
});
console.log(its);
});
Solution 2 (better)
Use a combination of .map() and .get(). This is the most jQuery-way to do it:
$('#hamid').click(function () {
var its = $('#list1 li').map(function() {
return this.id;
}).get();
console.log(its);
});
The reason why .get() is needed is because .map() returns a jQuery collection instead of an actual array. To retrieve the array itself, you will need to append .get() after .map().
I am trying to loop through an array of elements and then validate each instance of each element. This is how I am doing it:
var elements = ["h1","h2","h3","h4","p","strong","label","span","a"];
function targetZWS(){
for (var i = 0; i < elements.length; i++) {
var item = $(".page-content "+elements[i]);
$(item).each(function() {
checkElement(this);
});
}
}
This throws a warning that I am creating a function inside a loop, how do I avoid this?
You are trying too hard :) JQuery allows you to enter multiple options in a single selector.
function targetZWS(){
$("h1,h2,h3,h4,p,strong,label,span,a").each(function() {
checkElement(this);
});
}
}
http://api.jquery.com/multiple-selector/
Use .each() to loop through the array as:
$(function() {
var elements = ["h1","h2","h3","h4","p","strong","label","span","a"];
$.each(elements, function(index, value) {
alert(value);
var sel = ".page-content" + value
var item = $("sel");
$(item).each(function() {
checkElement(this);
});
})
})
DEMO
Hello I can't find out how to delete a specific value from string when clicking on an element with the string value. its for my todo list.
if (window.localStorage.fullName !== undefined) {
alert('Your browser does not support localStorage');
} else {
$(function () {
console.log('localSorage compitability detected. proceeding...');
global vars & functions
var tdli = [];
add list items
$('#tdladd').click(function () {
$('.todolist ul ul').append("<li class='tdli'>" + $('#tdlinput').val() + "</li>");
tdli.push($('#tdlinput').val());
$('#tdlinput').val('');
var array = tdli + "";
localStorage.setItem('tdlis', array);
console.log(array);
$('#todolist').hide().fadeIn('fast');
});
remove list items
$('li').click(function () {
var itemtoRemove = $(this);
tdli.splice($.inArray(itemtoRemove, tdli), 1);
console.log(tdli);
});
$('#clearall').click(function () {
localStorage.clear();
location.reload();
});
load list items
var tdlitems = localStorage.getItem('tdlis');
var array = tdlitems.split(',');
tdli.push(array);
for (var i = 0; i < array.length; i++) {
array[i] + "<br>";
$('.todolist ul ul').append("<li>" + array[i] + "</li>");
};
console.log(array);
});
}
Assuming that tdli is a jQuery wrapped set (which itself is an array-like-object), it will have DOM nodes stored instead of another jQuery objects. That means, just go like
var itemtoRemove = this;
and you should be fine.
After you posted your complete code, we can see you're actually pushing string values into your tdli Array, but you try to .splice() objects respectively DOM nodes, which of course doesn't make any sense at all (comparing apples to oranges).
I'm trying to create an array in Javascript with a size that is equivalent to the number of times a certain class is found in the DOM, and then iterate through it to grab the text from an input field present in that class. I can easily do this like so:
var count = 0;
$('.className').each(function() {
count++;
});
var classes = new Array(count);
count = 0;
$('.className input[type=text]').each(function() {
classes[count++] = $(this).val();
});
This looks like a lot of code for what seems to be a relatively simple task. Is there a more efficient or less lengthy way of doing this?
Thanks
It looks like you want this :
var classes = $('.className input[type=text]').map(function(){
return this.value
}).get();
But it's a guess : it's not clear why you start by counting all elements of the class and then iterate on the inputs.
You can construct an array of elements directly from your selector via the makeArray function, then transform the result using a map.
var classes = $.makeArray($('.className input[type=text]')).map(function() {
return $(this).val();
});
Use jQuery's map function, then get if you need a pure array:
var values = $('.className input[type=text]').map(function() {
return $(this).val();
}).get();
each passes the index, so you don't need to do it yourself:
var classes = [];
$('.className input[type=text]').each(function(index, value) {
classes[index] = $(this).val();
});
Arrays are dynamic and therefore don't need to be initialized. Create a new array, loop through the inputs and push the values to the new array:
var classes = [];
$('.className input[type=text]').each(function(idx, elem) {
classes.push($(elem).val());
});
In an each function, I search through the DOM for many elements with a specific className. This ClassName, according to its length, will create an array that is long 2 or 4.
I need to select these two type of element separately in order to act differently.
How can I do that?
<div class="foo-1"></div>
<div class="foo-1"></div>
<div class="foo-1-boo-2"></div>
jQuery
$( '[class*=foo-]' ).each(function() {
var foo = $( this );
var fooArray = foo.attr( 'class' ).split( '-' );
var arrayLength = fooArray.length;
});
the console will return that there are 3 elements, two of them have length 2 and one 4.
I need to separate these two results in order to act differently as they were variables.
I need something like:
var caseA = (foo with an arrayLength === 2);
var caseB = (foo with an awwayLength === 4);
One possible way is to use .filter method with a function as an argument:
var elements = $('[class*=foo-]'),
caseA = elements.filter(function() {
return this.className.split('-').length === 2;
}),
caseB = elements.filter(function() {
return this.className.split('-').length === 4;
});
console.log(caseA.length, caseB.length);
I'm guessing you want these as jQuery sets instead of arrays so you can easily manipulate them en masse with jQuery. So this will do it:
var caseA = $('[class*=foo-]').filter(function() {
return $(this).attr("class").split("-").length === 2;
});
var caseB = $('[class*=foo-]').filter(function() {
return $(this).attr("class").split("-").length === 4;
});
If you have tons of elements and it proves to be slow you can optimize this slightly by making it more complex and using one each instead of filter. But I wouldn't bother until it proves to be necessary.
Another possible way is to just use a conditional statement -
$('[class*=foo-]').each(function () {
var foo = $(this);
var fooArray = foo.attr('class').split('-');
var arrayLength = fooArray.length;
(2 == arrayLength ? console.log('to do something') : '');
(4 == arrayLength ? console.log('do something for') : '');
});
I mixed two solutions in the comment of this post:
var caseA = col.filter(function() {
return this.className.split( '-' ).length === 2;
});
var caseB = col.filter(function() {
return this.className.split( '-' ).length === 4;
});