Navbar div onclick function does not work for inner elements - javascript

I have a div class .dropbtn inside my navbar that I wish would run a list drop down function when clicked, but only the text "TOTAL" works onclick.
The <span> and the <i> inside it do not do anything when I click on it, and I need all three elements to be clickable and display the dropdown function. I am using jQuery, but not Bootstrap. Thanks in advance! EDITED.
jQuery('body').on('click', '.dropbtn', function() {
jQuery("#myDropdown").toggleClass("show");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="reservas_right">
<div class="dropdown_reservas nav-item_reservas" id="inner_reservas_right">
<div class="dropbtn">
TOTAL
<br /><span id="totalprice">0,00€</span>
<i class="material-icons">arrow_drop_down</i>
</div>
<div class="dropdown-content_reservas" id="myDropdown">
<ul id="dropul" class="dropul">
<li id="drop1"></li>
<li id="drop2"></li>
<li id="drop3"></li>
<li id="drop4"></li>
<li id="drop5"></li>
<li id="drop6"></li>
</ul>
</div>
</div>
</div>
CSS:
.show{
list-style-type:none;
}

jQuery('body').on('click', '.dropbtn', function(e) {
if(e.target !== this && jQuery(e.target).parent().is(".dropbtn"))
{
jQuery("#myDropdown").toggleClass("show");
} else {
jQuery("#myDropdown").toggleClass("show");
}
});

Related

Select current element and change values on click

I'm new to Javascript and I've been trying to program a code that changes the value of an attribute and a style when its element is clicked. I have this code and I want that when you click on "<li class="has-sub">" it changes to "<li class="has-sub show">"... and inside it, that "<ul class="sub-menu m-sub" style="display: none;">" changes to "<ul class="sub-menu m-sub" style="display: block;">":
<li class="has-sub">
Hi
<ul class="sub-menu m-sub" style="display: none;">
<li>
Hi
</li>
</ul>
<div class="submenu-toggle"></div>
</li>
When clicked, it should look like this:
<li class="has-sub show">
Hi
<ul class="sub-menu m-sub" style="display: block;">
<li>
Hi
</li>
</ul>
<div class="submenu-toggle"></div>
</li>
I have made the attempt on my own, and tried to place this:
<script type='text/javascript'>
$(document).ready(function change() {
$(this).attr('has-sub','has-sub show');
$(this > ul).css('display','block');
})
</script>
And call the function with "onclick":
<li class="has-sub" onclick"change();">
But I haven't been able to achieve it yet...
Thanks for the help :)
You can use the parent to toggle a class that has display: none applied to it. $(this).children('ul').toggleClass('hide') will target the class hide and then toggle its class on click using toggleClass(). Set the hide class by default on the HTML sub-menu element.
$(document).ready(function(){
$('.has-sub').on('click', function(){
$(this).children('ul').toggleClass('hide')
})
})
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li class="has-sub show">
Hi
<ul class="sub-menu m-sub hide">
<li>
Hi
</li>
</ul>
<div class="submenu-toggle"></div>
</li>
First of all, you need to add click listener on .has-sub and after that you can add class show.
You need to add class show. It is not an attribute.
Just use .has-sub > ul to get the ul that is direct child of .has-sub.
$(document).ready(function change() {
// $(this).attr("has-sub", "has-sub show");
$(".has-sub").click(function() {
$(this).addClass("show");
$(".has-sub > ul").css("display", "block");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li class="has-sub">
Hi
<ul class="sub-menu m-sub" style="display: none;">
<li>
Hi
</li>
</ul>
<div class="submenu-toggle"></div>
</li>
You can use this as click handler, then you can remove the onclick"change();"
$(document).ready(function() {
$(".has-sub > a").on("click", function() {
// here you can use
// - $(this).parent() to do something with the li.has-sub
// - $(this).next("ul") to do something with the ul.sub-menu
});
});

Remove and re-add Class Attribute inside a <div> unordered list item

This is the answer as i was able to solve.
Wanted to change the css class="jsTree-clicked" after the button click event happened from Hyperlink1 to Hyperlink3.
$(document).ready(function () {
//remove Class
$('#myJSTree').find('.jsTree-clicked').removeClass('jsTree-clicked');
//need to do add it to List Item which has Id =3
//check the list item which has id =3 if so add the class to it
// It is not a button click event.
$('#myJSTree li').each(function (i, li) {
console.log('<li> id =' + $(li).attr('id'));
var myIdVal = $(li).attr('id');
if (myIdVal == 3) {
$(this).addClass('jsTree-clicked');
}
});
});
.jsTree-clicked { background-color:red;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="myJSTree">
<ul class="nav nav-list">
<li id="1">
<a class="jsTree-clicked" title="Hyperlink1">HyperLink1</a>
</li>
<li id="2">
<a title="Hyperlink2">HyperLink2</a>
</li>
<li id="3">
<a title="Hyperlink3">HyperLink3</a>
</li>
</ul>
</div>
When the Hyperlink is clicked the JsTree adds a class="jsTree-clicked" . When you navigate to a different node it will remove and re-add the same class to the navigated node.
Expected
I want a function to remove [class="jsTree-clicked"] for the given List Item based on ID inside the div.
AND
Re-add [class="jsTree-clicked"] to any ListItem by passing the Key i.e ID .
I hope I was able to explain my problem.
Thank you
My JSTree is a third party open source.
$('.nav-list').on('click', 'li', function() {
$('.nav-list li.active').removeClass('active');
$(this).addClass('active');
});
.active{
background-color:red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="myJSTree">
<ul class="nav nav-list">
<li id="1">
<a title="Hyperlink1">HyperLink1</a>
</li>
<li id="2">
<a title="Hyperlink2">HyperLink2</a>
</li>
<li id="3">
<a title="Hyperlink3">HyperLink3</a>
</li>
</ul>
</div>
Maybe this is helpful to you?
$(function () { $('#myJSTree').jstree(); });
const toggle = (e) => {
if (+$("#test").val()>=10 ) {
e.target.classList.remove("jstree-clicked");
console.log("You entered an invalid number.")
}
console.log(e.target)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" />
<div id="myJSTree">
<ul>
<li id="1">
<a title="Hyperlink1" onclick="toggle(event)">HyperLink1</a>
</li>
<li id="2">
<a title="Hyperlink2">HyperLink2</a>
</li>
<li id="3">
<a title="Hyperlink3">HyperLink3</a>
</li>
</ul>
</div>
<input type="text" value="3" id="test"> < 10
I have simply included a rudimentary toggle() function to demonstrate the point of removing and ading the class name "jsTree-clicked". Please note that JStree assigns other classes to the node dynamically that should be kept there.
It appears to me as if the class jstree-clicked (not: jsTree-clicked) is set by JSTree after an element was clicked. You might have to play aroud with this further to get what you want.
The following might be more what you want. It will "link" to the given href only when the predefined test criteria in checkinput() is met:
$(function () { $('#myJSTree').jstree(); });
const checkinput = (e) => {
if (+$("#test").val()>=10 ) {
console.log("You entered an invalid number.")
} else document.location.href=e.target.href;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/jstree.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.2.1/themes/default/style.min.css" />
<div id="myJSTree">
<ul>
<li id="1">
<a title="Hyperlink1" href="https://jsonplaceholder.typicode.com/users/1" onclick="checkinput(event)">HyperLink1</a>
</li>
<li id="2">
<a title="Hyperlink2" href="https://jsonplaceholder.typicode.com/users/2">HyperLink2</a>
</li>
<li id="3">
<a title="Hyperlink3">HyperLink3</a>
</li>
</ul>
</div>
<input type="text" value="3" id="test"> < 10<br>
HyperLink1 will link to the page "user1" if the input is valid, <br>otherwise an eror will be shown in the console.

Looping through parent multiples times to fire correspoding child class

I have a dropdown menu and I am trying to toggle the display:block class on the ul child of the button, once that dropdown button is clicked. Currently the ul is set to display:none until the main button parent is clicked. So only the parent is shown on the screen currently.
I am having a hard time setting up these loops properly. I can set it up so when one button is clicked all the ul's for every project are shown but I only want the one under the corresponding button.
HTML:
<div class="dropdown">
<div class="project">
<button>website 1<i class="fas fa-caret-down"></i></button>
<ul class="drop-list">
<li>Live Website</li>
<li>Resources</li>
</ul>
</div>
<div class="project">
<button>Website 2<i class="fas fa-caret-down"></i></button>
<ul class="drop-list">
<li>Live Website</li>
<li>Resources</li>
</ul>
</div>
</div>
JAVASCRIPT:
const projects = document.querySelectorAll('.project')
const dropdown_lists = document.querySelectorAll('.drop-list')
projects.forEach(button => button.addEventListener('click', function(){
// Feel like I need a forEach loop here to loop through the dropdown_lists or a reg for loop
// for(i=0;i<dropdown_lists.length;i++) - maybe something like this
// then I need to classList.toggle('active') on this ul
// I'm getting stuck on how to make this in sync with the corresponding project button
}))
CSS:
.drop-list {
display: none;
}
.active {
display: block;
}
What I need is when projects[0] is clicked that toggles the class of 'active' to dropdown_lists[0] from the list.
When projects[1] is clicked that toggles the class of 'active' to dropdown_lists[1] from the list.
Again, I can set up the code so when I click one button all the ul dropdown-lists toggle the class 'active' but I only want the first button to go with the first ul and second button with the second ul.
I'm just not sure how to go about this, either make a boolean if dropdown lists === 2 and project === 2 than toggle the class. I just cant think of the best practice to do this easily.
Appreciate the help.
Thanks
I applied the toggle() method, together with the method of forEach(). In which you need to declare the variable of the current button - projects_current.
Next, .active class is assigned to <ul class="drop-list">...</ul> according to the index:
dropdown_lists[index]
const projects = document.querySelectorAll('.project')
const dropdown_lists = document.querySelectorAll('.drop-list')
projects.forEach(function (projects_current, index) {
projects_current.addEventListener('click', function () {
dropdown_lists[index].classList.toggle('active');
});
});
.drop-list {
display: none;
}
.active {
display: block;
}
<div class="dropdown">
<div class="project">
<button>website 1<i class="fas fa-caret-down"></i></button>
<ul class="drop-list">
<li>Live Website</li>
<li>Resources</li>
</ul>
</div>
<div class="project">
<button>Website 2<i class="fas fa-caret-down"></i></button>
<ul class="drop-list">
<li>Live Website</li>
<li>Resources</li>
</ul>
</div>
</div>
You could use "event delegation" to achieve the result without multiple event listeners. The basic idea is to use a click event listener on a common parent (div.dropdown) to check if a button was clicked, and if so, toggle the active class of the next sibling element.
A minimal event listener would then read like what you want to achieve:
document.querySelector(".dropdown").addEventListener( "click", event => {
if( event.target.tagName == "BUTTON") {
event.target.nextElementSibling.classList.toggle("active");
}
});
You can put an id in the dropdown to use it in the onclick of the buttons
const toggleDropdow = (dropdown) =>
document.getElementById(dropdown).classList.toggle("active");
.drop-list {
display: none;
}
.active {
display: block;
}
<div class="dropdown">
<div class="project">
<button onclick="toggleDropdow('dropdown1')">Website 1</button>
<ul id="dropdown1" class="drop-list">
<li>Live Website</li>
<li>Resources</li>
</ul>
</div>
<div class="project">
<button onclick="toggleDropdow('dropdown2')">Website 2</button>
<ul id="dropdown2" class="drop-list">
<li>Live Website</li>
<li>Resources</li>
</ul>
</div>
</div>

Javascript change effect for <ul><li> is not working correctly

I am new to Javascript. I want to click on the Navi bar to change some effect(underline to the words)
Coding for HTML
<div class="nav" id="nav">
<ul>
<li>Home</li>
<li>text1</li>
<li>text2</li>
</ul>
</div>
<div id="text1"> <!--> jump to here<-->
.....
</div>
<div id="text2"> <!--> jump to here<-->
.....
</div>
<script>
function SetTabState(dom){
$("#nav ul li").find('.underline_text').removeClass('underline_text');
$(dom).addClass('underline_text');
}
</script>
Just like the screenshot, when clicking "text1" tab, the home underline is removed and "text1" underline is added...
However, for my coding, when clicking on "text1", the underline is not changing and remain at "home". Anyone knows the problem here? Thx!
This is because from your html
<a href="index.html#text2" onclick="SetTabState(this)">
this refer to <a>, so dom is actually an <a>
From your SetTabState(dom), dom suppose to be a <li>?
You can add a event delegation to the <ul> with delegate to the <li>, like
function SetTabState(dom) {
$("#nav ul li").find('.underline_text').removeClass('underline_text');
$(dom).addClass('underline_text');
}
$(document).ready(function() {
$("#nav ul").on('click', 'li', function() {
SetTabState(this)
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav" id="nav">
<ul>
<li>Home</li>
<li>text1</li>
<li>text2</li>
</ul>
</div>
<div id="text1">
<!-->jump to here
<-->
.....
</div>
<div id="text2">
<!-->jump to here
<-->
.....
</div>
As others have said, the dom variable refers to the <a> element, but you're trying to remove the class from the <li>. Instead of using .find, you can directly select the element with the underline_text class:
<script>
function SetTabState(dom){
$("#nav ul li .underline_text").removeClass('underline_text');
$(dom).addClass('underline_text');
}
</script>
You can do like this :-
function SetTabState(dom){
$("#nav ul li a").removeClass('underline_text');
$(dom).addClass('underline_text');
}
ul {
padding: 0;
margin: 0;
list-style: none;
}
ul li a {
text-decoration: none;
}
ul li a.underline_text {
border-bottom: 1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="nav" id="nav">
<ul>
<li>Home</li>
<li>text1</li>
<li>text2</li>
</ul>
</div>
Because you need to change the state of the other elements rather than the only element you clicked, I suggest you use a function for the whole group of elements instead of handle click event on each element. This is my code:
function initClickableNav(nav) {
var navItems = nav.querySelectorAll('a');
var activeClass = 'underline_text';
nav.addEventListener('click', function (event) {
[].forEach.call(navItems, function (navItem) {
if (navItem === event.target || navItem.contains(event.target)) {
navItem.classList.add(activeClass);
} else {
navItem.classList.remove(activeClass);
}
});
});
}
initClickableNav(document.querySelector('#nav'));
HTML
<div class="nav" id="nav">
<ul>
<li><span>Home</span></li>
<li>text1</li>
<li>text2</li>
</ul>
</div>

jQuery hide elements of Widget Style ul li

I am designing a widget style using HTML ul tag.
<div class='tabs' style='width:50%'>
<ul>
<li id="basic-li"><a href='#basic_information'>Basic</a></li>
<li id="master-passenger-li"><a href='#master_passenger'>Master Passenger</a></li>
<li id="other-passenger-li"><a href='#all_passengers'>Other Passengers</a></li >
<li id="confirm-li"><a href='#confirm'>Confirmation</a></li>
</ul>
And I have 4 divs.
<div id="basic_information" class="tab">//content</div>
<div id="master_passenger" class="tab">//content</div>
<div id="other-passenger" class="tab">//content</div>
<div id="confirm" class="tab">//content</div>
I only want to show the li's href div that has currently been clicked. I only want to use HTML / CSS and jQuery.
This is the basic idea. You can improvise as per your need. I have set the target li's id as data attribute in to div where you will click. Now on click of that div i gets li's id so we can make that shown and all else li hide.
$(document).ready(function(){
$('.tab').click(function(){
$('.tabs li').hide();
var idTab = $(this).data('id');
$('#' + idTab).show();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='tabs' style='width:50%'>
<ul>
<li id="basic-li"><a href='#basic_information'>Basic</a>
</li><li id="master-passenger-li"><a href='#master_passenger'>Master Passenger</a>
</li><li id="other-passenger-li"><a href='#all_passengers'>Other Passengers</a>
</li ><li id="confirm-li"><a href='#confirm'>Confirmation</a></li>
</ul>
</div>
<div id="basic_information" data-id="basic-li" class="tab">//basic info</div>
<div id="master_passenger" data-id="master-passenger-li" class="tab">//master passenger</div>
<div id="other-passenger" data-id="other-passenger-li" class="tab">//other passenger</div>
<div id="confirm" data-id="confirm-li" class="tab">//confirm</div>
Cheers...!!
This can be achieved via the following changes to your HTML, and the addition of the jQuery script below:
<ul>
<!-- add data-target attribute to each "a", with value matching corresponding tab -->
<li>
<a data-target="basic_information" href='#basic_information'>Basic</a>
</li>
<li>
<a data-target="master_passenger" href='#master_passenger'>Master Passenger</a>
</li>
<li>
<a data-target="other-passenger" href='#all_passengers'>Other Passengers</a>
</li>
<li>
<a data-target="confirm" href='#confirm'>Confirmation</a>
</li>
</ul>
<div id="basic_information" class="tab">//content</div>
<div id="master_passenger" class="tab">//content</div>
<div id="other-passenger" class="tab">//content</div>
<div id="confirm" class="tab">//content</div>
<script>
$(function() {
// Hide all tabs by default
$('.tab').hide()
// Assign click handler to all elements with data target attribute
$('[data-target]').click(function() {
// Hide all tabs
$('.tab').hide()
// Extra target id of the menu link that was clicked
var tabToShow = $(this).data('target')
// Show the corresponding tab
$('#' + tabToShow).show()
// Return false to prevent default navigation behaviour of links
return false
})
})
</script>

Categories