views:

443

answers:

8

Hey,

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

A: 

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).

Jimmeh
$('.sameClass').each(function() { if (this.attr('class').contains('selected')) { setNextAsSelected = true this.removeClass('selected'); } if(setNextAsSelected) { this.addClass('selected'); setNextAsSelected =false; }});
Ketan Khairnar
thanks, i kinda wrote it in a rush, and have been slowly editting it ;p
Jimmeh
Although, you have the if statements the wrong way round :p
Jimmeh
Why select and work on more elements than is needed?
redsquare
A: 

Try this

var sel = $('.selected');
sel.removeClass('selected');
var ofSameClass = sel.siblings('.'+sel.attr('class'));
ofSameClass.eq(0).addClass('selected');
David Hedlund
A: 

Try with this:

$('.sameClass.selected')
    .removeClass('selected')
    .nextAll('.sameClass:eq(0)')
       .addClass('selected')'
krcko
.prev only ever returns the previous sibling, you need prevAll()
redsquare
you're right, i haven't tested this. i've posted it while having morning coffee, it might be that it haven't awaken me enough :)anyway, i've edited my answer with code that works (and uses nextAll)
krcko
but now it adds selected to all next siblings that have the same class, not just the next one ( .eq(0) )
redsquare
again, you're right :)so in nextAll selector should be '.sameClass:eq(0)'
krcko
A: 
$( '.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;
  }
} );
Jan Hančič
this will add .selected to next all .sameClass divs; which is not what he meant
Ketan Khairnar
it will not. notice the first "return false;" :)
Jan Hančič
A: 

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

redsquare
downvote explanation would be cool, cheers
redsquare
A: 

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;
    }
});
Ketan Khairnar
as suggested in my comments, the if statements are the wrong way round, but otherwise seems fine.
Jimmeh
you need to set flag when current item has .selected before removing. For the next .sameClass item flag==true means add .selected to current.
Ketan Khairnar
yea, but this will basically find the selected item, then remove the selected, then re add it to the same item. You could use and else if, but currently, this won't work.
Jimmeh
:) true..your updated reply is fine now..thanks
Ketan Khairnar
A: 

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.

dlamblin
+3  A: 

Here's an elegant solution:

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