HTML code from menu:
<ul id="sidebarMenu" data-nav-type="accordion">
<li >
<a href="#" ><i ></i>Webadmin</a>
<ul >
<li ><a href="#" ><i ></i>tester</a>
<ul >
<li >
<a href="#" ><i ></i>tester 2</a>
<ul >
<li >
<a href="/webadmin/config" ><i ></i>Site instellingen</a>
</li>
</ul>
</li>
</ul>
</li>
<li ><a href="/webadmin/configMenu" ><i ></i>Menu aanpassen</a></li>
</ul>
</li>
</ul>
What I want is add a class 'nav-item-expanded nav-item-open' on al related li with class nav-item-submenu.
So if the user is an a page that the menu collapse automatically the sub menus until the link
I have the next code:
This works. But its limited on my script this wil go back for 5 subs. But if the user want to use by example 6 menus the script fails. Sorry for my bad writing: D
$('.nav-item > a.active')
.closest('.nav-item-submenu')
.addClass('nav-item-expanded nav-item-open')
.parent()
.closest('.nav-item-submenu')
.addClass('nav-item-expanded nav-item-open')
.parent()
.closest('.nav-item-submenu')
.addClass('nav-item-expanded nav-item-open')
.parent()
.closest('.nav-item-submenu')
.addClass('nav-item-expanded nav-item-open')
.parent()
.closest('.nav-item-submenu')
.addClass('nav-item-expanded nav-item-open')
how can I simplify this code?
Example that I have tried:
var test = function(data = '') {
if (data === '') {
data = $('.nav-item > a.active').closest('.nav-item-submenu');
} else {
data = data.parent().closest('nav-item-submenu');
}
if (data.length > 0) {
data.addClass('nav-item-expanded nav-item-open');
test(data);
}
};
but that's not working.
CodePudding user response:
You can use .parentsUntil()
to simplify this. It returns all ancestors up to a point and can filter them. It takes two parameters:
- Selector for the final ancestor to stop at.
- Selector to filter the ancestors by.
This is almost the opposite of .find()
which will traverse descendants instead. However, .find()
will always work at any depth, it does not have a stop conditions like .parentsUntil()
.
A single call to .parentsUntil('#sidebarMenu', '.nav-item-submenu')
will return all ancestor elements that you want - the .nav-item-submenu
ones. At that point, you can add the classes you want or manipulate them further, if needed.
$('button').on('click', function() {
$('.nav-item > a.active')
.parentsUntil('#sidebarMenu', '.nav-item-submenu')
.addClass('nav-item-expanded nav-item-open');
})
.nav-item-submenu {
min-height: 50px;
padding: 5px;
border: 1px dashed black;
}
.nav-item-expanded {
border: 2px solid black;
}
.nav-item-open {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul id="sidebarMenu" data-nav-type="accordion">
<li >
<a href="#" >A</a>
<ul >
<li ><a href="#" >B1</a>
<ul >
<li >
<a href="#" >C</a>
<ul >
<li >
<a href="#" >D</a>
</li>
</ul>
</li>
</ul>
</li>
<li ><a href="#" >B2</a></li>
</ul>
</li>
</ul>
<button>Click me</button>