Select Closest href Match With jQuery? - javascript

trying to narrow down <a> hrefs to one with jQuery filter and then add the tag active class. I am doing this because I get redirected from sidebar submenu and want to still keep sidebar menu open.
$(document).ready(function () {
var url = window.location;
$('ul.treeview-menu a').filter(function () {
return url.indexOf(this.href) > -1;
}).parentsUntil(".sidebar-menu > .treeview-menu").addClass('active');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="sidebar-menu" data-widget="tree">
<li class="header">General</li>
<li class="home"><i class="fas fa-tachometer-alt"></i> <span> Dashboard</span></li>
<li class="header">Data Managment</li>
<li class="treeview">
<a href="#">p <span>Tree</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li>foo</li>
<li>bar</li>
<li>blah</li>
<li>blahh</li>
</ul>
</li>
<li class="treeview">
<a href="#"></i> <span>Tree 2</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li>aaa</li>
...
</ul>
</li>
</ul>
then if I get redirected inside foo and href be like /p/pages/foo.php/new.php I still want to foo be active.
why don't this work?

Other way would be using each loop and then comparing if the url == this.href if yes then add class to that li and open closest ul.
Demo Code :
$(document).ready(function() {
//just for demo...
var url = 'https://stacksnippets.net/p/pages/bar.php';
$('ul.treeview-menu a').each(function() {
//if full url is not same with li use indexof else if http://...also there in href of a tag use below..
if (url == this.href) {
$(this).addClass('active') //add class active to `a`
$(this).closest("ul").slideDown(); //slide ul tag where `li` is active
}
})
})
.treeview-menu {
display: none
}
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="sidebar-menu" data-widget="tree">
<li class="header">General</li>
<li class="home"><i class="fas fa-tachometer-alt"></i> <span> Dashboard</span></li>
<li class="header">Data Managment</li>
<li class="treeview">
<a href="#">p <span>Tree</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li>foo</li>
<li>bar</li>
<li>blah</li>
<li>blahh</li>
</ul>
</li>
<li class="treeview">
<a href="#"> <span>Tree 2</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li>aaa</li>
...
</ul>
</li>
</ul>
Updated Code :
$(window).on('load', function() {
var url = window.location.href;
var new_url = url.slice(url.lastIndexOf('/') + 1);
$('ul.treeview-menu a').each(function() {
var res = this.href.replace(".php", "");
var href = res + "/" + new_url;
if (href == url) {
$(this).parent().addClass('active') //add class active to `a
$(this).closest("ul").slideDown(); //slide ul tag where `li` is active
}
})
});

Related

How to set active class on current nav item

I am facing problem while setting active class on nav item.
Here is my code on template
<nav class="mt-2">
<ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
<li class="nav-item">
<a href="{{ url('/dashboard') }}" class="nav-link">
<i class="nav-icon fas fa-tachometer-alt"></i>
<p>
Dashboard
</p>
</a>
</li>
<li class="nav-item">
<a href="{{ url('/dashboard/logo') }}" class="nav-link">
<i class="nav-icon fab fa-bandcamp"></i>
<p>
Add/Change Logo
</p>
</a>
</li>
<li class="nav-item has-treeview">
<a href="#" class="nav-link">
<i class="nav-icon fas fa-image"></i>
<p>
Banner
<i class="fas fa-angle-left right"></i>
</p>
</a>
<ul class="nav nav-treeview">
<li class="nav-item">
<a href="{{ url('/dashboard/banner') }}" class="nav-link">
<i class="nav-icon fas fa-plus"></i>
<p>Add Banner</p>
</a>
</li>
<li class="nav-item">
<a href="{{url('/dashboard/banner/edit')}}" class="nav-link">
<i class="nav-icon fas fa-edit"></i>
<p>Edit Banner</p>
</a>
</li>
</ul>
</li>
</ul>
</nav>
I tried
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
var url = window.location;
$('ul.nav li.nav-item a[href="' + url + '"]').parent().addClass('active');
$('ul.nav li.nav-item a').filter(function () {
return this.href == url;
}).parent().addClass('active').parent().parent().addClass('active');
});
</script>
But this code setting the "active" class on list tag but not in anchor tag.
Instead of using .parent(), try using .closest('a').
closest() will traverse UP the DOM tree until it finds the specified selector - in the above example, the first <a> tag above the element.
Virtually all of your .parent() can be replaced with .closest() - but use as desired. There is no "right" or "wrong", just what works or is easiest for you.
You can use any normal css/jQuery selector with closest() - from a tagName:
.closest('a')
to a className:
.closest('a.nav-item')
etc.
Reference:
https://api.jquery.com/closest/

How can I select elements having specific siblings?

