Bootstrap menu click event in jQuery - javascript

HTML :
<ul id="Mydatatabs" class="nav nav-tabs nav-justified">
<li class="active"><a data-toggle="tab" href="#details" id="TabDetailsLink">Personal
Details</a></li>
<li><a data-toggle="tab" href="#tab1" id="Tabtab1Link">tab1</a></li>
<li><a data-toggle="tab" href="#tab2" id="Tabtab2Link">tab2</a></li>
<li><a data-toggle="tab" href="#tab3" id="Tabtab3Link">tab3</a></li>
<li><a data-toggle="tab" href="#tab4" id="Tabtab4Link">tab4</a></li>
</ul>
JS :
$("#Mydatatabs li").click(function (e) {
e.preventDefault();
alert(1);
var MyID = $("#MyID").val();
alert(2);
switch ($(this).children(":first").attr("href")) {
alert(3);
case "#tab1":
});
Here I am unable to recieve the click event . Looks like I am making some mistake. Can someone show me the right way.

Because the JS is loaded first the DOM is not ready yet so it could not find the Mydatatabs list, you should put your code inside ready function :
$(function(){
//Your code here
})
Hope this helps.
$(function(){
$("#Mydatatabs li").click(function (e) {
e.preventDefault();
alert(1);
var MyID = $("#MyID").val();
alert(2);
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<ul id="Mydatatabs" class="nav nav-tabs nav-justified">
<li class="active"><a data-toggle="tab" href="#details" id="TabDetailsLink">Personal
Details</a></li>
<li><a data-toggle="tab" href="#tab1" id="Tabtab1Link">tab1</a></li>
<li><a data-toggle="tab" href="#tab2" id="Tabtab2Link">tab2</a></li>
<li><a data-toggle="tab" href="#tab3" id="Tabtab3Link">tab3</a></li>
<li><a data-toggle="tab" href="#tab4" id="Tabtab4Link">tab4</a></li>
</ul>

So, first you have to put your jquery code inside a document ready statement. See the example:
$(document).ready(function(){
//... code
});
This is to be certain that the element to which the .click() event is bound has been created when the function executes.
For further explanation, look this response: Why should $.click() be enclosed within $(document).ready()?
And is not missing any end curly braces in this click event? In between switch case and end of the function?

Related

Bootstrap Navbar Toggler - Custom JS causes navbar menu to close on dropdown click

I'm new to JS and am in the process of learning while coding a website. I'm using a template that I found online with some custom modifications so I'm not super familiar with the JS used. Here is the issue.
While using the navbar toggler there is some custom JS to close the menu when the once a click happens in the menu. The issue is that I added a dropdown into the menu, and when it's clicked instead of showing the drop down details, the JS executes and closes the menu. here is the JS:
window.addEventListener('DOMContentLoaded', event => {
// Navbar shrink function
var navbarShrink = function () {
const navbarCollapsible = document.body.querySelector('#mainNav');
if (!navbarCollapsible) {
return;
}
if (window.scrollY === 0) {
navbarCollapsible.classList.remove('navbar-shrink')
} else {
navbarCollapsible.classList.add('navbar-shrink')
}
};
// Shrink the navbar
navbarShrink();
// Shrink the navbar when page is scrolled
document.addEventListener('scroll', navbarShrink);
// Activate Bootstrap scrollspy on the main nav element
const mainNav = document.body.querySelector('#mainNav');
if (mainNav) {
new bootstrap.ScrollSpy(document.body, {
target: '#mainNav',
offset: 74,
});
};
// Collapse responsive navbar when toggler is visible
const navbarToggler = document.body.querySelector('.navbar-toggler');
const responsiveNavItems = [].slice.call(
document.querySelectorAll('#navbarResponsive .nav-link')
);
responsiveNavItems.map(function (responsiveNavItem) {
responsiveNavItem.addEventListener('click', () => {
if (window.getComputedStyle(navbarToggler).display !== 'none') {
navbarToggler.click();
}
});
});
});
Only the bottom function is running the menu click/close function, but I provided all the code as for the custom menu actions as I'm not super familiar with JS. I understand, more or less, what it is doing, but I'm not sure how to modify it appropriately.
I'd imagine there is a simple way to modify that last "if" statement to check to see what was actually clicked (for example, if a .dropdown-menu was clicked). I just don't know how to use the code that is there and check what click caused the event trigger. I'd like to keep the close behavior when the .dropdown-items and other .nav-items are clicked. I just don't want the behavior when the .dropdown-menu is clicked.
Here is the html:
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav text-uppercase ms-auto py-4 py-lg-0">
<li class="nav-item"><a class="nav-link" href="#portfolio">Products</a></li>
<li class="nav-item"><a class="nav-link" href="#services">Services</a></li>
<li class="nav-item"><a class="nav-link" href="#how-to-order">How Order</a></li>
<li class="nav-item dropdown"><a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false">F.A.Q.</a>
<ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="dropdownMenuButton2">
<li><a class="dropdown-item" href="#">Knowledge Base</a></li>
<li><hr class="dropdown-divider"></li>
<li><h4 class="dropdown-header">Most Common Questions:</h4></li>
<li><a class="dropdown-item" href="#">Where are you located</a></li>
<li><a class="dropdown-item" href="#">How long is shipping</a></li>
<li><a class="dropdown-item" href="#">How do I pay</a></li>
<li><hr class="dropdown-divider"></li>
</ul>
</li>
<li class="nav-item"><a class="nav-link" href="#contact">Contact</a></li>
</ul>
</div>
I'm pretty sure this is a super simple JS problem that any coder worth his $.02 would know, but not knowing JS I don't even know where or what to search for. Any help?
The issue with your code is that when you are using querySelectorAll to access the nav-links the code is trying to access all the nav-links i.e., you are considering all the nav-links then the dropdown in your nav which is also a nav-link is also considered. So the better way to solve this is you can create a new class and attach it to the dropdown nav-link in your case F.A.Q and exclude that class from the function.
Your code:
<li class="nav-item dropdown"><a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false">F.A.Q.</a>
<ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="dropdownMenuButton2">
<li><a class="dropdown-item" href="#">Knowledge Base</a></li>
<li><hr class="dropdown-divider"></li>
<li><h4 class="dropdown-header">Most Common Questions:</h4></li>
<li><a class="dropdown-item" href="#">Where are you located</a></li>
<li><a class="dropdown-item" href="#">How long is shipping</a></li>
<li><a class="dropdown-item" href="#">How do I pay</a></li>
<li><hr class="dropdown-divider"></li>
</ul>
</li>
const responsiveNavItems = [].slice.call(
document.querySelectorAll('#navbarResponsive .nav-link')
);
You can add a class called faq and exlude it from the querySelectorAll using :not()
<!-- added a new class faq to the dropdown link -->
<li class="nav-item dropdown"><a class="nav-link dropdown-toggle faq" data-bs-toggle="dropdown" role="button" aria-expanded="false">F.A.Q.</a>
<ul class="dropdown-menu dropdown-menu-dark" aria-labelledby="dropdownMenuButton2">
<li><a class="dropdown-item" href="#">Knowledge Base</a></li>
<li><hr class="dropdown-divider"></li>
<li><h4 class="dropdown-header">Most Common Questions:</h4></li>
<li><a class="dropdown-item" href="#">Where are you located</a></li>
<li><a class="dropdown-item" href="#">How long is shipping</a></li>
<li><a class="dropdown-item" href="#">How do I pay</a></li>
<li><hr class="dropdown-divider"></li>
</ul>
</li>
// select all links except faq class
const responsiveNavItems = [].slice.call(
document.querySelectorAll('#navbarResponsive a.nav-link:not(.faq)')
);
Just add the below scripts within your tags, preferably before the closing tag
<!-- JavaScript -->
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>

Script runs multiple times

I have this script that replaces content in a div using a menu structure.
This works fine, except it runs multiple times when clicking the various menu items. This makes the page load really slow.
Here is my structure:
$(document).ready(function() {
$('a.nav-link').click(function(e) {
var datalist = $(this).data('value');
var dataname = $(this).data('name');
console.log(datalist, dataname);
$(".content_div").hide().delay(500).fadeIn(500);
$(".content_div").load(dataname + ".php");
return false;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<ul class="nav nav-tabs" id="top-nav" role="tablist">
<li class="nav-item"><a class="nav-link active home" href="#" data-value="home" data-name="home">Aanwezig</a></li>
<li class="nav-item"><a class="nav-link" href="#" data-value="vervoer" data-name="vervoer">Vervoer</a></li>
<li class="nav-item"><a class="nav-link" href="#" data-value="extra" data-name="extra">Overige</a></li>
</ul>
</nav>
<div class="content_div">
</div>
And a screenshot of the console where you can see the script is multiplying...
I have no idea why this is happening. Any help would be really great...
It looks like your js code with the eventhandler is loaded more than once. You better figure out why.
Anyway, you can overcome this by using .off('click').on('click') (every time the code runs you cancel the existing eventhandler (off()) and set a new one (on()).
$('a.nav-link').off('click').on('click', function(e){ ...});
Like other already said, the script itself work fine, maybe because your script it's included more than once in your page.
$(document).ready(function() {
$('a.nav-link').on('click', function(e) {
e.preventDefault();
var datalist = $(this).data('value');
var dataname = $(this).data('name');
console.log('datalist : ', datalist);
console.log('dataname : ', dataname);
$(".content_div").hide().delay(500).fadeIn(500);
$(".content_div").load(dataname + ".php");
});
});
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<nav>
<ul class="nav nav-tabs" id="top-nav" role="tablist">
<li class="nav-item"><a class="nav-link active home" href="#" data-value="home" data-name="home">Aanwezig</a></li>
<li class="nav-item"><a class="nav-link" href="#" data-value="vervoer" data-name="vervoer">Vervoer</a></li>
<li class="nav-item"><a class="nav-link" href="#" data-value="extra" data-name="extra">Overige</a></li>
</ul>
</nav>
<div class="content_div">
</div>
</body>
</html>
Put a log statement in your $(document).ready
$(document).ready(function() {
console.log('Ready');
$('a.nav-link').click(function(e) {});
});
To trace how many the document.ready is called.
To make sure the 'click' event on your link item to be call only once, you can change the code a little bit
$(document).ready(function() {
console.log('Ready');
$('a.nav-link').unbind('click').bind('click', function(e) {});
});
It is because of calling .click on an item means adding a new event handler on that item, not replacing.

trigger click on next tab in jQuery

How to trigger click on next tab in jQuery, I have tried below code but not working, TIA.
var c = $('ul#tabs li').length;
var selected = parseInt($('ul#tabs li.active').index())+1;
if (c != selected) {
$("ul#tabs li:nth-child(" + selected + ")").click();
return false;
}
<div id="mytabs">
<ul class="nav nav-tabs" id="tabs">
<li class="active"><a data-toggle="tab" href="#Personal" aria-expanded="false">Personal</a></li>
<li><a data-toggle="tab" href="#Business">Business</a></li>
<li><a data-toggle="tab" href="#Documents" aria-expanded="true">Documents</a></li>
<li><a data-toggle="tab" href="#References">References</a></li>
<li><a data-toggle="tab" href="#OrderDelivery">Order & Delivery</a></li>
</ul>
</div>
I'm a bit unclear as to what's not working, but the simplified code below is all that's required to get current tab and next tab:
$(document).ready(function() {
let currentTab = $('ul#tabs li.active');
let nextTab = currentTab.next();
// Once you have the tab, click it (clicking after 2 seconds to demonstrate)
setTimeout(function() { nextTab.find("a").get(0).click()}, 2000);
// If you need to do things when a tab is clicked, create an event handler
$('a[data-toggle="tab"]').click(function(event) {
// Do something when a tab is clicked
// For example: Remove active class, and add it to active element
$('a[data-toggle="tab"]').parent().removeClass("active");
// Add active class to clicked li
$(this).parent().addClass("active");
});
});
.active a {
color: green !important;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="mytabs">
<ul class="nav nav-tabs" id="tabs">
<li class="active"><a data-toggle="tab" href="#Personal" aria-expanded="false">Personal</a></li>
<li><a data-toggle="tab" href="#Business">Business</a></li>
<li><a data-toggle="tab" href="#Documents" aria-expanded="true">Documents</a></li>
<li><a data-toggle="tab" href="#References">References</a></li>
<li><a data-toggle="tab" href="#OrderDelivery">Order & Delivery</a></li>
</ul>
</div>

How do I get the current element on nav bar and save on localStorage?

I have a nav bar, this has a links to pages, I want to save the current nav active when I clicked on that, this because I have a same menu in the other pages.
<ul>
<li id="nav1" class="navigation-item"><a href="#" >Nav 1</a></li>
<li class="navigation-item"><a href="#" >Nav 2</a></li>
<li class="navigation-item"><a href="#" >Nav 2</a></li>
<li class="navigation-item"><a href="#" >Nav 2</a></li>
</ul>
I try to get from $(this) and then use after the page is reload in order to add the class active.
$(document).ready(function () {
$('.navigation-item').on('click', function (e) {
var current = $( this );
console.log(current);
console.log(JSON.stringify(current));
localStorage.setItem('activeTab', current);
});
var activeTab = localStorage.getItem('activeTab');
if (activeTab) {
// activeTab.addClass('active');
// $('#nav1').parent().addClass('active');
console.log(activeTab);
$( "ul li:nth-child(2)" ).append( "<span> - 2nd!</span>" );
}
});
jsFiddle
Best Regards.
You need to store the index of the element:
$('.navigation-item').on('click', function (e) {
var current = $(this );
console.log(current);
console.log(JSON.stringify(current));
localStorage.setItem('activeTab', $('.navigation-item').index(current));
});
And then, use the index to get back the element:
var activeTab = localStorage.getItem('activeTab');
if (activeTab) {
activeTabEL = $('.navigation-item').eq(parseInt(activeTab));
activeTabEL.addClass('active');
// $('#nav1').parent().addClass('active');
console.log(activeTabEL);
$( "ul li.navigation-item" ).eq(parseInt(activeTab)).append( "<span> - 2nd!</span>" );
}
Example: https://jsfiddle.net/xmzb7hdk/7/
You don't need much JavaScript. You can use an HTML5 custom attribute to identify each element in the nav (data-nav-item):
<ul>
<li data-nav-item="nav-1" id="nav1" class="navigation-item"><a href="#" >Nav 1</a></li>
<li data-nav-item="nav-2" class="navigation-item"><a href="#" >Nav 2</a></li>
<li data-nav-item="nav-3" class="navigation-item"><a href="#" >Nav 2</a></li>
<li data-nav-item="nav-4" class="navigation-item"><a href="#" >Nav 2</a></li>
</ul>
Then it's just a simple 3 lines of JavaScript to set the value:
$(document).on("click", "[data-nav-item]", function(event) {
localStorage.setItem("activeTab", this.getAttribute("data-nav-item"));
});
After that, you can identify the active nav using:
var activeTab = $("[data-nav-item='" + localStorage.getItem("activeTab") + "']")
You can store the id Instead of storing the whole object.
It simplifies the use on retrieval.
Fiddle here
HTML:
<ul>
<li id="nav1" class="navigation-item"><a href="#" >Nav 1</a></li>
<li id="nav2" class="navigation-item"><a href="#" >Nav 2</a></li>
<li id="nav3" class="navigation-item"><a href="#" >Nav 3</a></li>
<li id="nav4" class="navigation-item"><a href="#" >Nav 4</a></li>
</ul>
Script:
$(document).ready(function () {
$('.navigation-item').on('click', function (e) {
var currentID = $(this).attr("id");
console.log(currentID+" = stored to localStorage");
localStorage.setItem('activeTab', currentID);
});
var activeTab = localStorage.getItem('activeTab');
if (activeTab!="") {
console.log(activeTab+" = retrieved form localStorage");
$("#"+activeTab ).append( "<span> - active!</span>" );
$("#"+activeTab ).addClass('active');
}
});

Changing aria-expanded="true" manually not opening new tab

I would like to open another tab after certain action is true.
Here you see my bootstrap navbar and the jQuery script.
<ul class="nav navbar-default nav-justified" role="tablist" id="navbar">
<li role="presentation" class="active"><a id="tab1" href="#home" aria-controls="home" role="tab" data-toggle="tab">Home</a></li>
<li role="presentation" ><a id="tab2" href="#msg" aria-controls="msg" role="tab" data-toggle="tab">Messages</a></li>
</ul>
And here is the script.
$("#password-button").on("click", function () {
if($("#password-name").val() === password) {
$("#tab1").attr("aria-expanded", "false");
$("#tab2").attr("aria-expanded", "true");
}
}
Firebug shows me that it changes those attributes but nothing happens?
Use .tab() property to show or hide tab from Jquery. Try this:
$('.nav-tabs a[href="#tab1"]').tab('show');
Working DEMO

Categories