TheDuck
TheDuck

Reputation: 105

Check if each div has an element with a specific class inside it

I have a tree of div elements with the same class but different id as we can see below:

<div class="resultsAnalitics" id="result_0">
  <span class="successResults">Success</span>
</div>

<div class="resultsAnalitics" id="result_1">
  <span class="warningResults">Warning</span>
</div>

<div class="resultsAnalitics" id="result_2">
  <span class="dangerResults">Danger</span>
</div>

I have to check which class exists in each of these divs and show on the console. For this I created the following code:

$( ".resultsAnalitics" ).each(function( index ) {
var current = $(this).attr('id');

console.log("I'm on div: " + current);

if($(this).has('.successResults')){
console.log('The results is success');
}

if($(this).has('.warningResults')){
console.log('The results is warning');
}

if($(this).has('.dangerResults')){
console.log('The results is danger');
}


});

I expected to get the following results like this:

I'm on div: result_0 The results is success

I'm on div: result_1 The results is warning

I'm on div: result_2 The results is danger

But I'm getting the following results:

I'm on div: result_0 The results is success The results is warning The results is danger

I'm on div: result_1 The results is success The results is warning The results is danger

I'm on div: result_2 The results is success The results is warning The results is danger

How I can solve this problem?

Upvotes: 3

Views: 3291

Answers (6)

Saurabh More
Saurabh More

Reputation: 34

You can always use jQuery "find" method to check out for specific elements in a particular element.It returns jQuery object. Using this object we can further check for number of elements by using 'length'.

<div class="resultsAnalitics" id="result_0">
  <span class="successResults">Success</span>
</div>

<div class="resultsAnalitics" id="result_1">
  <span class="warningResults">Warning</span>
</div>

<div class="resultsAnalitics" id="result_2">
  <span class="dangerResults">Danger</span>
</div>

<script>
$( ".resultsAnalitics" ).each(function( index ) {
var current = $(this).attr('id');

console.log("I'm on div: " + current);

if($(this).find('.successResults').length){
console.log('The results is success');
}

if($(this).find('.warningResults').length){
console.log('The results is warning');
}

if($(this).find('.dangerResults').length){
console.log('The results is danger');
}


});
</script>

Upvotes: 0

Mihai Alexandru-Ionut
Mihai Alexandru-Ionut

Reputation: 48357

One efficiency solution is to use .children method, because you have to check if span children of each div has one certain class.

children method gets the children of each element in the set of matched elements, optionally filtered by a selector.

$( ".resultsAnalitics" ).each(function( ) {
var current = $(this).attr('id');

console.log("I'm on div: " + current);

if($(this).children('.successResults').length){
console.log('The results is success');
}

if($(this).children('.warningResults').length){
console.log('The results is warning');
}

if($(this).children('.dangerResults').length){
console.log('The results is danger');
}


});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="resultsAnalitics" id="result_0">
<span class="successResults">Success</span>
</div>

<div class="resultsAnalitics" id="result_1">
<span class="warningResults">Warning</span>
</div>

<div class="resultsAnalitics" id="result_2">
<span class="dangerResults">Danger</span>
</div>

Upvotes: 3

Phil
Phil

Reputation: 11175

// Grabs all classes that end with Results within resultsAnalitics     
var results = $(".resultsAnalitics span[class$='Results']");

// loop through each, grabbing parent id and innerHTML
results.each(function(idx, node) {
    console.log("I'm on div:", node.parentNode.id, "- Result are:", node.innerHTML);
})

Upvotes: 0

Josh Crozier
Josh Crozier

Reputation: 240908

You were close.

The problem is that the .has() method will still return a jQuery object even if an element isn't selected. As the relevant jQuery documentation states, the .has() method will "reduce the set of matched elements to those that have a descendant that matches the selector or DOM element".

This means that your conditional statements were always true, which is why the message was logged regardless of whether any elements were found.

To check if any elements are returned from the jQuery object, check the .length property of the jQuery object in your conditional statements. In doing so, the value will be 0 when an element isn't found.

Your updated code would be:

$(".resultsAnalitics").each(function(index) {
  console.log("I'm on div: " + this.id);

  if ($(this).has('.successResults').length) {
    console.log('The results is success');
  }

  if ($(this).has('.warningResults').length) {
    console.log('The results is warning');
  }

  if ($(this).has('.dangerResults').length) {
    console.log('The results is danger');
  }
});

Upvotes: 3

gavgrif
gavgrif

Reputation: 15499

You could go the other way and target each of the classes specifically and then find the id of the parent container. Notethat I added another success div at the bottom to demonstrate that all success divs give the parent ID and then the warning and then the danger.

$(".successResults" ).each(function(){
var parent = $(this).parent().attr('id');
  console.log("I'm on div: " + parent + ' - The results is success');
});

$(".warningResults" ).each(function(){
var parent = $(this).parent().attr('id');
  console.log("I'm on div: " + parent + ' - The results is warning');
});

$(".dangerResults" ).each(function(){
var parent = $(this).parent().attr('id');
  console.log("I'm on div: " + parent + ' - The results is danger');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="resultsAnalitics" id="result_0">
<span class="successResults">Success</span>
</div>

<div class="resultsAnalitics" id="result_1">
<span class="warningResults">Warning</span>
</div>

<div class="resultsAnalitics" id="result_2">
<span class="dangerResults">Danger</span>
</div>

<div class="resultsAnalitics" id="result_3">
<span class="successResults">Success</span>
</div>

Upvotes: 1

Przemysław Melnarowicz
Przemysław Melnarowicz

Reputation: 1057

You could use .find() (checking length of search result) and use loop to make it more elegant and elastic for further changes.

http://codepen.io/themeler/pen/mRgKLP

$( ".resultsAnalitics" ).each(function( index ) {
    var $this = $(this),
        current = $this.attr('id'),
        states = [
            {
                name: '.successResults',
                msg: 'The results is success'
            },
            {
                name: '.warningResults',
                msg: 'The results is warning'
            },
            {
                name: '.dangerResults',
                msg: 'The results is danger'
            }
        ];

    for (var i = 0; i < states.length; i++) {
        if ($this.find(states[i].name).length) console.log("I'm on div: " + current, states[i].msg)
    }

});

Upvotes: 0

Related Questions