CyberJ
CyberJ

Reputation: 1124

jQuery onclick in for each selector

When I click a button div, I want to add a class named active to the popup div that has the corresponding class name in the data-trigger attribute.

For example if I click on the div with class name button-two, the div with data-trigger="button-two" should get class active.

The issue: active is added only to the last popup div. How can I make this work?

Here's what I have tried:

$('.popup').each(function() {

  popupObj = $(this);
  var popupTrigger = popupObj.data("trigger");

  $('.' + popupTrigger).click(function() {
    popupObj.addClass('active');
  });

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="button-one">Test 1</div>
<div class="button-two">Test 2</div>
<div class="button-three">Test 3</div>

<div class="popup" data-trigger="button-one">Hello world</div>
<div class="popup" data-trigger="button-two">Hello there</div>
<div class="popup" data-trigger="button-three">Hello again</div>

Upvotes: 0

Views: 63

Answers (4)

MichaelvE
MichaelvE

Reputation: 2578

Here's a solution that matches the popup to the button using the same data trigger for both:

$(document).ready(function() {
  $(".btn").click(function() {
    var trigger = $(this).data("trigger");
    $('.popup').each(function() {
      if ($(this).data("trigger") == trigger) {
        $(this).addClass('active');
      } else {
        $(this).removeClass('active');
      }
    });
  });

});
.active {
  background-color: coral;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="btn" data-trigger="button-one">Test 1</div>
<div class="btn" data-trigger="button-two">Test 2</div>
<div class="btn" data-trigger="button-three">Test 3</div>

<div class="popup" data-trigger="button-one">Hello world</div>
<div class="popup" data-trigger="button-two">Hello there</div>
<div class="popup" data-trigger="button-three">Hello again</div>

Upvotes: 0

Paulo Pedroso
Paulo Pedroso

Reputation: 3685

The "each" function in jQuery returns 2 values: index and element. Try using the element returned instead of $(this).

$('.popup').each(function(index, element) {

    var popupTrigger = element.data("trigger");

    $('.'+popupTrigger).click(function() {
        element.addClass('active');
    });

});

Upvotes: 0

Mohamed-Yousef
Mohamed-Yousef

Reputation: 24001

Simple way to use data attribute also for buttons .. and make only one click event for the buttons .. see the next example

$('.button[data-to-trigger]').on('click' , function(){
    var GetTriggerDiv = $(this).attr('data-to-trigger');
    $('.popup').removeClass('active').filter('.popup[data-trigger="'+GetTriggerDiv+'"]').addClass('active');
});
.active{
  background : red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="button" data-to-trigger="button-one">Test 1</div>
<div class="button" data-to-trigger="button-two">Test 2</div>
<div class="button" data-to-trigger="button-three">Test 3</div>

<div class="popup" data-trigger="button-one">Hello world</div>
<div class="popup" data-trigger="button-two">Hello there</div>
<div class="popup" data-trigger="button-three">Hello again</div>

Upvotes: 2

trincot
trincot

Reputation: 350300

This is because you did not declare popupObj as a local variable; It is global, and so it will have changed in the last iteration of the each: it is that value that will be referenced in all three click handlers.

Remember that each will have performed all iterations before any of the click handlers get called.

Solution: use var popupObj. That way each of the click handlers will reference their "own" variable.

Upvotes: 3

Related Questions