Getting the class of the element being clicked in jQuery - javascript

I have a jQuery snippet that collapses the responsive navbar (in mobile mode) when a menu item is clicked.
$('.navbar-fixed-top').click('li', function() {
$('.navbar-collapse').collapse('hide');
});
However, I also have a couple of menu items with drop-down sub-menus and they have the Bootstrap class .dropdown assigned to them. I want the above function to exempt these dropdown menu items.
To that end, I would like to retrieve the class of the item being clicked in order to make a decision on whether to collapse the navbar.
I tried this but it didn't output anything.
$('.navbar-fixed-top').click('li', function() {
console.log($(this).class);
$('.navbar-collapse').collapse('hide');
});
I also tried this with similar results.
$('.navbar-fixed-top').click('li', function(event) {
console.log(event.target.class);
$('.navbar-collapse').collapse('hide');
});
What else can I try? Right now, my navbar collapses when the dropdown menu item is tapped on a mobile device even before the user has a chance to see the sub-items which is what I am trying to remedy.
In case anyone wants to take a look, here's the HTML:
<ul class="nav navbar-nav pull-right">
<li ng-class="{ active: isActive('/about')}"><a onClick="pagetop()" href="#about">ABOUT</a></li>
<li ng-class="{ active: isActive('/blog')}"><a onClick="pagetop()" href="#blog">BLOG</a></li>
<li><a onClick="pagetop()" href="#">PREMIUM</a></li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">RESOURCES<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
<li role="separator" class="divider"></li>
<li>Separated link</li>
<li role="separator" class="divider"></li>
<li>One more separated link</li>
</ul>
</li>
<li>CONTACT</li>
</ul>

