John Denney
John Denney

Reputation: 23

How do I get the previously clicked list item in an unordered list in same click event Jquery

I have an unordered list like below :

<ul class='learningAreas'>
    <li class="caret"><span><img src="/assets/img/rightarrow.png">&nbsp;&nbsp;</span>Performance Art
        <ul class='subjectRef'>
            <li class="subject ACTIVE" id="PAADLB" data-status="ACTIVE"><a href="#" class="ACTIVE" title="PAADLB">(PAADLB) - Acting & Directing</a></li>
            <li class="subject ACTIVE" id="PAATDY" data-status="ACTIVE"><a href="#" class="ACTIVE" title="PAATDY">(PAATDY) - Acting Design</a></li>
        </ul>
    </li>
    <li class="caret"><span><img src="/assets/img/rightarrow.png">&nbsp;&nbsp;</span>Visual Art
        <ul class='subjectRef'>
            <li class="subject ACTIVE" id="VA2DFAW" data-status="ACTIVE"><a href="#" class="ACTIVE" title="VA2DFAW">(VA2DFAW) - 2D Fine Art</a></li>
            <li class="subject ACTIVE" id="VA2DMY" data-status="ACTIVE"><a href="#" class="ACTIVE" title="VA2DMY">(VA2DMY) - 2D Media</a></li>
        </ul>
    </li>
</ul>

The list items (Learning Areas) with class 'caret' expand/collapse into a sub-list depending on click.

I have a right arrow image in a span before the list item when a user clicks a "Learning Area" the arrow switches to a down arrow.

My problem is that when the user clicks a new "Learning Area" it should set the previous down arrow to a right arrow and the new "Learning Area" right arrow to a down arrow

The CSS works fine and I can click a "Learning Area" and the right arrow switches to a down arrow yet when I click another "Learning Area" the previously clicked arrow does not change.

My CSS is this

.rightArrow {
      -webkit-transform: rotate(0deg);
      -moz-transform: rotate(0deg);
      -o-transform: rotate(0deg);
      -ms-transform: rotate(0deg);
      transform: rotate(0deg);
      display: inline-block;

}

.downArrow {
      -webkit-transform: rotate(90deg);
      -moz-transform: rotate(90deg);
      -o-transform: rotate(90deg);
      -ms-transform: rotate(90deg);
      transform: rotate(90deg);
      display: inline-block;

}

My JQuery looks like this

    $('ul.subjectRef').hide();
  $("li > span").addClass("rightArrow"); 
  
    $('.learningAreas > li').click(function(){
        $('.caret').not(this).find(".subjectRef").hide();
        $(this).find(".subjectRef").toggle();
          $(this).find(".rightArrow").toggleClass("downArrow"); 
        
    });

Where am I going wrong? I have tried .hasClass with .addClass and .removeClass but am just going around in circles. I somehow need to know what was the previously clicked item and change its arrows.

any help would be appreciated Thanks John

Upvotes: 2

Views: 85

Answers (1)

Alexander Nied
Alexander Nied

Reputation: 13623

I made the following adjustments to your script:

$('.learningAreas > li').click(function() {
  // use variables to cache our collections for performance and clarity
  const clickedListElement = $(this);
  const otherListElements = $('.caret').not(this);
  // find the .subjectRef in the other list elements and hide it
  otherListElements.find(".subjectRef").hide();
  // find the .downArrow classed image in the other list elements and toggle the down arrow class
  otherListElements.find(".downArrow").toggleClass("downArrow");
  // toggle on the current list item
  clickedListElement.find(".subjectRef").toggle();
  clickedListElement.find(".rightArrow").toggleClass("downArrow");
});

You can see it in action below:

$('ul.subjectRef').hide();
$("li > span").addClass("rightArrow");

$('.learningAreas > li').click(function() {
  // use variables to cache our collections for performance and clarity
  const clickedListElement = $(this);
  const otherListElements = $('.caret').not(this);
  // find the .subjectRef in the other list elements and hide it
  otherListElements.find(".subjectRef").hide();
  // find the .downArrow classed image in the other list elements and toggle the down arrow class
  otherListElements.find(".downArrow").toggleClass("downArrow");
  // toggle on the current list item
  clickedListElement.find(".subjectRef").toggle();
  clickedListElement.find(".rightArrow").toggleClass("downArrow");
});
.rightArrow {
  -webkit-transform: rotate(0deg);
  -moz-transform: rotate(0deg);
  -o-transform: rotate(0deg);
  -ms-transform: rotate(0deg);
  transform: rotate(0deg);
  display: inline-block;
}

.downArrow {
  -webkit-transform: rotate(90deg);
  -moz-transform: rotate(90deg);
  -o-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  transform: rotate(90deg);
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class='learningAreas'>
  <li class="caret"><span><img src="https://i.imgur.com/APHeUQH.png">&nbsp;&nbsp;</span>Performance Art
    <ul class='subjectRef'>
      <li class="subject ACTIVE" id="PAADLB" data-status="ACTIVE"><a href="#" class="ACTIVE" title="PAADLB">(PAADLB) - Acting & Directing</a></li>
      <li class="subject ACTIVE" id="PAATDY" data-status="ACTIVE"><a href="#" class="ACTIVE" title="PAATDY">(PAATDY) - Acting Design</a></li>
    </ul>
  </li>
  <li class="caret"><span><img src="https://i.imgur.com/APHeUQH.png">&nbsp;&nbsp;</span>Visual Art
    <ul class='subjectRef'>
      <li class="subject ACTIVE" id="VA2DFAW" data-status="ACTIVE"><a href="#" class="ACTIVE" title="VA2DFAW">(VA2DFAW) - 2D Fine Art</a></li>
      <li class="subject ACTIVE" id="VA2DMY" data-status="ACTIVE"><a href="#" class="ACTIVE" title="VA2DMY">(VA2DMY) - 2D Media</a></li>
    </ul>
  </li>
    <li class="caret"><span><img src="https://i.imgur.com/APHeUQH.png">&nbsp;&nbsp;</span>Performance Art
    <ul class='subjectRef'>
      <li class="subject ACTIVE" id="PAADLB" data-status="ACTIVE"><a href="#" class="ACTIVE" title="PAADLB">(PAADLB) - Acting & Directing</a></li>
      <li class="subject ACTIVE" id="PAATDY" data-status="ACTIVE"><a href="#" class="ACTIVE" title="PAATDY">(PAATDY) - Acting Design</a></li>
    </ul>
  </li>
</ul>

This works, but you could probably extract some of this behavior into functions to structure it a bit better, if you think you might have more DOM pieces to shuffle around for each operation. As it is it will do a needless iteration on .otherListElements when the user clicks the currently open item to toggle it.

Upvotes: 1

Related Questions