Question

I am trying to use JQuery to select the next element in a set of elements with the same class.

Here is the HTML setup:

<div class="sameClass selected">
  <p>Text in here</p>
</div>
<div class="differentClass">
  <p>Text in here
</div>
<div class="sameClass">
  <p>Text in here</p>
</div>

When I have the first div with the class "sameClass" I would like to remove the "selected" class from the top div and apply it to the next div with the class "sameClass" so the results are like so:

<div class="sameClass">
  <p>Text in here</p>
</div>
<div class="differentClass">
  <p>Text in here
</div>
<div class="sameClass selected">
  <p>Text in here</p>
</div>

I hope you get what I mean :)

UPDATE:

I have found that this one works the best.

$(".sameClass.selected").nextAll(".sameClass:first").andSelf().toggleClass("selected")

I have encountered one bug with it how ever, if the HTML is like so:

<p>
  <div class="sameClass">
    <p>Text in here</p>
  </div>
  <div class="differentClass">
    <p>Text in here
  </div>
  <div class="sameClass  selected">
    <p>Text in here</p>
  </div>
</p>
<p>
  <div class="sameClass">
    <p>Text in here</p>
  </div>
</p>

It will not select the "sameClass" which is in the second P block. Any idea why this is happening?

Eef

Was it helpful?

Solution

Here's an elegant solution:

$(".sameClass.selected")
 .nextAll(".sameClass:first").andSelf()
 .toggleClass("selected")

OTHER TIPS

Try this

var sel = $('.selected');
sel.removeClass('selected');
var ofSameClass = sel.siblings('.'+sel.attr('class'));
ofSameClass.eq(0).addClass('selected');
$( '.sameClass' ).each ( function () {
  var jThis = $( this );
  if ( jThis.hasClass ( 'selected' ) ) {
    jThis.removeClass ( 'selected' );
    jThis.nextAll ( '.sameClass' ).each ( function () {
      $( this ).addClass ( 'selected' );
      return false;
    } );

    return false;
  }
} );

You could use:

$('.sameClass').each(function() {
  if(setNextAsSelected) {
      this.addClass('selected');
      return;
  }
  if (this.attr('class').contains('selected')) { 
      setNextAsSelected = true;
      this.removeClass('selected'); 
  }
});

or something (Mostly pseudocoded).

Modification to Jimmeh's reply

var setNextAsSelected = false;
$('.sameClass').each(function() {
    if (this.hasClass('selected')) 
    { 
      setNextAsSelected = true 
      this.removeClass('selected');
    }
    if(setNextAsSelected)
    {
       this.addClass('selected');
       setNextAsSelected =false;
    }
});

You dont make it clear if your always going forward to find the 'next' div. So either use .nextAll or .siblings.eq(0) depends if you going both left and right.

var $el = $('div.selected');
$el.removeClass('selected');
   .nextAll('.' + $el.attr('class') ).eq(0)
   .addClass('selected');

Also do not forget to use tagname prefix in the selector rather than a pure class based selector $('div.class') 99% of the time better than $('.class')

P.S instead of nextAll you could use ben almans nextUntil plugin available @ http://github.com/cowboy/jquery-misc

I tried this and I think it does what you want:

var s='selected';
var c='.sameClass';
$($(c+'.'+s).removeClass(s).nextAll(c)[0]).addClass(s)
// s and c added for brevity, probably use this expanded in source code.

It does not work if the last .sameClass element was selected, but then, neither do the other answers so far.

Try with this:

$('.sameClass.selected')
    .removeClass('selected')
    .nextAll('.sameClass:eq(0)')
       .addClass('selected')'
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top