jQuery to loop through elements with the same class - javascript

I have a load of divs with the class testimonial and I want to use jquery to loop through them to check for each div if a specific condition is true. If it is true, it should perform an action.
Does anyone know how I would do this?

Use each: 'i' is the postion in the array, obj is the DOM object that you are iterating (can be accessed through the jQuery wrapper $(this) as well).
$('.testimonial').each(function(i, obj) {
//test
});
Check the api reference for more information.

try this...
$('.testimonial').each(function(){
//if statement here
// use $(this) to reference the current div in the loop
//you can try something like...
if(condition){
}
});

It's pretty simple to do this without jQuery these days.
Without jQuery:
Just select the elements and use the .forEach() method to iterate over them:
const elements = document.querySelectorAll('.testimonial');
Array.from(elements).forEach((element, index) => {
// conditional logic here.. access element
});
In older browsers:
var testimonials = document.querySelectorAll('.testimonial');
Array.prototype.forEach.call(testimonials, function(element, index) {
// conditional logic here.. access element
});

Try this example
Html
<div class="testimonial" data-index="1">
Testimonial 1
</div>
<div class="testimonial" data-index="2">
Testimonial 2
</div>
<div class="testimonial" data-index="3">
Testimonial 3
</div>
<div class="testimonial" data-index="4">
Testimonial 4
</div>
<div class="testimonial" data-index="5">
Testimonial 5
</div>
When we want to access those divs which has data-index greater than 2 then we need this jquery.
$('div[class="testimonial"]').each(function(index,item){
if(parseInt($(item).data('index'))>2){
$(item).html('Testimonial '+(index+1)+' by each loop');
}
});
Working example fiddle

you can do it this way
$('.testimonial').each(function(index, obj){
//you can use this to access the current item
});

jQuery's .eq() can help you traverse through elements with an indexed approach.
var testimonialElements = $(".testimonial");
for(var i=0; i<testimonialElements.length; i++){
var element = testimonialElements.eq(i);
//do something with element
}

divs = $('.testimonial')
for(ind in divs){
div = divs[ind];
//do whatever you want
}

I may be missing part of the question, but I believe you can simply do this:
$('.testimonial').each((index, element) => {
if (/* Condition */) {
// Do Something
}
});
This uses jQuery's each method: https://learn.jquery.com/using-jquery-core/iterating/

You can do this concisely using .filter. The following example will hide all .testimonial divs containing the word "something":
$(".testimonial").filter(function() {
return $(this).text().toLowerCase().indexOf("something") !== -1;
}).hide();

With a simple for loop:
var testimonials= $('.testimonial');
for (var i = 0; i < testimonials.length; i++) {
// Using $() to re-wrap the element.
$(testimonials[i]).text('a');
}

Without jQuery updated
document.querySelectorAll('.testimonial').forEach(function (element, index) {
element.innerHTML = 'Testimonial ' + (index + 1);
});
<div class="testimonial"></div>
<div class="testimonial"></div>

You could use the jQuery $each method to loop through all the elements with class testimonial.
i => is the index of the element in collection and val gives you the object of that particular element and you can use "val" to further access the properties of your element and check your condition.
$.each($('.testimonal'), function(i, val) {
if(your condition){
//your action
}
});

In JavaScript ES6 .forEach()
over an array-like NodeList collection given by Element.querySelectorAll()
document.querySelectorAll(".testimonial").forEach((el, idx) => {
el.style.color = "red";
console.log(`${idx} Element ${el.tagName} with ID #${el.id} says: ${el.textContent}` );
});
<p class="testimonial" id="1">This is some text</p>
<div class="testimonial" id="2">Lorem ipsum</div>

$('.testimonal').each(function(i,v){
if (condition) {
doSomething();
}
});

More precise:
$.each($('.testimonal'), function(index, value) {
console.log(index + ':' + value);
});

Related

How to select a specific <span> with the same class names?

