user3655574
user3655574

Reputation: 723

jQuery addClass is not working inside for loop

I have a jQuery addClass function in a loop that I can seem to get to work for some strange reason, it supposed to paint my Font Awesome star golden. The loop works with no issues, I tested it to confirm with console.log to check that it is looping through all the necessary integers. Also, the addClass function works fine when it is by itself, I tested it by hard coding the eq selector. But when I combine both, it stops working. I can't simplify this function further to narrow down the problem and I don't see any issues logged on the console for this problem.

$(".star").on('click', function(){

  var starvalue = parseInt($(this).data('value'), 10)
  var totalstars = $(".stars").children().length

    $(".golden").css("color","gold")

    // $(".star:eq(1)").addClass('golden');
      
    for (i = 0; i < starvalue; i++) {
      console.log(i)
      $(".star:eq(i)").addClass('golden');
    }

})
<!doctype html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>Star rating Demo</title>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
      <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.9/css/all.css" integrity="sha384-5SOiIsAziJl6AWe0HWRKTXlfcSHKmYV4RBF18PPJ173Kzn7jzMyFuTtk8JA7QQG1" crossorigin="anonymous">
  </head>

  <body>

    <h1>Star rating test</h1>

    <div class="stars">
      <i class="star fa fa-star fa-fw" title='Poor' data-value='1'></i>
      <i class="star fa fa-star fa-fw" title='Fair' data-value='2'></i>
      <i class="star fa fa-star fa-fw" title='Good' data-value='3'></i>
      <i class="star fa fa-star fa-fw" title='Excellent' data-value='4'></i>
      <i class="star fa fa-star fa-fw" title='WOW!!!' data-value='5'></i>
    </div>

  </body>
 
</html>

Upvotes: 1

Views: 1128

Answers (4)

Nir Tzezana
Nir Tzezana

Reputation: 2342

Try this (I used template literals which makes everything much more readable, take note that this only works on ES6 supported browsers):

for (i = 0; i < starvalue; i++) {
      console.log(i)
      $(`.star:eq(${i})`).addClass('golden');
      // Note that I have used backticks - ``
}

Upvotes: 1

Mamun
Mamun

Reputation: 68933

Inside the selector i is not evaluating dynamically:

Change

$(".star:eq(i)").addClass('golden');

To

$('.star:eq('+i+')').addClass('golden');

$('.star').on('click', function(){

  var starvalue = parseInt($(this).data('value'), 10)
  var totalstars = $('.stars').children().length;
  
    //$('.golden').css("color",'gold')

    // $(".star:eq(1)").addClass('golden');

    for (let i = 0; i < starvalue; i++) {
      $('.star:eq('+i+')').addClass('golden');
    }

})
.golden {color: gold}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Star rating Demo</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
        <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.9/css/all.css" integrity="sha384-5SOiIsAziJl6AWe0HWRKTXlfcSHKmYV4RBF18PPJ173Kzn7jzMyFuTtk8JA7QQG1" crossorigin="anonymous">

</head>

  <body>

    <h1>Star rating test</h1>
    <div class="stars">
      <i class="star fa fa-star fa-fw" title='Poor' data-value='1'></i>
      <i class="star fa fa-star fa-fw" title='Fair' data-value='2'></i>
      <i class="star fa fa-star fa-fw" title='Good' data-value='3'></i>
      <i class="star fa fa-star fa-fw" title='Excellent' data-value='4'></i>
      <i class="star fa fa-star fa-fw" title='WOW!!!' data-value='5'></i>
    </div>

  </body>

</html>

OR: You can use Template literals (Template strings) that allows embedded expressions.

$(`.star:eq(${i})`).addClass('golden');

$('.star').on('click', function(){

  var starvalue = parseInt($(this).data('value'), 10)
  var totalstars = $('.stars').children().length;
  
    //$('.golden').css("color",'gold')

    // $('.star:eq(1)').addClass('golden');

    for (let i = 0; i < starvalue; i++) {
      $(`.star:eq(${i})`).addClass('golden');
    }

})
.golden {color: gold}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Star rating Demo</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
        <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.9/css/all.css" integrity="sha384-5SOiIsAziJl6AWe0HWRKTXlfcSHKmYV4RBF18PPJ173Kzn7jzMyFuTtk8JA7QQG1" crossorigin="anonymous">

</head>

  <body>

    <h1>Star rating test</h1>
    <div class="stars">
      <i class="star fa fa-star fa-fw" title='Poor' data-value='1'></i>
      <i class="star fa fa-star fa-fw" title='Fair' data-value='2'></i>
      <i class="star fa fa-star fa-fw" title='Good' data-value='3'></i>
      <i class="star fa fa-star fa-fw" title='Excellent' data-value='4'></i>
      <i class="star fa fa-star fa-fw" title='WOW!!!' data-value='5'></i>
    </div>

  </body>

</html>

Please Note: Instead of setting the color inside the click event use CSS. Also mixing double quotes and single quotes unnecessarily in the code is not a good practice.

Upvotes: 3

Vishvadeep singh
Vishvadeep singh

Reputation: 1663

use below code to add class here is fiddle link:

  $(".star").on('click', function(){

  var starvalue = parseInt($(this).data('value'), 10)

  var totalstars = $(".stars").children().length

   // $(".golden").css("color","gold")
    $(".star").removeClass('golden')
    // $(".star:eq(1)").addClass('golden');

    for (i = 0; i < starvalue; i++) {
      console.log(i)
      $(".star:eq("+i+")").addClass('golden');
    }

})

css Code here:

.golden{
  color:#DAA520;
}

it will also remove the class when you will click other star and make it same as you required.

Upvotes: 1

Sam Thornton
Sam Thornton

Reputation: 983

The problem isn't the loop (which is working well), but that i is just being read as a string, and not a variable. A couple of options for using the variable:

$('.star:eq("' + i + '")').addClass('golden');

or you could use .eq

$('.star').eq(i).addClass('golden');

Full working example:

$(".star").on('click', function () {
  var starvalue = parseInt($(this).data('value'), 10)
  var totalstars = $(".stars").children().length;
  for (var i = 0; i < starvalue; i++) {
    $(".star").eq(i).addClass('golden');
  }
});
.golden { 
  color: yellow; 
}
<!doctype html>
<html>
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.0.9/css/all.css" integrity="sha384-5SOiIsAziJl6AWe0HWRKTXlfcSHKmYV4RBF18PPJ173Kzn7jzMyFuTtk8JA7QQG1" crossorigin="anonymous">
</head>
<body>
  <h1>Star rating test</h1>
  <div class="stars">
    <i class="star fa fa-star fa-fw" title='Poor' data-value='1'></i>
    <i class="star fa fa-star fa-fw" title='Fair' data-value='2'></i>
    <i class="star fa fa-star fa-fw" title='Good' data-value='3'></i>
    <i class="star fa fa-star fa-fw" title='Excellent' data-value='4'></i>
    <i class="star fa fa-star fa-fw" title='WOW!!!' data-value='5'></i>
  </div>
</body>
</html>

Upvotes: 1

Related Questions