0

I've three dropdowns.. When i click on the div with the data-column="1" ( Momentum Jeans Shorts ), I want the current dropdown to remove the "active" & "disable" class for the data-column="1" (Momentum Shorts) and also add the "disable" & "active" class on the selected div which is the data-column="1" ( Momentum Jeans Shorts )..

On my second dropdown, I would want the data-column="1" (Momentum Shorts) to not have the "disable" & "active" class. data-column="2" ( Momentum Jeans Shorts ) would have the "disable" class.

I've tried to work on this many hours but I cant seems to get the algorithm right.. I've attached a screenshot of the dropdowns, and hopefully you get what I'm trying to achieve

<nav>
    <ul class="cf">
      <li>
        <div>
            <a class="dropdown" href="#">CHANGE SHORT</a>
            <ul>
            
            <li>
                <div class="compare-filter-item  active disable" data-column="1" data-product="momentum-shorts">Momentum Shorts</div>
            </li>
            
            <li>
                <div class="compare-filter-item disable" data-column="1" data-product="momentum-shorts-2-0">Momentum Shorts 2.0</div>
            </li>
            
            <li>
                <div class="compare-filter-item disable" data-column="1" data-product="ease-linen-shorts">Ease Linen Shorts</div>
            </li>
            
            <li>
                <div class="compare-filter-item " data-column="1" data-product="momentum-jeans-shorts">Momentum Jeans Shorts</div>
            </li>
            
            </ul>
        </div>
      </li>
      <li>
        <div>
            <a class="dropdown" href="#">CHANGE SHORT</a>
            <ul>
                
                <li>
                <div class="compare-filter-item disable" data-column="2" data-product="momentum-shorts">Momentum Shorts</div>
                </li>
                
                <li>
                <div class="compare-filter-item  active disable" data-column="2" data-product="momentum-shorts-2-0">Momentum Shorts 2.0</div>
                </li>
                
                <li>
                <div class="compare-filter-item disable" data-column="2" data-product="ease-linen-shorts">Ease Linen Shorts</div>
                </li>
                
                <li>
                <div class="compare-filter-item " data-column="2" data-product="momentum-jeans-shorts">Momentum Jeans Shorts</div>
                </li>
                
            </ul>
        </div>
      </li>
      <li>
        <div>
            <a class="dropdown" href="#">CHANGE SHORT</a>
            <ul>
                
                <li>
                <div class="compare-filter-item disable" data-column="3" data-product="momentum-shorts">Momentum Shorts</div>
                </li>
                
                <li>
                <div class="compare-filter-item disable" data-column="3" data-product="momentum-shorts-2-0">Momentum Shorts 2.0</div>
                </li>
                
                <li>
                <div class="compare-filter-item  active disable" data-column="3" data-product="ease-linen-shorts">Ease Linen Shorts</div>
                </li>
                
                <li>
                <div class="compare-filter-item " data-column="3" data-product="momentum-jeans-shorts">Momentum Jeans Shorts</div>
                </li>
                
            </ul>
         </div>
        </li>
    </ul>
  </nav>


$(function() {
            $(".compare-filter-item").on("click",function() {
                const column_value = $(this).attr("data-column");
                const selected_data_product = $(this).attr("data-product");

                $('.compare-filter-item[data-product="' + selected_data_product + '"][data-column="' + column_value + '"]').parent().parent().find(".active.disable").removeClass("active disable");


                $("[data-product='" + selected_data_product + "']").addClass("disable");
                $(this).addClass("active");

                const myarray = $(`.compare-all .compare-products [data-product="${selected_data_product}"]`).map(function() {
                return $(this).html();
                });

                $(`.compare-main .compare-products [data-column="${column_value}"]`)
                .each(function(i) { $(this).html(myarray[i]) });
            });
        });

enter image description here enter image description here

9
  • 1
    Write the html as text please. Commented Mar 21, 2022 at 18:27
  • @Erenn sure! i've updated it! Commented Mar 21, 2022 at 18:45
  • 1
    Don't you think having both .disable and .active classes on an element a bit confusing? At this point I'm not confident about how I understand your question or how you expect it to work. Commented Mar 22, 2022 at 1:35
  • 1
    It's just confusing, I think you want mutually exclusive selection, like a group of radio buttons. Commented Mar 22, 2022 at 1:43
  • 1
    So basically these dropdowns give you 3 unique choices. Commented Mar 22, 2022 at 1:48

1 Answer 1