How can I prevent anchor (<a>) tag from doing nothing if li has ul according to the following code:
<aside class="sidebar">
<div id="leftside-navigation" class="nano">
<ul class="nano-content">
<li>
<a href="index.html">
<span>Home</span>
</a>
</li>
<li class="sub-menu">
<a href="javascript:void(0);">
<span>Categories</span>
<i class="arrow fa fa-angle-right pull-right"></i>
</a>
<ul>
<li>
<a href="index.html">
<span>Home</span>
</a>
</li>
<li>
<a href="index.html">
<span>Lifestyles</span>
</a>
</li>
<li>
<a href="index.html">
<span>Technology</span>
</a>
</li>
</ul>
</li>
</ul>
</div>
I've tried to put javascript:void(0) - it works but I wanted to make it with if else statement or any other way.
I wanted to do that is:
if li.submenu has ul li.has-submenu a prevent default
You can write a selector for a that's a child of an li that has a submenu.
$("li:has(ul) > a").click(function(e) {
e.preventDefault();
});
Another approach would be to not include the <a> tag in general. Just write the the text "Categories" within the <li class="sub-menu> and it will display in menu as normal.
Example:
<li class="sub-menu">
<span>Categories</span>
<i class="arrow fa fa-angle-right pull-right"></i>
<ul>
<li>......
Although you would need to add CSS if you want the cursor to change or if you want the text to be underlined for your <span> etc...
You can also try this.
$("li").find("ul > a").click(function(e) {
e.preventDefault();
});

How can i get clicked link href?

I need to confirm users when they try to exit forms and click on menu; I try to use preventDefault method and its work, but I need get menu item's href that user clicks on it to set after confirm response is true.
I have this HTML code:
<ul class="page-sidebar-menu page-header-fixed page-sidebar-menu-hover-submenu ">
<li class="start ">
<a href="/Dashboard">
<i class="icon-home"></i>
<span class="title">Dashboard</span>
</a>
</li>
<li class=" ">
<a href="javascript:;" class="auto">
<i class="icon-wrench"></i>
<span class="title">Administration</span>
</a>
<ul class="sub-menu">
<li>
<a href="/OrganizationUnits">
<span><i class="sub-menu-icon icon-layers"></i> Organization units</span>
</a>
</li>
</ul>
</li>
<li class=" ">
<a href="javascript:;" class="auto">
<a href="javascript:;" class="auto">
<span class="title">Base Info</span>
</a>
<ul class="sub-menu">
<li>
<a href="javascript:;" class="auto">
<i class="fa fa-map-marker"></i>
<span class="title">Area</span>
<span class="arrow"></span>
</a>
<ul class="sub-menu">
<li>
<a href="/Country">
<span><i class="sub-menu-icon fa fa-map-marker"></i> Countries</span>
</a>
</li>
<li>
<a href="/Zone">
<span><i class="sub-menu-icon fa fa-map-marker"></i> Zones</span>
</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
I try to find links href after each link is click. the following code is my java script:
$('ul.page-sidebar-menu li a').click(function(e) {
e.preventDefault();
confirm("Are You Sure To Exit From This Form?", function (isConfirm) {
if (isConfirm) {
window.location = $(this).attr('href');
}
});
});
But $(this).attr('href') equals undefined.
How can I get clicked link href?
Inside confirm's callback handler, scope of this changes local to that function,
So change it to
$('ul.page-sidebar-menu li a').click(function(e) {
e.preventDefault();
var $self = $(this); //notice this new line
confirm("Are You Sure To Exit From This Form?", function (isConfirm) {
if (isConfirm) {
window.location = $self.attr('href'); //notice $(this) is replaced by $self
}
});
});
Adding to gurvinder372's answer, you can also use arrow function instead of assigning this to $self.
$('ul.page-sidebar-menu li a').click(function(e) {
e.preventDefault();
confirm("Are You Sure To Exit From This Form?", isConfirm => {
if (isConfirm) {
window.location = $(this).attr('href');
}
});
});

How to add active class only on second level of the navigation

