Making dropdown lists run function - javascript

I have adapted some code from the W3 hoverable dropdown tutorial and want to make it so that rather than following a link when clicked, it passes a value to a function. A rough snippet of the HTML code is below:
<div class="dropdown">
<button class="dropbtn">Item</button>
<div class="dropdown-content" (change)="selectChange($event)">
<a value="egg">Egg</a>
<a value="milk">Milk</a>
</div>
</div>
I want to figure out how to get the value "egg" into the JavaScript function selectChange if the user clicks on that box, but currently, the boxes are not clickable and don't do anything. I would like to avoid using a <select> tag if possible.
Here is the W3 link I got the structure of this code from:
https://www.w3schools.com/howto/howto_css_dropdown.asp

You've tagged this with angular, so I'm assuming you're using that framework. If that's the case, just use (click)="function()".
<div class="dropdown">
<button class="dropbtn">Item</button>
<div class="dropdown-content">
<a (click)="selectChange('egg')">Egg</a>
<a (click)="selectChange('milk')">Milk</a>
</div>
</div>

Probably the best solution
How about an eventListener to all the links in the dropdown in Javascript that checks if when a link was clicked and then performs the function with the value of the element that was clicked?
Probably the easiest solution
Or maybe for just a few elements or if you don't feel like/don't know how to use an eventListener for this could always use some simple onclick events with a parameter.
function selectChange(selected)
{
//not sure what you want to do now
console.log(selected);
alert(selected);
}
.dropbtn {
background-color: #04AA6D;
color: white;
padding: 16px;
font-size: 16px;
border: none;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content span {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content span:hover {background-color: #ddd;}
.dropdown:hover .dropdown-content {display: block;}
.dropdown:hover .dropbtn {background-color: #3e8e41;}
<div class="dropdown">
<button class="dropbtn">Item</button>
<div class="dropdown-content">
<span onclick="selectChange('egg')">Egg</span>
<span onclick="selectChange('milk')">Milk</span>
</div>
</div>
*In this example a replaced the a-tags with span as you probably shouldn't use an anchor-tag without a href.

Related

How to create hoverable dropdown menu that shows selected variable

I am looking for some (probably easy) advice which I cant seem to find googling. I have a hoverable dropdown menu such as:
/* Dropdown Button */
.btn {
background-color: #D6182D;
color: white;
padding: 8px;
font-size: 16px;
border: none;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
display: inline-block;
border: 10px;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.dropdown-content a:hover {
background-color: #ddd;
}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {
display: block;
}
/* Change the background color of the dropdown button when the dropdown content is shown */
.dropdown:hover .btn {
background-color: rgb(134, 30, 42);
}
<center>
<div class="dropdown">
<a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Chose a month to display</a>
<div class="dropdown-content">
<a class="nav-link" href="/jan">
<font color="black">January 2018</font>
</a>
<a class="nav-link" href="/feb">
<font color="black">February 2018</font>
</a>
<a class="nav-link" href="/mar">
<font color="black">March 2018</font>
</a>
<a class="nav-link" href="/tot">
<font color="black">Total</font>
</a>
</div>
</div>
</center>
Basically taken from w3schools..
Now instead of "Chose a month to display" I would like to display the chosen option once someone clicks on it. Do you guys have any idea on how to change the code to do so?
Looking forward to your answers :-)
I made some changes in your HTML to make it more semantic and for dropdown text, you can try plain javascript. I hope, This will help you.
For old value, you can store your value somewhere, like in localstorage
For Example, I am saving old selected value in local storage.
const months = document.getElementsByClassName("dropdown-content");
if(localStorage.getItem("oldval")){
document.getElementById("dropdownMenuLink").innerHTML =
localStorage.getItem("oldval");
}
Array.from(months).map(month=>{
month.addEventListener("click",(e)=>{
let selectedValue = e.target.textContent;
document.getElementById("dropdownMenuLink").innerHTML =
selectedValue;
localStorage.setItem("oldval",selectedValue);
});
});
const months = document.getElementsByClassName("dropdown-content");
Array.from(months).map(month=>{
month.addEventListener("click",(e)=>{
e.preventDefault();
let selectedValue = e.target.textContent;
document.getElementById("dropdownMenuLink").innerHTML = selectedValue;
});
});
/* Dropdown Button */
.btn {
background-color: #D6182D;
color: white;
padding: 8px;
font-size: 16px;
border: none;
min-width: 200px;
display:inline-block;
text-decoration:none;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
position: relative;
display: inline-block;
border: 10px;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 200px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
list-style: none;
padding:0;
margin:0;
}
/* Links inside the dropdown */
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
/* Change color of dropdown links on hover */
.dropdown-content a:hover {
background-color: #ddd;
}
/* Show the dropdown menu on hover */
.dropdown:hover .dropdown-content {
display: block;
}
/* Change the background color of the dropdown button when the dropdown content is shown */
.dropdown:hover .btn {
background-color: rgb(134, 30, 42);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<center>
<div class="dropdown">
<a class="btn btn-secondary dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Chose a month to display</a>
<ul class="dropdown-content">
<li><a class="nav-link" href="/jan">
January 2018
</a></li>
<li><a class="nav-link" href="/feb">
February 2018
</a></li>
<li><a class="nav-link" href="/mar">
March 2018
</a></li>
<li><a class="nav-link" href="/tot">
Total
</a></li>
</ul>
</div>
</center>
</body>
</html>
as i can see you are using <div> and <a> to achieve a drop-down which is not wrong at all but is not correct way of html to do it.
Read about <select> and <option> tag which will help you to get a drop-down effect as well as you can set value inside <option> tag dynamically as you click it. by using getElementById('id-of-element')
read about getElementById here
Also if you want some redirection when user clicks it you can use <a> tag inside <option> tag.
select tag
hope this will help you, post any doubts if you have will be happy to help you :-)

Display child-element with hover, hide it when focus is lost

I have an element (dropdown-content) that is displayed when its parent (Element2) is hovered. When no interaction with the element (dropdown-content) occurs I want it to act as it does now and disappear when the hover is over. But when the element gets focus (the select or input or somewhere else in the dropdown-content are clicked) I want it to stay displayed until it loses focus (clicked somewhere outside the dropdown-content), even when the coursor leaves the dropdown-content.
I have already tried to find a solution with the search and several things using CSS and/or javascript but was not able to archive what I want. Here is an example code to illustrate my problem:
.dropdown-content {
display: none;
position: absolute;
border: 1px solid black;
width: 300px;
z-index: 1;
}
.dropdown:hover .dropdown-content,
.dropdown-content:focus {
display: inline-block;
}
<ul>
<li>Element1</li>
<li class="dropdown">
<span>Element2</span>
<div class="dropdown-content">
<select>
<option>option1</option>
<option>option2</option>
</select>
<input type="text">
</div>
</li>
<li>Element3</li>
</ul>
I would prefer a CSS solution if there is a clean one but I am also fine with javascript, but I don't want a JQuery solution if this is possible. If this makes the solution way easier it would be also fine if the dropdown-contet just stays displayed when there is focus on the select and input only.
You don't need Javascript let alone jQuery for that. It can and should be done with pure CSS with the pseudo-class :focus-within.
.dropdown-content {
display: none;
position: absolute;
border: 1px solid black;
margin: -3px 0 0 3px;
}
.dropdown:hover .dropdown-content, .dropdown-content:focus-within {
display: inline-block;
}
<ul>
<li>Element1</li>
<li class="dropdown">
<span>Element2</span>
<div class="dropdown-content">
<select>
<option>option1</option>
<option>option2</option>
</select>
<input type="text">
</div>
</li>
<li>Element3</li>
</ul>

Removing Class Using Javascript

I'm trying to teach myself a little javascript for project I am working on and just wanted to see if I could get some help. I use 3 different drop down menus and I use the below function to hide one menu when another is clicked. It worked
function DropDownMenuNavigation() {
document.getElementById("DropDownMenuNav").classList.toggle("show");
document.getElementById('DropDownMenuChart').classList.remove('show');
}
The above code worked well when I had 2 different drop down menus. But now that I have 3 it doesn't seem to see the 3 line I've added below.
function DropDownMenuNavigation() {
document.getElementById("DropDownMenuNav").classList.toggle("show");
document.getElementById('DropDownMenuChart').classList.remove('show');
document.getElementById('DropDownMenuCat').classList.remove('show');
}
If I switch the bottom line with the middle line it will regonize that line, I'm guessing there is something wrong with the format I'm writing it in? Something tells me I'm not including a separator or something. Anyways, I know its something small, maybe someone could point it out to me.
EDIT:
JAVASCRIPT
<script>
function DropDownMenuNavigation() {
document.getElementById("b2DropDownMenuNav").classList.toggle("show");
document.getElementById("b2DropDownMenuCat").classList.toggle("remove");
document.getElementById("b2DropDownMenuCha").classList.toggle("remove");
}
function DropDownMenuCategory() {
document.getElementById("b2DropDownMenuCat").classList.toggle("show");
document.getElementById("b2DropDownMenuNav").classList.toggle("remove");
}
function DropDownMenuCharts() {
document.getElementById("b2DropDownMenuCha").classList.toggle("show");
document.getElementById("b2DropDownMenuNav").classList.toggle("remove");
}
</script>
HTML
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuNavigation()" class="dropbtn">☰ MENU</button>
</div>
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuCategory()" class="dropbtn">CATEGORIES</button>
</div>
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuCharts()" class="dropbtn">CATEGORIES</button>
</div>
<div class="dropdown">
<div id="b2DropDownMenuCategory" class="dropdown-content">
1
</div>
</div>
<div class="dropdown">
<div id="b2DropDownMenuCharts" class="dropdown-content">
2
</div>
</div>
<div class="dropdown">
<div id="b2DropDownMenuNavigation" class="dropdown-content">
3
</div>
</div>
CSS
/* Dropdown Button */
.dropbtn {
background-color: #0066a2;
color: white;
padding: 1px;
font-size: 15px;
font-weight: bold;
border: none;
cursor: pointer;
}
.dropbtn a {
color: #FFFFFF;
text-decoration: none;
font-size: 15px;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
float: left;
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #0066a2;
min-width: 260px;
max-width: 960px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: #000000;
text-decoration: none;
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {display:block;}
The code you posted has mismatches between the actual ids of the content and the document.getElementById() lines, but assuming that you correct that, your code does in fact work, but each bit of content just winds up going under the other, so you never see the correct content.
function DropDownMenuNavigation() {
document.getElementById("b2DropDownMenuNav").classList.toggle("show");
document.getElementById("b2DropDownMenuCat").classList.toggle("remove");
document.getElementById("b2DropDownMenuCha").classList.toggle("remove");
}
function DropDownMenuCategory() {
document.getElementById("b2DropDownMenuCat").classList.toggle("show");
document.getElementById("b2DropDownMenuNav").classList.toggle("remove");
}
function DropDownMenuCharts() {
document.getElementById("b2DropDownMenuCha").classList.toggle("show");
document.getElementById("b2DropDownMenuNav").classList.toggle("remove");
}
/* Dropdown Button */
.dropbtn {
background-color: #0066a2;
color: white;
padding: 1px;
font-size: 15px;
font-weight: bold;
border: none;
cursor: pointer;
}
.dropbtn a {
color: #FFFFFF;
text-decoration: none;
font-size: 15px;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
float: left;
position: relative;
display: inline-block;
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #0066a2;
min-width: 260px;
max-width: 960px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
/* Links inside the dropdown */
.dropdown-content a {
color: #000000;
text-decoration: none;
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show {display:block;}
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuNavigation()" class="dropbtn">☰ MENU</button>
</div>
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuCategory()" class="dropbtn">CATEGORIES</button>
</div>
<div class="dropbtn" style="float: left;">
<button onclick="DropDownMenuCharts()" class="dropbtn">CATEGORIES</button>
</div>
<div class="dropdown">
<div id="b2DropDownMenuCat" class="dropdown-content">
1
</div>
</div>
<div class="dropdown">
<div id="b2DropDownMenuCha" class="dropdown-content">
2
</div>
</div>
<div class="dropdown">
<div id="b2DropDownMenuNav" class="dropdown-content">
3
</div>
</div>
But, since you are new to this, it's best not to start off with bad habits, so don't use inline HTML event attributes (i.e. onclick, etc.), there are many reasons why and you can review them here.
Next, you have a lot of unneeded HTML and the structure of the HTML should be altered to represent the hierarchy of the content.
Also, you don't need separate functions for each menu click as trying to keep track of what should be hidden and what should be shown in an ever-increasing list of menu items is not a scaleable result.
When these changes are made, the HTML is much cleaner and less involved and the JavaScript is also much simpler:
// First, get references to the HTML elements your code will need.
// You could get individual references, like this:
/*
var b2DropDownMenuNav = document.getElementById("b2DropDownMenuNav");
var b2DropDownMenuCat = document.getElementById("b2DropDownMenuCat");
var b2DropDownMenuCha = document.getElementById("b2DropDownMenuCha");
*/
// But in your case, a single reference to the collection of menus will do.
// We'll also want that collection to be converted to a JavaScript array.
var menus = Array.prototype.slice.call(document.querySelectorAll(".dropbtn"));
// Now, we can just loop over the array and give the buttons a common function
// to perform when they are clicked (no need for multiple functions.
menus.forEach(function(menu){
menu.addEventListener("click", function(){
// Hide any currently showing menu content
Array.prototype.slice.call(document.querySelectorAll(".dropdown-content")).forEach(function(content){
content.classList.remove("show");
});
// Show the content of the menu that was clicked:
menu.querySelector(".dropdown-content").classList.toggle("show");
});
});
/* Dropdown Button */
.dropbtn {
background-color: #0066a2;
color: white;
padding: 1px;
font-size: 15px;
font-weight: bold;
border: none;
cursor: pointer;
float:left; /* no need to write this inline with the HTML, just put it here */
}
.dropbtn a {
color: #FFFFFF;
text-decoration: none;
font-size: 15px;
font-weight: bold;
}
/* The container <div> - needed to position the dropdown content */
/* I can't see any need for this class at all:
.dropdown {
float: left;
position: relative;
display: inline-block;
}
*/
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
background-color: #0066a2;
min-width: 260px;
max-width: 960px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
position: absolute;
/* z-index: 1; <-- NOT NEEDED */
}
/* Links inside the dropdown */
.dropdown-content a {
color: #000000;
text-decoration: none;
}
/* Show the dropdown menu (use JS to add this class to the .dropdown-content container when the user clicks on the dropdown button) */
.show { display:block; }
<!-- There is no need to nest button elements inside of div elements.
Just get rid of the buttons completely and make the divs the clickable
elements. -->
<div class="dropbtn" id="b2DropDownMenuNav">☰ MENU
<div class="dropdown dropdown-content">1</div>
</div>
<div class="dropbtn" id="b2DropDownMenuCat">CATEGORIES
<div class="dropdown dropdown-content">2</div>
</div>
<div class="dropbtn" id="b2DropDownMenuCha">CATEGORIES
<div class="dropdown dropdown-content">3</div>
</div>

How to trigger mouse hover event on anchor tags of drop down list

.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover,
.dropbtn:focus {
background-color: #3e8e41;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #0000FF;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
.dropdown-content a {
color: white;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {
background-color: #ff0000
}
.show {
display: block;
<div class="dropdown">
<button id="myButton" onclick="PrintHello()" class="dropbtn">click</button>
<div id="myDropdown" class="dropdown-content">
<a class="link" id="Home" href="#home">Home</a>
<a class="link" id="About1" href="#about">About</a>
<a class="link" id="Contact" href="#contact">Contact</a>
</div>
</div>
I'm trying to trigger mouse 'hover' event on one of the anchor tag when the drop down menu pop-ups,
I'm using:
$("#About1").trigger('hover');
It doesn't trigger any event. I have written some event handler for anchor tag for "hover"event. When I use:
$("#About1").trigger('mouseover');
it calls the event handler but there is no hover effect seen on the web page. I was expecting it to be hovered as same as when you physically hover the mouse on it.
Am I missing something? Is it possible to create such effects by triggering the events? Please do suggest a solution.
You can just use hover() DEMO
$('button, #myDropdown').hover(function() {
$('#myDropdown').toggleClass('show');
})
Or you can trigger custom event on when you hover (mouseenter) over element DEMO
$('#About1').mouseenter(function() {
$(this).trigger('customEvent');
});
$('#About1').on('customEvent', function() {
alert('Lorem Ipsum');
});
If you try to change styles only it's better to use selector :hover in css.
If you require anything else use hover: $('selector').hover(functionOnHover,FunctionOnHoverOut);
If you want to trigger mouse hover event on drop down items like for example "About" without physically hovering the mouse on it, you can add
$(document).ready(function(){
$("#About1").trigger('mouseenter');
});
DEMO

Is it possible to run a js function by means of a dropdown CSS menu?

original post
Is it possible to run a js function by means of a dropdown CSS menu ?
I would realize a menu, looking like the habitual navigational ones, but aimed, instead, to run a different javascript function on each item, or, I think it's the same thing, to pass a different argument to a function and run it.
Is it practicable ? Googling, I pick the opposite (dropdown menu via js) ...
addendum
Thanks to the advice provided by some courteous members, I have solved my problem, attaching an event handler to each item of the menu. Therefore I post here the code. Thanks again.
<HTML>
<HEAD>
<TITLE></TITLE>
<style>
<!--http://www.w3schools.com/css/css_dropdowns.asp-->
.dropbtn {
background-color: #4CAF50;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {background-color: #f1f1f1}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown:hover .dropbtn {
background-color: #3e8e41;
}
#myvar{
margin-top: 200px;
}
</style>
<script type="text/javascript">
function setVar(arg){
document.getElementById("myvar").innerHTML = arg;
}
</script>
<script>
var x = 0;
</script>
</HEAD>
<BODY onLOad="setVar(x)">
<div class="dropdown">
<span>menu</span>
<div id = "menudd" class="dropdown-content">
<p onClick="setVar(1)">item 1</p>
<p onClick="setVar(2)">item 2</p>
<p onClick="setVar(3)">item 3</p>
</div>
</div>
<p onClick="setVar(3)">again 3</p>
<P id="myvar"></P>
</BODY>
</HTML>
I don't know what you mean by a "CSS menu". You don't create menus with CSS; you create them with HTML. You use CSS to style them and make them look menu-like.
All HTML-based web applications are based on attaching behaviors (implemented in JS) to HTML elements (such as buttons or menu items).
Attach an event handler for the click event to the HTML element that represents a particular menu item, and provide whatever function you want to execute.

Categories

Resources