-1

I have a list of elements with the same class month. Some of them might have the class cal as well, and only one element of the list has the class today.

I'd like to search for the first element with the class cal, but only after the element today is found. The tricky part here is that the elements might not be siblings. If they were siblings, this would work:

 $('#eventCal .today').nextAll('#eventCal .cal:first').text();

So for example, if I have the following list, how could I target the first cal after today?

<div id="eventCal">
    <ul>
        <li class="month"></li>
        <li class="month cal">Not show because it's before TODAY</li>
        <li class="month"></li>
    </ul>
    <ul>
        <li class="month"></li>
        <li class="month today">Today</li>
        <li class="month"></li>
    </ul>
    <ul>
        <li class="month cal">To show as it's the first CAL after the TODAY</li>
        <li class="month cal">Not show because is not the first CAL</li>
        <li class="month"></li>
    </ul>
</div>
Mika
  • 305
  • 3
  • 15

4 Answers4

2

To make this work when the li are not all siblings you can get the index of the .today element within all .month elements. Then you can get all .month following that, and retrieve the first .cal using filter(), like this:

var todayIndex = $('.month.today').index();
var $cal = $(`.month:gt(${todayIndex})`).filter('.cal:first').addClass('foo');
.foo { color: #C00; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="eventCal">
    <ul>
        <li class="month"></li>
        <li class="month cal">Not show because it's before TODAY</li>
        <li class="month"></li>
    </ul>
    <ul>
        <li class="month"></li>
        <li class="month today">Today</li>
        <li class="month"></li>
    </ul>
    <ul>
        <li class="month cal">To show as it's the first CAL after the TODAY</li>
        <li class="month cal">Not show because is not the first CAL</li>
        <li class="month"></li>
    </ul>
</div>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
0

An alternate solution is, find it by parent plus nextAll like below:

$('.month').each(function() {
  if ($(this).hasClass('today')) {
    $(this).parent().nextAll().find('.cal:first').addClass('active');
  }
});
.active {
  background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="eventCal">
  <ul>
    <li class="month"></li>
    <li class="month cal">Not show because it's before TODAY</li>
    <li class="month"></li>
  </ul>
  <ul>
    <li class="month"></li>
    <li class="month today">Today</li>
    <li class="month"></li>
  </ul>
  <ul>
    <li class="month cal">To show as it's the first CAL after the TODAY</li>
    <li class="month cal">Not show because is not the first CAL</li>
    <li class="month"></li>
  </ul>
</div>

Or you can easily get it like this:

$('.today').parent().nextAll().find('.cal:first').addClass('active');
.active {
  background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="eventCal">
  <ul>
    <li class="month"></li>
    <li class="month cal">Not show because it's before TODAY</li>
    <li class="month"></li>
  </ul>
  <ul>
    <li class="month"></li>
    <li class="month today">Today</li>
    <li class="month"></li>
  </ul>
  <ul>
    <li class="month cal">To show as it's the first CAL after the TODAY</li>
    <li class="month cal">Not show because is not the first CAL</li>
    <li class="month"></li>
  </ul>
</div>
Pedram
  • 15,766
  • 10
  • 44
  • 73
0
    $(document).ready(function(){
      var foundToday = false;

  $('.month').each(function (idx,item) { 
         if( $(this).hasClass('cal') ){
            foundToday = true;
         }

         if(foundToday){
            if( $(this).hasClass('today') ){
                console.log($(this).text())
            }
         }

  });

});
HarshaHR
  • 73
  • 4
0

I think the next solution is quite simple.

var first_cal = ''
if($('.today').siblings('.cal').length){
    first_cal = $('.today').siblings('.cal').html()
}else{
    first_cal = $('.today').parent().nextAll('ul').find('.cal').html();
}

$('.result').text(first_cal);

What we do is to check if .today has siblings with cal, if not, we search the first cal starting from the next ul.

Notice that you can put as many ul without cal as you want after the ul that contains today, it wont affect the result.

Here an example on fiddle: https://jsfiddle.net/Samuel10F/utna63qx/

Samuel Diez
  • 541
  • 4
  • 5