I have an vertical navigation with two levels.
What I want is when I press the main li to add active and open class just to the main li and when I press on the sub-menu I want to add active just to that li. Here is my code:
HTML
<ul class="page-sidebar-menu" data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200">
<li class="start active open">
<a href="javascript:;">
<i class="icon-home"></i>
<span class="title">Rezervari</span>
<span class="arrow "></span>
</a>
<ul class="sub-menu">
<li class="active">
<a href="#">
<i class="icon-bar-chart"></i>
Vezi rezervari</a>
</li>
<li>
<a href="#">
<i class="icon-bulb"></i>
Istoric rezervari</a>
</li>
</ul>
</li>
<li>
<a href="javascript:;">
<i class="icon-home"></i>
<span class="title">Rezervari</span>
<span class="arrow "></span>
</a>
<ul class="sub-menu">
<li>
<a href="#">
<i class="icon-bar-chart"></i>
Vezi rezervari</a>
</li>
<li>
<a href="#">
<i class="icon-bulb"></i>
Istoric rezervari</a>
</li>
</ul>
</li>
</ul>
JS
$(".sub-menu li").on("click", function() {
$(".sub-menu li").removeClass("active");
$(this).addClass("active");
});
$(".page-sidebar-menu li").on("click", function() {
$(".page-sidebar-menu li").removeClass("active open");
$(this).addClass("active open");
});
You have to target the closest li inside class .page-sidebar-menu
$(".sub-menu li").on("click", function() {
$(".sub-menu li").removeClass("active");
$(this).addClass("active");
});
$(".page-sidebar-menu > li").on("click", function() {
$(".page-sidebar-menu > li").removeClass("active open");
$(this).addClass("active open");
});
i'm not sure if i understood exactly what you asked.
But, from what i get i remade your html a bit (added a menu class to bind the click event more precisely)
<ul class="page-sidebar-menu" data-keep-expanded="false" data-auto-scroll="true" data-slide-speed="200">
<li class="menu start active open"> <a href="javascript:;">
<i class="icon-home"></i>
<span class="title">Rezervari</span>
<span class="arrow "></span>
</a>
<ul class="sub-menu">
<li class="active"> <a href="#">
<i class="icon-bar-chart"></i>
Vezi rezervari</a>
</li>
<li> <a href="#">
<i class="icon-bulb"></i>
Istoric rezervari</a>
</li>
</ul>
</li>
<li class="menu"> <a href="javascript:;">
<i class="icon-home"></i>
<span class="title">Rezervari</span>
<span class="arrow "></span>
</a>
<ul class="sub-menu">
<li> <a href="#">
<i class="icon-bar-chart"></i>
Vezi rezervari</a>
</li>
<li> <a href="#">
<i class="icon-bulb"></i>
Istoric rezervari</a>
</li>
</ul>
</li>
</ul>
And so my version of your jQuery looks like that :
$(document).ready(function () {
// added a menu class to bind the click event more precisely
$(".menu > a").on("click", function () {
// nothing is active but this
$(".active").removeClass("active");
// and close the other menus
$(".menu").removeClass("open");
$(this).parent().addClass("active open");
});
$(".sub-menu li").on("click", function () {
// nothing is active but this
$(".active").removeClass("active");
$(this).addClass("active");
});
});
The CSS i used to test it was just this :
.menu { display: block; }
.sub-menu { display: none; }
.open, .open .sub-menu { display: block; }
.active { text-transform: uppercase; }
For an example, go check that jsfiddle that i made to answer you (really basic css here) and tell me if that's what you asked for.

mmenu doesnt fire onclick event

I am using the mmenu jquery plugin (http://mmenu.frebsite.nl/).
When clicking on items on the menu it doesnt trigger my onclick event. Any ideas why this could be happening would be much appreciated.
<nav id="menu">
<ul>
<li>
<span id="showScanDataBtn">
<i class="menu-icon fa fa-leaf"></i> Scan Data
</span>
</li>
<li>
<span id="showPickingBtn">
<i class="menu-icon fa fa-list"></i> View Picking
</span>
</li>
<li>
<span id="logoutBtn">
<i class="menu-icon fa fa-power-off"></i> Logout
</span>
</li>
</ul>
</nav>
This is the javascript:
$(function () {
$("#showPickingBtn").click(function (e) {
alert("Button Clicked!");
});
});
I have also tried the exact same but with a tags instead just in case the span was causing the issue, but im having the same effect.
How about this?
$("#showPickingBtn").on("click", function (e) {
alert("Button Clicked!");
});
try with ...on('click', function...
$(function () {
$("#showPickingBtn").on('click', function (e) {
alert("Button Clicked!");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="menu">
<ul>
<li>
<span id="showScanDataBtn">
<i class="menu-icon fa fa-leaf"></i> Scan Data
</span>
</li>
<li>
<span id="showPickingBtn">
<i class="menu-icon fa fa-list"></i> View Picking
</span>
</li>
<li>
<span id="logoutBtn">
<i class="menu-icon fa fa-power-off"></i> Logout
</span>
</li>
</ul>
</nav>
Maybe you can use this as example so you just have to set the onclick event once and then inside check for id and do whatever you want with it...
$(function () {
$("#menu").find('li span').on('click', function (e) {
if( $(this).attr('id') === 'showPickingBtn' ) {
alert('CRAZY - ' + 'showPickingBtn' + ' has been clicked');
} else {
alert($(this).attr('id') + ' has been clicked');
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="menu">
<ul>
<li>
<span id="showScanDataBtn">
<i class="menu-icon fa fa-leaf"></i> Scan Data
</span>
</li>
<li>
<span id="showPickingBtn">
<i class="menu-icon fa fa-list"></i> View Picking
</span>
</li>
<li>
<span id="logoutBtn">
<i class="menu-icon fa fa-power-off"></i> Logout
</span>
</li>
</ul>
</nav>
this code working for me
$(document).ready(function() {
$("#showPickingBtn").click(function (e) {
alert("Button Clicked!");
});
});

Categories