views:

149

answers:

1

Hi there,

This is a two-part question. I'm using jQuery for a project and wanting to click a link and toggle the class name "highlight" to that link and also to the div with the same id as the rel attribute of the link. I then want to be able to link to the next div without the classname of "highlight". Here's the HTML for it:

<ul>
   <li><a href="#" rel="panel1">Item 1</a></li>
   <li><a href="#" rel="panel2">Item 2</a></li>
   <li><a href="#" rel="panel3">Item 3</a></li>
</ul>  

<a href="">go to next div without class of highlight</a>


<div id="panel1">some text</div>
<div id="panel2">some text</div>
<div id="panel3">some text</div>

Can anyone help with jQuery side of things?

Many thanks in advance!

A: 

Assuming HTML like this:

<ul>
  <li><a href="#" rel="panel1">Item 1</a></li>
  <li><a href="#" rel="panel2">Item 2</a></li>
  <li><a href="#" rel="panel3">Item 3</a></li>
</ul>

<a id="next-unhighlighted">Go to next div without class "highlight"</a>

<div class="panel" id="panel1">Panel 1</div> <!-- Note the added -->
<div class="panel" id="panel2">Panel 2</div> <!-- "panel" classes -->
<div class="panel" id="panel3">Panel 3</div>

You can use JS like this:

$('ul li a').click(function(){
  var $this = $(this), // <a>
      id    = $this.attr('rel'),
      nextUnhighlighted = $('#next-unhighlighted'), // <a>
      targetDiv = $('#' + id),
      nextDiv;

  // Un/highlight the clicked link
  $this.toggleClass('highlight');

  // Un/highlight the div related to the target link
  targetDiv.toggleClass('highlight');

  // Update nextUnhighlighted to point to next unhighlighted div
  nextDiv = $('div.panel:not(.highlight)');
  if(!!nextDiv[0]){ // A next sibling was found
    nextUnhighlighted.attr('href', '#' + nextDiv.attr('id'));
  }else{
    nextUnhighlighted.removeAttr('href');
  }
});

​ Note that, if the final panel is already highlighted, then this code does not update the href attribute for a#next-unhighlighted, but removes it. It's a trivial exercise to add wrap-around behavior, such that highlighting the final panel would link back to the first panel.

A note about the odd syntax !!nextDiv[0]: If the first element in the jQuery collection nextDiv exists, then there is at least one element in the collection. This behaves similarly to (but not exactly the same as) nextDiv.length > 0, but is marginally faster, and saves bytes.


As discussed in the comments, to link each panel to the next unhighlighted one, add <a rel="next-panel">Next panel</a> to each panel's HTML, then add something like this to the main click handler:

$('div.panel a[rel="next-panel"]').each(function(){
  var $this = $(this),
      nextPanel = $this.parent().next('div.panel:not(.highlight)');
  if(!!nextPanel[0]){
    $this.attr('href', '#' + nextPanel.attr('id'));
  }
});

Depending on your project requirements, you'll need to initialize each of these next-panel links (or else they'll only initialize after the first click), and you may want to make the final panel's ;oml wrap around to the first.

Ron DeVera
Thanks a lot for that - it works up to a point although if I click item 2, the link goes to #panel3 when it should go to #panel1 (which is the next div without .highlight). I also want to be able to "highlight" multiple links, so that clicking on Item 1 and Item 2 will link to #panel3.
Chris
I also need to be able to toggle the classes so clicking Item 1 will add .highlight and clicking it again would remove it.
Chris
Updated; I had understood "next div without .highlight" to mean the next div after the currently highlighted one. The latest code now links to the *first* unhighlighted div.
Ron DeVera
You're bloody awesome - I'll give that a go :)
Chris
A thousand thanks Ron - that works like a charm! Just to complicate matters a bit further, do you know how I would go about adding links to the text in each of the panels that would link to the next div in the sequence without the class of highlight?
Chris
I've updated my answer to cover linking from one panel to the next. It's not perfect, but you should be able to massage it to fit your project's evolving requirements.
Ron DeVera
Hey Ron, I've given this a go but still doesn't seem to be working. Any ideas why this might be?
Chris