I am attempting to extract some data from this block of HTML.
<div class="group-capitalization-content field-group-html-element">
<h2><span>Capitalization</span></h2>
<div class="item">
<div class="label-inline">Issued & Outstanding: </div>
<span class="number">242906121</span>
</div >
<div class="item">
<div class="label-inline">Reserved for Issuance: </div>
<span class="number">51423534</span >
</div>
</div>
I'm using an npm module called cheerio to scrape data from HTML. Thus I have the following code to try and get the "numbers".
var data = $('.group-capitalization-content .item .number').text();
Running this code results in: 24290612151423534, which is both results appended together.
How do I select the individual numbers here / separate them?
If the above example is all you need, use .eq().
First items's text() is
$('.group-capitalization-content .item .number').eq(0).text();
...and second is
$('.group-capitalization-content .item .number').eq(1).text();
If you have a more complex case and you need to store the data in an array, for later, I'd use $.map() (#Sushanth's answer) - probably a bit more specific, to rule out the possibility of other .numbers in the page:
let data = $.map(
$('.group-capitalization-content .item .number'),
function(e){ return $(e).text() }
);
You could you map method and target the .number class, which will spit out the contents into an array.
let data = $.map($('.number'), function(elem) {
return $(elem).text();
});
console.log(data);
If you don't know ahead of time how many there will be you can loop through them with an .each
$('.group-capitalization-content .item .number').each(function() {
$(this).text(); // Save this to a var or do something with it
});
How about each function to go through each of your results, like:
$('.group-capitalization-content .item .number').each(function(index, element) {
//your individual item code goes here
console.log( index + ": " + $( this ).text() );
});
i usually get all the dom elements and then loop over them to do my necessary functions. here is a working fiddle. https://jsfiddle.net/bbmtk7tm/
var data = $('.group-capitalization-content .item .number');
for(var i=0; i<data.length;i++)
{
console.log(data[i].innerHTML);
}

Removing specific classes from all div elements of certain format

I would like to remove all classes starting with nf-
Console image
JSfiddle
https://jsfiddle.net/zapjelly/fda3Lm84/11/
I have the following HTML/JS:
var nfClasses = document.querySelectorAll('.custom-nf [class*="nf-"]');
Array.prototype.map.call(nfClasses, function(elem) {
Array.prototype.map.call(elem.classList, function(classStr) {
if (classStr.match(/^nf\-/)) elem.classList.remove(classStr);
});
});
<p>Remember to inspect element on the input below</p>
<div class="custom-nf">
<div class="input nf-input-outer nf-validation">
<div class="nf-container">
<div class="nf-outer nf-outer-input nf-outer-validation">
<div class="nf-middle">
<div class="nf-inner">
<label for="dummy" class="nf-label"></label>
<input id="dummy" type="text" class="nf-input">
</div>
</div>
</div>
</div>
</div>
</div>
As stated by MDN, the .classList property returns a live DOMTokenList of the class attributes of the element. The key point is that the list is live, which means that as you remove classes, you are inadvertently skipping over some of the other classes while iterating over them.
Based on the code that you provided, you could simply create a copy of the class list so that it is no longer live. You can do this by calling the .slice() method:
Updated Example
var nfClasses = document.querySelectorAll('.custom-nf [class*="nf-"]');
Array.prototype.forEach.call(nfClasses, function(element) {
var classListCopy = Array.prototype.slice.call(element.classList);
classListCopy.forEach(function(className) {
if (className.match(/^nf\-/)) {
element.classList.remove(className);
}
});
});
Alternatively, you could also iterate over the classes backwards. In doing so, none of the classes will be skipped:
Updated Example
var nfClasses = document.querySelectorAll('.custom-nf [class*="nf-"]');
Array.prototype.forEach.call(nfClasses, function(element) {
for (var i = element.classList.length; i >= 0; i--) {
if (element.classList[i] && element.classList[i].match(/^nf\-/)) {
element.classList.remove(element.classList[i]);
}
}
});
A third option would be to just use a regular expression to replace the classes:
var nfClasses = document.querySelectorAll('.custom-nf [class*="nf-"]');
Array.prototype.forEach.call(nfClasses, function(element) {
element.className = element.className.replace(/\bnf-\S+\b/g, '').trim();
});
Updated inner loop to slice as suggested and working now
https://jsfiddle.net/zapjelly/fda3Lm84/12/
var nfClasses = document.querySelectorAll('.custom-nf [class*="nf-"]');
Array.prototype.map.call(nfClasses,
function(elem){
Array.prototype.slice.call(elem.classList).map(
function(classStr){
if(classStr.match(/^nf\-/)) elem.classList.remove(classStr);
})
});

