Adyyda
Adyyda

Reputation: 335

How can I add a class to an element if an anchor inside a list item is active?

I have this structure:

<div id="prev-button">
  Previous
</div>
<ul class="thumbnails">
  <li class="" data-skus="">
    <a class="thumbnail active">
      <img src=""></a>
  </li>
  <li class="" data-skus="">
    <a class="thumbnail">
      <img src=""></a>
  </li>
  <li class="" data-skus="">
    <a class="thumbnail">
      <img src=""></a>
  </li>
</ul>
<div id="next-button">
  Next
</div>

I need to add new-class to id="prev-button" when the first <li> has active class on its <a> child.

When first anchor doesn't have active class, remove the new-class from id="prev-button"

Also, when last list item has active class added to its child anchor, same new-class has to be added to id="next-button".

I tried to add new-class to the parent list item when the anchor has active class and is not working.

if ($('.thumbnail').is(".active")) {
    $(this).parent().addClass("active");
}

Upvotes: 0

Views: 62

Answers (2)

trincot
trincot

Reputation: 350272

You can use .index to know the sequential order of the selected element. So depending on which one is active, the following expression:

$(".thumbnail.active").parent().index()

will evaluate to 0, 1 or 2.

Then with toggleClass() you can choose to set the "new-class" on the first button when, and only if, that index is 0, and something similar can be done for the other button.

Here is a demo:

// The argument to this function determines how the current selection should move:
// 0: don't move it; just apply the necessary CSS
// 1: move it down
// -1: move it up
function select(dir) {
    let last = $(".thumbnail").length - 1;
    let curr = $(".thumbnail.active").parent().index() + dir;
    if (curr >= 0 && curr <= last) {
        $(".thumbnail").removeClass("active").eq(curr).addClass("active");
        $("#prev-button").toggleClass("disabled", curr == 0);
        $("#next-button").toggleClass("disabled", curr == last);
    }
}

$("#prev-button").click(select.bind(0, -1));
$("#next-button").click(select.bind(0, 1));
select(0); // initialise also on page load
#prev-button, #next-button {
  padding: 5px;
  text-align: center;
  background: lightblue;
  display: inline-block;
  user-select: none;
  cursor: pointer;
}

.active { background: yellow }
#prev-button.disabled, #next-button.disabled { background: silver }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="prev-button">
  Previous
</div>
<ul class="thumbnails">
  <li class="" data-skus="">
    <a class="thumbnail active">
      <img src="">first</a>
  </li>
  <li class="" data-skus="">
    <a class="thumbnail">
      <img src="">second</a>
  </li>
  <li class="" data-skus="">
    <a class="thumbnail">
      <img src="">third</a>
  </li>
</ul>
<div id="next-button">
  Next
</div>

Without parent().index():

The above is quite sensitive to the document structure. Alternatively, you can use index with an argument, which works much like indexOf on arrays:

// The argument to this function determines how the current selection should move:
// 0: don't move it; just apply the necessary CSS
// 1: move it down
// -1: move it up
function select(dir) {
    let $links = $(".thumbnail");
    let $active = $links.filter(".active");
    let curr = $links.index($active) + dir;
    let last = $links.length - 1;
    if (curr >= 0 && curr <= last) {
        $(".thumbnail").removeClass("active").eq(curr).addClass("active");
        $("#prev-button").toggleClass("disabled", curr == 0);
        $("#next-button").toggleClass("disabled", curr == last);
    }
}

$("#prev-button").click(select.bind(0, -1));
$("#next-button").click(select.bind(0, 1));
select(0); // initialise also on page load
#prev-button, #next-button {
  padding: 5px;
  text-align: center;
  background: lightblue;
  display: inline-block;
  user-select: none;
  cursor: pointer;
}

.active { background: yellow }
#prev-button.disabled, #next-button.disabled { background: silver }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="prev-button">
  Previous
</div>
<ul class="thumbnails">
  <li class="" data-skus="">
    <a class="thumbnail active">
      <img src="">first</a>
  </li>
  <li class="" data-skus="">
    <a class="thumbnail">
      <img src="">second</a>
  </li>
  <li class="" data-skus="">
    <a class="thumbnail">
      <img src="">third</a>
  </li>
</ul>
<div id="next-button">
  Next
</div>

Upvotes: 2

Peter Pointer
Peter Pointer

Reputation: 4162

Why are you trying to access the id="prev-button" with $(this).parent().addClass("active");? The parent would be the li element. Why not use $("#prev-button") to access the prev-button?

You can create a playground at Codepen.io to experiment, for example. I have created one this which is the first fix for what you asked: https://codepen.io/peter-krebs/pen/xxdxoPZ

https://api.jquery.com/ has tons of resources for you to read with example code. Don't be afraid to educate yourself, don't just guess how it works.

Upvotes: 0

Related Questions