amazedinc
amazedinc

Reputation: 418

Better way to use jquery each

I have a parent div containing 5 children (.item). Each child div is a progress point that can have three options: .past - .current - .future. The divs are in order (left to right) so if the middle div (3) has the class .current, the previous 2 should be past, and the 2 following that div should be future.

In my example I've used jQuery each to add the proper classes and it works. However, I am curious if there is a better, more concise, way to achieve this? (I'm sure there is!)

Fiddle: https://jsfiddle.net/remix1201/uxgv62z9/

HTML:

<div class="series-set-options">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
</div>

JS:

var flowStep = 3;

$(".series-set-options").children().each(function(i){
    if (flowStep > i){
        $(".series-set-options").children().eq(i).addClass("past");
    }
    if ( flowStep == i){
        $(".series-set-options").children().eq(i).addClass("current");
    }
    if (flowStep < i){
        $(".series-set-options").children().eq(i).addClass("future");
    }
});

Upvotes: 3

Views: 134

Answers (3)

Nenad Vracar
Nenad Vracar

Reputation: 122067

You could use :eq() and then prevAll() and nextAll() DEMO

$(".item:eq(2)").addClass('current').prevAll('.item').addClass('past');
$(".item:eq(2)").nextAll('.item').addClass('future');

Or as @Tushar suggested single-line DEMO

$(".item")
    .eq(flowStep)                         // flowStep = 2
    .addClass('current')                  // eq(2)
    .prevAll('.item').addClass('past')    // prevAll of eq(2)
    .end()                                // eq(2) end = go back to prev context
    .nextAll('.item').addClass('future'); // nextAll of eq(2)

Upvotes: 2

Tushar
Tushar

Reputation: 87203

A simple thing to improve your code

  1. Use $(this) inside each to refer to the current element
  2. Use else if

Code:

var flowStep = 3;

$(".series-set-options").children().each(function (i) {
    if (flowStep > i) {
        $(this).addClass("past");
    } else if (flowStep == i) {
        $(this).addClass("current");
    } else if (flowStep < i) {
        $(this).addClass("future");
    }
});

No need of using each(), You can use :lt & :gt selectors.

$('.series-set-options .item:lt(' + flowStep + ')').addClass('past');
$('.series-set-options .item').eq(flowStep).addClass('current');
$('.series-set-options .item:gt(' + flowStep + ')').addClass('future');

Updated Fiddle

var flowStep = 3;

$('.series-set-options .item:lt(' + flowStep + ')').addClass('past');
$('.series-set-options .item').eq(flowStep).addClass('current');
$('.series-set-options .item:gt(' + flowStep + ')').addClass('future');
div {
  width: 100px;
  height: 100px;
}
.past {
  background: gray;
}
.current {
  background: white;
}
.future {
  background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="series-set-options">
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
  <div class="item"></div>
</div>

Upvotes: 2

jkojoa
jkojoa

Reputation: 62

You could have a look at the .each jQuery docs and see other parameter objects. In this case el would be your child item.

var flowStep = 3;
flowStep = flowStep - 1;

$(".series-set-options .item").each(function(i,el) {
  if (flowStep > i) {
    $(el).addClass("past");
  }
  if (flowStep == i) {
    $(el).addClass("current");
  }
  if (flowStep < i) {
   $(el).addClass("future");
  }
});

Upvotes: 0

Related Questions