JQuery: Don't search within children

Let's say I wan't to find all the elements that have a data-view attribute but I there can be elements that have data-view which are parents to other data-view elements. I don't want the children to be in the search, I want the parents.
$('[data-view]').each(function() {});
with the following HTML:
<body>
<div data-view="app">
<div data-view="hello1">
</div>
</div>
<div data-view="job">
</div>
</body>
It should return only app and job and not hello1. I've had no luck in using the .not selector has it stops selecting any [data-view] elements.
Any suggestions?
Try:
var target_attr = "[data-view]";
$(target_attr).filter(function () {
return !$(this).find(target_attr).length;
}).each(function () {
// Whatever
});
DEMO: http://jsfiddle.net/gEVyk/1/
This will find all elements with the data-view attribute that have 0 descendants with the same attribute. In your case, that's hello1 and job.
If you're sure they're only <div>s, you should use div[data-view].
This will find all elements with the attribute that have 0 parents with the same attribute:
var target_attr = "[data-view]";
$(target_attr).filter(function () {
return !$(this).parents(target_attr).length;
}).each(function () {
// Whatever
});
DEMO: http://jsfiddle.net/ue9w9/1/
In your case, that's app and job.
How about
$('[data-view]:not([data-view] [data-view])').each(function() {});
http://jsfiddle.net/p5P8X/
Try something like $("body").children("[data-view]"). The .children() will only look at the immediate descendents of the selected element.
This should do the trick:
$('[data-view]:not([data-view] [data-view])').each(function() { ... });

jQuery select if multiple elements has the same class

Example HTML:
<div class="elem-1"></div>
<div class="elem-2"></div>
<div class="elem-2"></div>
<div class="elem-3"></div>
<div class="elem-4"></div>
<div class="elem-4"></div>
<div class="elem-4"></div>
Needed:
How can I select the div's which has "elem-2"s and "elem-4"s with jQuery selectors? (multiple elements has same class)
You can use , to separate different selectors:
$(".elem-2, .elem-4")
selector will be given the value that you desire
http://jsfiddle.net/mMEN5/1
var selector = $();
var list = $('[class]').toArray().reduce(function(p, e){
p = p || {};
var classes = $(e).prop('class').split(/\s/);
$.each(classes, function(i,c){
p[c] = p[c] || [];
p[c].push(e);
});
return p;
}, {})
for (el in list) if (list[el].length > 1) selector=selector.add(list[el]);
​
$('.elem-2, .elem-4').hide() // or any other jquery method
By the way, it's not a jQuery selector, it's just a CSS selector, see this article for an explanation
Even though you have asked for css selector, we can also use the attributeStartsWith selector
I will just mention the selector usage. you can use to for any internal DOM chnage
alert($('div[class^="elem-2"], div[class^="elem-4"]').length);
here i have used .length just to give a correct count. Use can use above with id attributes also.

How to use jquery to select all elements that have two specific attributes

I have some markup where a lot of id's have an id attribute, as well as innerText. I want to select each of these elements, performing a function on the id.
How do I do that?
Something like this?
$('[id]:not(:empty)').each(function(i, el) {
// do stuff
});
Give them a common class:
HTML
<div id="first" class="all"></div>
<div id="second" class="all"></div>
<div id="third" class="all"></div>
jQuery
$('div.all').each(function(index){
processid(this.id);
});
If you are talking about selecting elements whose id (or some permutation of it) is included in its text then
$('[id]').filter(function(){
return $(this).text().indexOf( this.id ) >= 0; // the this.id should be altered to match the permutation you seek ..
}).css('color','red'); // turn those to red
After you comment to #lonesomeday (at the question comments) here is what to do ..
$('[id]').each(function(){
processid(this.id);
});
First select by a regular ID selector and then loop over that selection by filtering .text() non-empty.
$("[id]").each(function() {
if ($(this).text() != "") {
// do stuff
}
});

Categories

Resources