In jQuery, you can do:
$(this).attr('class');
which is equal to className in plain JS:
event.target.className;
Since target references the anchor, you need the class of its parent (which is the li element). Try clicking the first two items here (added dummy-classes for them):
$('.nav').click('li', function(e) {
alert(e.target.parentElement.className);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav navbar-nav pull-right">
<li class="aboutClass" ng-class="{ active: isActive('/about')}">ABOUT <--- click me
</li>
<li class="blogClass" ng-class="{ active: isActive('/blog')}">BLOG <--- click me
</li>
<li><a onClick="pagetop()" href="#">PREMIUM</a>
</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">RESOURCES<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Action
</li>
<li>Another action
</li>
<li>Something else here
</li>
<li role="separator" class="divider"></li>
<li>Separated link
</li>
<li role="separator" class="divider"></li>
<li>One more separated link
</li>
</ul>
</li>
<li>CONTACT
</li>
</ul>

Related

How to extract specific text from a html tag that is dynamically placed in the code

I want to extract a specific text which is located between the <li></li> tags in the navigation bar of a html page, but the code's not consistent. The order of the navbar elements changes depending on the conditions that I'm unable to predict. The only thing that doesn't change in the code is the <li></li> tags where the text I want to extract is embedded.
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active">Homepage</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Menu - 1<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Menu - 1 - Option - 1</li>
<li>Menu - 1 - Option - 1</li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Menu - 2<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Menu - 2 - Option - 1</li>
<li>Menu - 2 - Option - 2</li>
<li role="separator" class="divider"></li>
<li>Menu - 2 - Option - 3</li>
<li>Menu - 2 - Option - 4</li>
</ul>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Menu - 3<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Menu - 3 - Option - 1</li>
<li>Menu - 3 - Option - 2</li>
</ul>
</li>
<!-- The element I need to access -->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">
------->[TEXT I WANT TO EXTRACT]<-------
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>My Account</li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">Help</li>
<li>Contact Us</li>
<li>Logout</li>
</ul>
</li>
<!-- The element I need to access -->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Menu - 5<span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Menu - 5 - Option - 1</li>
<li>Menu - 5 - Option - 2</li>
<li>Menu - 5 - Option - 3</li>
</ul>
</li>
</ul>
</div>
So, the following <li></li> tags of the code never changes, but its placement in the navbar changes:
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">
------->[TEXT I WANT TO EXTRACT]<-------
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>My Account</li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">Help</li>
<li>Contact Us</li>
<li>Logout</li>
</ul>
</li>
When I try to extract the text using querySelector from JavaScript, it sometimes doesn't work because the <li></li> element is no longer the fifth one in the list. Thus, the selector doesn't match:
document.querySelector('li.dropdown:nth-child(5) > a:nth-child(1)');
What would be the safest way for me to extract this text?
Maybe you can give a class to the li that you want to extract and then select that class using querySelector.
Here I am assuming you want to select the logout list element.
------->[TEXT I WANT TO EXTRACT]<-------
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li>My Account</li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">Help</li>
<li>Contact Us</li>
<li class="logout">Logout</li> //Here I have given a class 'logout'
</ul>
</li>
Select that li element using querySelector
let text = document.querySelector('.logout').innerText;
Using the filter method to find the right element is the solution to my issue. I just check whether the children of the specified tags contain a particular text that the element I want to access has. Then, I simply extract the text like the following:
// Retrieve all children inside of the navbar
Array.from(document.querySelectorAll(".nav > li.dropdown"))
// Filter the child that contains the text
.filter((el) => el.textContent.includes("Logout"))[0]
// Extract the text from the child tag
.querySelector("a").textContent.trim();

Manipulating a Bootstrap nav with dropdowns so 1 dropdown is always exposed on the page

I have a standard Bootstrap (3.3.7) nav item with 2 dropdown menus. Upon loading the page, the first dropdown item in the nav should be exposed by default. When hovering over the second dropdown item, that item should now be the only exposed dropdown until the first is hovered over again. Clicking anywhere on the page should not close any dropdown menu, and clicking on the name of the dropdown (Dropdown #1, etc) must function as a link.
I currently have it so the nav is exposed by default and the nav switches on hover, but clicking anywhere on the page closes the dropdown and I do not know how to override this. Also, is there a better way to have the first item defaulted to open?
My code looks something like this:
$(document).ready(function() {
var $dropdown = $(".nav li.dropdown");
$dropdown.first().addClass('open');
$dropdown.hover(function() {
if (!$(this).hasClass('open')) {
$dropdown.removeClass('open');
$(this).addClass('open');
}
});
});
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="collapse navbar-collapse" id="test-nav">
<ul class="nav navbar-nav">
<li class="dropdown">
Dropdown #1 <span class="caret"></span>
<ul class="dropdown-menu">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
<li>Separated link</li>
<li>One more separated link</li>
</ul>
</li>
<li class="dropdown">
Dropdown #2 <span class="caret"></span>
<ul class="dropdown-menu">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
<li>One more separated link</li>
</ul>
</li>
</ul>
</div><!-- /.navbar-collapse -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
You can prevent the default action of hide.bs.dropdown while closing (removing open class) current dropdown on element click. It's enough to add:
$dropdown.on('hide.bs.dropdown', function (e) {
e.preventDefault();
})
$(".nav li.dropdown ul.dropdown-menu").on('click', function (e) {
$(this).closest('li.dropdown').toggleClass('open forceclose');
})
And avoid to add open class to current dropdown if it has the class forceclose.
$(".nav li.dropdown").on('mouseenter', function (e) {
if (!$(this).hasClass('open')) {
$(".nav li.dropdown").removeClass('open');
if ($(this).is('.forceclose')) {
$(this).removeClass('forceclose');
} else {
$(this).addClass('open');
}
}
}).on('hide.bs.dropdown', function (e) {
e.preventDefault();
}).first().addClass('open');
$(".nav li.dropdown ul.dropdown-menu").on('click', function (e) {
$(this).closest('li.dropdown').toggleClass('open forceclose');
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="collapse navbar-collapse" id="test-nav">
<ul class="nav navbar-nav">
<li class="dropdown">
<a href="http://google.com" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-haspopup="true" aria-expanded="false">Dropdown #1 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
<li>Separated link</li>
<li>One more separated link</li>
</ul>
</li>
<li class="dropdown">
<a href="http://google.com" class="dropdown-toggle" data-toggle="dropdown" role="button"
aria-haspopup="true" aria-expanded="false">Dropdown #2 <span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
<li>One more separated link</li>
</ul>
</li>
</ul>
</div>

How can I prevent a menu link from redirecting on first click if it has subitems

I have a menu with multiple dropdowns and each li tag has a link.
The HTML looks like this:
<ul class="menu nav navbar-nav">
<li class="first leaf active active">Home</li>
<li class="expanded dropdown has-children">
About <span class="caret"></span>
<ul class="dropdown-menu depth-1">
<li class="first leaf has-sub-children">Why Somerset College?</li>
<li class="leaf has-sub-children">History</li>
<li class="last expanded dropdown has-sub-children">
Governors <span class="caret"></span>
<ul class="dropdown-menu depth-2">
<li class="first leaf">Board of Governors</li>
<li class="last leaf">PA Commitee</li>
</ul>
</li>
</ul>
</li>
<li class="expanded dropdown has-children">
Admissions <span class="caret"></span>
<ul class="dropdown-menu depth-1">
<li class="first last leaf has-sub-children">Scholarships & Bursaries</li>
</ul>
</li>
<li class="expanded dropdown has-children">
Pre Preparatory <span class="caret"></span>
<ul class="dropdown-menu depth-1">
<li class="first leaf has-sub-children">Aftercare</li>
<li class="last leaf has-sub-children">Letter From the Head</li>
</ul>
</li>
<li class="collapsed">Preparatory</li>
<li class="expanded dropdown has-children">
High School <span class="caret"></span>
<ul class="dropdown-menu depth-1">
<li class="first expanded dropdown has-sub-children">
Senior Academics <span class="caret"></span>
<ul class="dropdown-menu depth-2">
<li class="first leaf">High School - Subject Choices</li>
<li class="leaf">Matric Results</li>
<li class="leaf">Student Development Unit</li>
<li class="last leaf">High School - House, Grade and Tutor System</li>
</ul>
</li>
<li class="expanded dropdown has-sub-children">
Student Leadership <span class="caret"></span>
<ul class="dropdown-menu depth-2">
<li class="first leaf">Social Responsibility</li>
<li class="leaf">The President's Award</li>
<li class="last leaf">Exchange Programme</li>
</ul>
</li>
<li class="leaf has-sub-children">Outdoor Education</li>
<li class="leaf has-sub-children">Sports</li>
<li class="last expanded dropdown has-sub-children">
Culture <span class="caret"></span>
<ul class="dropdown-menu depth-2">
<li class="first leaf">Music</li>
<li class="last leaf">Art</li>
</ul>
</li>
</ul>
</li>
<li class="collapsed">Cambridge</li>
<li class="leaf">Old Oaks</li>
<li class="last leaf">Contact Us</li>
</ul>
With jQuery I managed to the following:
When I click on a first level menu item, it prevents from redirecting and the sub item drops. Then if I click again in it, or in its subitem, the page redirects to its respective url.
However, If I click on the first level, then inside that subitem I click on a link that also has sub-items, after clicking on the link from the last level, the page redirects to the wrong url.
If I click under about->governors->board of governors. The redirect goes to Governors page.
Which means that my js is only working for first level dropdowns.
Initially, my js looked like this:
$('li.dropdown').click(function(e) {
if ($(window).width() < 1800) {
if (!$(e.target).closest('ul').is('.dropdown-menu.depth-1')) {
e.preventDefault();
if (!$(this).hasClass('open')) {
$(this).addClass('open');
//toggle the menu
} else {
//redirect if second click
window.location = $(this).find('a').attr('href');
}
}
}
});
Then I edited to the above in order to work for second level:
$('ul.menu > li.dropdown').addClass("has-children");
$('ul.menu > li.dropdown > ul > li').addClass("has-sub-children");
$('li.dropdown.has-children').click(function(e) {
if ($(window).width() < 1800) {
if (!$(e.target).closest('ul').is('.dropdown-menu.depth-1')) {
e.preventDefault();
if (!$(this).hasClass('open')) {
$(this).addClass('open');
//toggle the menu
} else {
//redirect if second click
window.location = $(this).find('a').attr('href');
}
}
}
});
$('li.expanded.dropdown.has-sub-children').click(function(e) {
if ($(window).width() < 1800) {
if (!$(e.target).closest('ul').is('.dropdown-menu.depth-2')) {
e.preventDefault();
if (!$(this).hasClass('open')) {
$(this).addClass('open');
//toggle the menu
} else {
//redirect if second click
window.location = $(this).find('a').attr('href');
}
}
}
});
How can I make the dropdowns work regardless of the sub level?
When it is cliecked for the first time, you can store it in its data, and the second time redirect:
$('li.dropdown.has-children').click(function(){
if($(this).data("clicked")=='1')
{
//it's been clicked before and redirect
}
else
{
//this is the first time it is clicked
$('li.dropdown.has-children').data("clicked", "0"); // this one is clicked so
//reset previously clicked ones.
$(this).data("clicked", "1");
}
});

Bootstrap Navigation Javascript not working

my Javascript that is supposed to open the 2nd layer of my Navigation does not work and I dont know why it is not working. Am I overseeing something obvious? Its a bit warm in my office atm. :D
$('.submenu').click(function(e) {
e.preventDefault();
if ($(this).closest("ul .sub").hasClass("hide")) {
$(this).closest("ul .sub").removeClass('hide');
$(this).closest("ul sub").addClass('show');
}
else {
$(this).closest("ul sub").addClass('hide');
$(this).closest("ul sub").removeClass('show');
}
});
The HTML:
<nav class="navbar navbar-default navbar-fixed-top">
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse">
<div class="centering">
<ul class="nav navbar-nav">
<li><a class="navbar-brand" href="#"><img id="navlogo" alt="trlololol" src="gfx/Logo_Friedhof_Bildmarke-01.svg"></a></li>
<li class="dropdown">
Dropdown<span class="nav-img"></span>
<ul class="dropdown-menu">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
<li class="submenu dropdown-toggle">Next menu level<span class="nav-img"></span></li>
<ul class="sub hide">
<li>Blablabla</li>
<li>Blablubla</li>
<li>Blablibla</li>
</ul>
<li>One link</li>
</ul>
</li>
<li class="dropdown">
Dropdown32<span class="nav-img"></span>
<ul class="dropdown-menu">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
<li class="submenu">Next menu level<span class="nav-img"></span></li>
<ul class="sub hide">
<li>Blablabla</li>
<li>Blablubla</li>
<li>Blablibla</li>
</ul>
You should nest your ul inside of your li like this:
<li class="submenu">Next menu level<span class="nav-img"></span>
<ul class="sub hide">
<li>Blablabla</li>
<li>Blablubla</li>
<li>Blablibla</li>
</ul>
</li>
Then you can do:
$('.submenu').click(function(e) {
$(this).children('ul.sub').toggleClass('hide')
});
fiddle: https://jsfiddle.net/hubkefw7/

dropdown-toggle in my thymeleaf isn't working

I use spring boot, thymeleaf and bootstrap. This is my partial code in thymeleaf
<ul class="nav navbar-nav">
<li th:class="${page == 'home' ? 'active' : ''}"><a
th:href="#{/}"><span class="glyphicon glyphicon-home"></span>
Home</a></li>
<li class="dropdown"><a href="#" class="dropdown-toggle"
data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false">Dropdown <span class="caret"></span></a>
<ul class="dropdown-menu">
<li>Action</li>
<li>Another action</li>
<li>Something else here</li>
<li role="separator" class="divider"></li>
<li class="dropdown-header">Nav header</li>
<li>Separated link</li>
<li>One more separated link</li>
</ul></li>
</ul>
and this code for includes css and javascript file
<link rel="stylesheet" th:href="#{/bootstrap/css/bootstrap.min.css}" />
<script type="text/javascript" th:src="#{/jquery/jquery-2.1.3.min.js}"></script>
<script>
$(document).ready(function () {
$('.dropdown-toggle').dropdown();
});
</script>
<script type="text/javascript"
th:src="#{/bootstrap/js/bootstrap.min.js}"></script>
Why is the dropdown-toggle in my thymeleaf not working?

Categories

Resources