user3438917 user3438917 - 6 months ago 8
Javascript Question

Targeting data-state to toggle nav headers

UPDATE

enter image description here

I discovered I could toggle the data state on click with

$(".list-header").attr("data-state", $(".list-header").hasClass('list-header') ? "hide" : "show");


However, when I click the same header I just opened, it doesn't revert back to its original icon or "hide" state.

How can I toggle the current header back to the data-state="hide" state?

$('.list-header.major').click(function(){
$(".list-header").attr("data-state", $(".list-header").hasClass('list-header') ? "hide" : "show");
$('.list-header.major').next('div').slideUp();
$(this).next('div').toggle();
$('.list-header.major').removeClass('active');
$(this).toggleClass('active');
return false;
});


===========================================================================

I need to be able to toggle the "HEADER"'s so that when the subnav is closed for any of them, the header icon is always set to a
+
sign, and has a
data-state=hide


I found that the state of the headers is always set to active, and that the only way to toggle the
+
or
-
sign is to toggle the
data-state
from
show
to
hide
, which would be based on the state of the
.col-wrapper
classes
style
being either
display:none
or
display: block
.

The question is how to look for the display state of the
.col-wrapper
class and change the
data-state
based on whether the
.list-header
has been clicked or not. I've included screen shots of the states from the fiddle(https://jsfiddle.net/2bu35uLn/3/show/) below.

Essentially, the issue is that the icons aren't toggling back to the plus sign, if the user clicks on another header. This should force any closed list header to go back to the plus sign.

This is the closed state
enter image description here

This is the open state
Notice that the
.col-wrapper
class has
display:block
to show the subnav, but the
.list-header
class is still set to
data-state="hide"
, which keeps the header from being toggled back to the correct state.
enter image description here

I'm trying to target the
data-state
to change to
hide
if the
.col-wrapper
class is
display:none
, by doing something like this:

$(".list-header").on('click', function(){
if($(this).find(".col-wrapper").css("display", "none")){
force data-state to be hide
}
});


HTML

<div class="inner">
<button data-target="#data-nav-0" data-toggle="collapse" data-state="show" class="list-header major no-style"> <span>HEADER</span> </button>
<div class="col-wrapper collapse in" id="data-nav-0" style="display: block;">
<div class="column">
<ul class="list-unstyled">

<li class="list-header mobile"><a href="#" class="link">link</a></li>
<li class="list-header desktop"><a href="#">head</a></li>
<li class="mobile chevron-right" data-target="#data-inner-0-0" data-toggle="collapse" data-state="hide">
<button class="no-style sub-header">This should toggle the ul links</button>
</li>

<ul class="inner collapse" id="data-inner-0-0">
<li><a href="#" class="link">link</a></li>
<li><a href="#" class="link">link</a></li>
<li><a href="#" class="link">link</a></li>
<li><a href="#" class="link">link</a></li>
</ul>
</ul>
</div>
<div class="column">
<ul class="list-unstyled">
<li class="list-header desktop"><a href="#">Link</a></li>
<li class="mobile chevron-right" data-target="#data-inner-0-1" data-toggle="collapse" data-state="hide">
<button class="no-style sub-header">This should toggle the ul links</button>
</li>

<ul class="inner collapse" id="data-inner-0-0">
<li><a href="#" class="link">link</a></li>
<li><a href="#" class="link">link</a></li>
<li><a href="#" class="link">link</a></li>
<li><a href="#" class="link">link</a></li>
</ul>
</ul>
</ul>
</div>
</div>
</div>

<div class="inner">
<button data-target="#data-nav-0" data-toggle="collapse" data-state="show" class="list-header major no-style"> <span>HEADER</span> </button>
<div class="col-wrapper collapse in" id="data-nav-0" style="display: block;">
<div class="column">
<ul class="list-unstyled">

<li class="list-header mobile"><a href="#" class="link">link</a></li>
<li class="list-header desktop"><a href="#">head</a></li>
<li class="mobile chevron-right" data-target="#data-inner-0-0" data-toggle="collapse" data-state="hide">
<button class="no-style sub-header">This should toggle the ul links</button>
</li>

<ul class="inner collapse" id="data-inner-0-0">
<li><a href="#" class="link">link</a></li>
<li><a href="#" class="link">link</a></li>
<li><a href="#" class="link">link</a></li>
<li><a href="#" class="link">link</a></li>
</ul>
</ul>
</div>
<div class="column">
<ul class="list-unstyled">
<li class="list-header desktop"><a href="#">Link</a></li>
<li class="mobile chevron-right" data-target="#data-inner-0-1" data-toggle="collapse" data-state="hide">
<button class="no-style sub-header">This should toggle the ul links</button>
</li>

<ul class="inner collapse" id="data-inner-0-0">
<li><a href="#" class="link">link</a></li>
<li><a href="#" class="link">link</a></li>
<li><a href="#" class="link">link</a></li>
<li><a href="#" class="link">link</a></li>
</ul>
</ul>
</ul>
</div>
</div>
</div>


jQuery

$('.list-header.major').next('div').toggle();
$('.list-header.major').click(function(){
$('.list-header.major').next('div').slideUp();
$(this).next('div').toggle();
$('.list-header').removeClass('active');
$(this).toggleClass('active');
return false;
});

$('.mobile').next('ul').toggle();
$('.mobile').click(function() {
$('.mobile').next('ul').slideUp();
$(this).next('ul').toggle();
$('.mobile button').removeClass('active');
if ($(this).next('ul').is(':visible')) {
$(this).find('button').addClass('active');
}
return false;
});


CSS

button.list-header.major {
&:before,
&:after {
color: $purple;
font-family: 'Material Icons';
font-size: 20px;
position: absolute;
right: 20px;
}

&:before {
content: "\E145"; <--THIS IS A PLUS SIGN
}

&:after {
content: "\E15B"; <--THIS IS A MINUS SIGN
}
}
.sub-header:after{
content: " >";
font-family: 'Material Icons';
display: inline-block;
transform: rotate(0);
font-size: 26px;
color: $white;
position: relative;
top: 8px;
transition: transform .3s;
}
.sub-header.active:after{
content: " v";
color: red;
display: inline-block;
transform: rotate(8deg);
font-size: 26px;
color: $neon-green;
transition: transform .3s;
}


UPDATE WITH SCREENSHOT AND MORE DETAIL

The top navigation should have a
+
icon, not
-
. Here you can see the second Header is opened and has the correct
-
, while the Header above it still has the
-
, although the contents
col-wrapper
has collapsed below it:

First header should have + instead of -

Answer

Changed code together with the author of question. Should work as expected.

$('.list-header.major').click(function(){
if (current !== this)
    $(current).attr('data-state', 'hide');
$(this).attr("data-state", $(this).attr('data-state') === 'hide' ? "hide" : "show");
current = this;
$('.list-header.major').next('div').slideUp();
  $(this).next('div').toggle();
  $('.list-header.major').removeClass('active');
  $(this).toggleClass('active');
  return false;
});

Here is it the fiddle

Comments