KillerDesigner
KillerDesigner

Reputation: 515

Toggle class on element, ignore all but one child

Having a hard time solving this even after reading jQuery stopPropagation for only some class of elements, Javascript toggle class on element and countless other references.

I want to toggle class "active" when clicking on nav > ul > li AND .dd-toggle (a child of .dropdown) but NOT .dropdown itself or anything within it (other than .dd-toggle).

<nav class="nav-dropdowns" role="navigation">
    <ul>
        <li class="">
            <span class="dropdown-title">Price</span>
            <div class="dropdown">
                <a class="dd-toggle">X</a>
                <div id="field-price" class="field"><label>Price Range</label>
                    <div class="details"></div>
                </div>
                </div> <button type="submit" class="extra-submit buttonstyle">Search</button>
            </div>
        </li>
        <li class="">
            <span class="dropdown-title">Type</span>
            <div class="dropdown">
                <a class="dd-toggle">X</a>
                <div id="field-type" class="field"><label>Property Type</label>
                    <div class="details"></div>
                </div> <button type="submit">Search</button>
            </div>
        </li>
        <li class="search-submit">
            <button class="search-button" type="submit">Search</button>
        </li>
    </ul>
</nav>

I have tried numerous variations starting with:

jQuery(document).ready(function($){
    $( "nav > ul > li" ).click(function() {
      $( this ).closest().toggleClass( "active" );
    });
});

then

jQuery(document).ready(function($){
    $( "nav > ul > li" ).click(function() {
      $( this ).toggleClass( "active" );
    });
    $('.dropdown').click(function(e) {
      return false;
    });
});

and finally

jQuery(document).ready(function($){
    $( "nav > ul > li" ).click(function( event ) {
        event.stopImmediatePropagation();      
    $( this ).toggleClass( "active" ).not('.dropdown');
    });
});

I get ignoring the children of or closest to, but can't figure out how to do that but still observe a child of the child. Perhaps only first child of?

Ignore .dropdown but NOT .dd-toggle

Am I close?

Upvotes: 0

Views: 682

Answers (1)

Erik Philips
Erik Philips

Reputation: 54676

I would really recommend reading:

Decoupling Your HTML, CSS, and JavaScript. It will really reduce your tightly coupled code.

Everything in Green will change to red, unless you are in blue (in green). Although I'm not sure (because you're question isn't clear) if you're asking for active on either the li and the .dd-toggle (as it is now) or only the li which wouldn't be hard.

If you need active only on the li simply change the .dd-toggle code to:

$(this).parents('li').first().toggleClass('active');

CodePen.IO Working Example

$(document).ready(function() {
  $("nav > ul > li").on("click", function(e) {
    if ($(e.target).parents('.dropdown').length === 0 &&
      !$(e.target).hasClass('dropdown')) {
      $(this).toggleClass("active");
    }
  });
  $(".dd-toggle").on("click", function(e) {
    $(this).toggleClass("active");
  });
});
nav > ul > li, .dd-toggle {
  border: 2px solid green;  
  cursor: pointer;
  user-select: none;
}

.active {
  border: 2px solid red;
}

.dropdown {
  border: 2px solid blue;
  cursor: default;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav class="nav-dropdowns" role="navigation">
  <ul>
    <li class="">
      <span class="dropdown-title">Price</span>
      <div class="dropdown">
        <a class="dd-toggle">X</a>
        <div id="field-price" class="field"><label>Price Range</label>
          <div class="details"></div>
        </div>
      </div> <button type="submit" class="extra-submit buttonstyle">Search</button>
      </div>
    </li>
    <li class="">
      <span class="dropdown-title">Type</span>
      <div class="dropdown">
        <a class="dd-toggle">X</a>
        <div id="field-type" class="field"><label>Property Type</label>
          <div class="details"></div>
        </div> <button type="submit">Search</button>
      </div>
    </li>
    <li class="search-submit">
      <button class="search-button" type="submit">Search</button>
    </li>
  </ul>
</nav>

Upvotes: 1

Related Questions