1

The behavior described in OP is called mutually exclusivity. Basically only one of a group can be selected, like radio buttons that share the same [name].

HTML

First, assign a common class to all items:

<li><a href='#' class='link'></a></li>

Next, a "group" class for each set of 3 items that share the same position:

<!-- For example, each 2nd item of each dropdown -->
<li><a href='#' class='link x1'></a></li> // 1st dropdown
<li><a href='#' class='link x1'></a></li> // 2nd dropdown
<li><a href='#' class='link x1'></a></li> // 3rd dropdown

Then add a data-* attribute to each item, call it data-group and assign the same value as the new class:

<li><a href='#' class='link x1' data-group='x1'></a></li> 

CSS

Two classes are needed:

.active {
  color: blue;
  background: goldenrod
}

.disabled {
  pointer-events: none;
  color: white;
  background: grey;
}

jQuery

First, register all .link to the "click" event. When a .link is clicked...

$('.link').on('click', function() {
  // Get the clicked .link's [data-group]
  const group = $(this).data('group');
  ...

Finally, make each .link able to .toggle() .active class on/off. If the clicked .link is .active then add .disabled to the other 2 items that share the same group, otherwise remove .disabled from the other 2 items:

...
  $(this).toggleClass('active');
  if ($(this).is('.active')) {
    $('.' + group).not(this).addClass('disabled');
  } else {
    $('.' + group).removeClass('disabled');
  }

$('.trigger').on('click', function() {
  $(this).next().slideToggle();
});

$('.link').on('click', function() {
$(this).closest('ul').find('.link').removeClass('active');
  $(this).addClass('active');
  $('.link').removeClass('disabled');
  $('ul').each(function() {
    activate(this);
  });
});

function activate(selector) {
  const act = $(selector).find('.active');
  if (act) {
    const group = $(act).data('group');
    $('.' + group).not(act).addClass('disabled');
  } 
  if (!act) {
    $('.' + group).removeClass('disabled');
  }
}
html {
  font: 2ch/1.15 'Segoe UI';
}

body {
  overflow-y: scroll;
}

nav {
  display: flex;
  justify-content: center;
  align-items: flex-start;
}

menu {
  width: 30%;
  margin-left: -40px;
}

ul {
  display: none;
  list-style: none;
  margin-left: -40px;
}

a {
  color: black;
  text-decoration: none;
}

a,
li {
  display: block;
  text-align: center;
}

.active {
  color: blue;
  background: goldenrod
}

.disabled {
  pointer-events: none;
  color: white;
  background: grey;
}
<nav>
  <menu>
    <a href='#' class='trigger'>Xn</a>
    <ul>
      <li><a href='#' class='link x0' data-group='x0'>X0</a></li>
      <li><a href='#' class='link x1' data-group='x1'>X1</a></li>
      <li><a href='#' class='link x2' data-group='x2'>X2</a></li>
      <li><a href='#' class='link x3' data-group='x3'>X3</a></li>
      <li><a href='#' class='link x4' data-group='x4'>X4</a></li>
    </ul>
  </menu>
  <menu>
    <a href='#' class='trigger'>Xn</a>
    <ul>
      <li><a href='#' class='link x0' data-group='x0'>X0</a></li>
      <li><a href='#' class='link x1' data-group='x1'>X1</a></li>
      <li><a href='#' class='link x2' data-group='x2'>X2</a></li>
      <li><a href='#' class='link x3' data-group='x3'>X3</a></li>
      <li><a href='#' class='link x4' data-group='x4'>X4</a></li>
    </ul>
  </menu>
  <menu>
    <a href='#' class='trigger'>Xn</a>
    <ul>
      <li><a href='#' class='link x0' data-group='x0'>X0</a></li>
      <li><a href='#' class='link x1' data-group='x1'>X1</a></li>
      <li><a href='#' class='link x2' data-group='x2'>X2</a></li>
      <li><a href='#' class='link x3' data-group='x3'>X3</a></li>
      <li><a href='#' class='link x4' data-group='x4'>X4</a></li>
    </ul>
  </menu>
</nav>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Sign up to request clarification or add additional context in comments.

4 Comments

Your solution is really close on this one! However, the dropdown now allows multiple selections if they are not selected before. how if i want to just allow users to select one option instead of multiple in a single dropdown?
Do you mean 1 active per dropdown?
correct ! @zer00ne
Ok see update, it does as we discussed, I'll explain it later.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.