JQuery on click <li> interference - javascript

Ok, the problem is a little hard to explain but I'll do my best.
when I click on one <li> element everyone else inside him is clicked.
I try to create categories and subcategories.but whenever I click on a category a subcategory is also called!
<li class="has-sub product_type" id="category1"> <a>Lorem1</a>
<ul>
<li class="product_sub_type" id="subcategory1"><a>Lorem2</a></li>
<li class="product_sub_type" id="subcategory2"><a>Lorem2</a></li>
<li class="product_sub_type" id="subcategory3"><a>Lorem2</a></li>
<li class="product_sub_type" id="subcategory4"><a>Lorem2</a></li>
</ul>
</li>
$(document).ready(function(){
var type_id = '';
$(".all_products").fadeOut("fast");
$(".product_type").on("click", function(event) {
alert("Dbg");
type_id = event.currentTarget.id;
$(".big_categoryes").fadeOut("fast");
$(".all_products").fadeIn("smooth");
sortProducts(type_id);
});
var type_sub_id = '';
$(".product_sub_type").on("click", function(event) {
type_sub_id = event.currentTarget.id;
sortSubProducts(type_sub_id);
});
});

Related

How to make JS code accept multiple similar IDs

I have the JS code below that I use with the form after it. However, it only calls the first dropdown and ignores the rest. The dropdown are generated by Hugo (SSG) and I all share the same ID/class in the menu. I need help to make the code work for multiple dropdown menus.
document.getElementById("dropbtn").addEventListener('click', function() {
document.getElementById("sub-menu").classList.toggle("show");
var x = document.getElementById("dropbtn").getAttribute("aria-expanded");
if (x == "true")
{
x = "false"
} else {
x = "true"
}
document.getElementById("dropbtn").setAttribute("aria-expanded", x);
});
// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("sub-menu");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
<nav>
<ul>
<li class="dropdown" id="dropdown">
<a id="dropbtn" class="dropbtn" href="#" aria-expanded="false">Toggle<span class="drop-icon" for="toggle">▾</span></a>
<ul id="sub-menu" class="sub-menu">
<li>
A
</li>
<li>
B
</li>
<li>
<a href="/c/" >C</a>
</li>
</ul>
</li>
<li class="dropdown" id="dropdown">
<a id="dropbtn" class="dropbtn" href="#" aria-expanded="false">Dropdown <span class="drop-icon" for="dropdown">▾</span></a>
<ul id="sub-menu" class="sub-menu">
<li>
D
</li>
<li>
E
</li>
<li>
F
</li>
</ul>
</li>
</ul>
</nav>
It's not reccomended to use multiple id's with the same name.
Here's my solution for your case.
<nav>
<ul>
<li class="dropdown">
<a class="dropbtn" aria-expanded="false" href="#">Toggle<span class="drop-icon">▾</span></a>
<ul class="sub-menu">
<li>
A
</li>
<li>
B
</li>
<li>
C
</li>
</ul>
</li>
<li class="dropdown">
<a class="dropbtn" aria-expanded="false" href="#">Dropdown <span class="drop-icon">▾</span></a>
<ul class="sub-menu">
<li>
D
</li>
<li>
E
</li>
<li>
F
</li>
</ul>
</li>
</ul>
</nav>
<script>
let dropbtns = document.getElementsByClassName('dropbtn');
for (let dropbtn of dropbtns) {
dropbtn.onclick = () => {
dropbtn.nextElementSibling.classList.toggle('show');
let expanded = dropbtn.getAttribute('aria-expanded');
dropbtn.setAttribute('aria-expanded', expanded == 'true' ? 'false' : 'true');
};
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function (event) {
if (!event.target.matches('.dropbtn')) {
let dropbtns = document.getElementsByClassName('dropbtn');
for (let dropbtn of dropbtns) {
dropbtn.nextElementSibling.classList.remove('show');
dropbtn.setAttribute('aria-expanded', 'false');
}
}
};
</script>
So, first of all. There can only be one unique ID per page, so your HTML is now invalid. You will have to have different IDs on your HTML elements (if you still need them at all). Below JS hopefully should work.
const dropdownTriggers = document.querySelectorAll('.dropbtn');
[...dropdownTriggers].forEach((trigger) => {
trigger.addEventListener('click', (e) => {
const triggerClicked = e.target;
const dropdownMenu = triggerClicked.nextElementSibling;
const isDropdownShown = Boolean(triggerClicked.getAttribute('aria-expanded'));
dropdownMenu.classList.toggle('show', !isDropdownShown);
triggerClicked.setAttribute('aria-expanded', isDropdownShown);
})
})
document.addEventListener('click', (e) => {
if (!event.target.matches('.dropbtn')) {
[...dropdownTriggers].forEach((trigger) => {
const dropdownMenu = trigger.nextElementSibling;
dropdownMenu.classList.toggle('show', false);
trigger.setAttribute('aria-expanded', false);
})
}
});

Select current link in menu

I'm using MentisMenu for my site, and I'm trying to get the active menu selection to be set to active. I can get the Menu and submenus to activate and expand, but the actual link selected will not be marked active. Anyone?
const currentLinkParents = currentLink => {
let target = currentLink
let parent = []
while (target) {
// Get only nav-link
if (target.classList.contains('nav-item')) parent.unshift(target.querySelector('.nav-link'))
// Stop on treeview
if (target.classList.contains('treeview')) break
target = target.parentNode
}
return parent
}
const updateMenu = currentLink => {
document.querySelectorAll('#menu .active').forEach(i => i.classList.remove('active', 'show'))
for (const i of currentLinkParents(currentLink)) {
i.classList.add('active')
i.classList.contains('treeview-toggle') && i.classList.add('show')
}
}
updateMenu(document.querySelector(`#menu a[href="${window.location.pathname.split('/').pop()}"]`))
Sample HTML here:
<li class="nav-item">
<a class="nav-link has-icon treeview-toggle" href="#"><i class="material-icons">construction</i>Engineering</a>
<ul class="nav">
<li>Active Renovations</li>
<li>Maintenance Requests</li>
<li>Projects</li>
<li>Recurring Events</li>
<li class="nav-item">
Inventories
<ul class="nav">
<li>Stock Inventory</li>
<li>Master Keys</li>
</ul>
</li>
</ul>
</li>
In this example, if I select "Master Keys" then the menus Engineering and Inventories both expand and are set to active, but the Master Keys selection is not marked active.
Hope someone can help!
Turns out the following line after the call to updateMenu() fixes it:
document.querySelector(#menu a[href="${window.location.pathname.split('/').pop()}"]).classList.add('active');

Is it possible to find out the id of the element mouse is curently pointing at (not clicking) with only javascript, no libraries? [duplicate]

This question already has answers here:
Getting id of any tag when mouseover
(3 answers)
Closed 4 years ago.
I have few separate elements in my html page right next to each other.
I want to show certain content while mouse is on one of those elements, and hide it when mouse moves away from them.
If I just use mouseon/mouseout events, I get some flickering on content i want to show when i move the mouse between correct elements.
For solution I figured i could create an aray of correct element ID's and then check if mouse is pointing at any of array's elements. But can't find a way to get element's id without clicking it.
So is it possible to get the id of the element mouse is curently hovering or pointing at without jquery or other libraries?
HTML part:
<div id="navigationBarContainer">
<ul id="navigationBarList">
<li>Naujienos</li>
<li id="dropDownBarControl">Veikla
<ul id="dropDownBar" class="hideList">
<li id="preschool" class="hide">Pradine</li>
<li id="middleschool" class="hide">Pagrindine</li>
<li id="highschool" class="hide">Abiturientai</li>
<li id="grownups" class="hide">Suauge</li>
<li id="conferences" class="hide">Konferencijos</li>
<li id="other" class="hide">Teminiai</li>
</ul><!--end of dropDownBar-->
</li>
<li>Kainorastis</li>
<li>Registracija
<ul>
<li id="forStudents" class="hide">Mokiniams</li>
<li id="forGrownups" class="hide">Suaugusiems</li>
</ul><!--end of dropDownBar-->
</li>
<li>Kontaktai</li>
</ul><!--end of navigationBarList-->
</div><!--end of navigationBarContainer-->
and Javascript:
function showItem(name){//make item visable
document.getElementById(name).classList.remove("hide");
}
function hideItem(name){//make item hidden
document.getElementById(name).classList.add("hide");
}
document.getElementById('dropDownBarControl').addEventListener("mouseover", function(){
document.getElementById('dropDownBar').classList.replace("hideList", "showList");
var links = ["preschool","middleschool","highschool","grownups","conferences","other"];
var time = 0;
links.forEach(function(element){
time = time + 20;
setTimeout(function(){
showItem(element);
}, time);
});
});
document.getElementById('dropDownBar').addEventListener("mouseout", function(){
document.getElementById('dropDownBar').classList.replace("showList", "hideList");
var links = ["other","conferences","grownups","highschool","middleschool","preschool"];
var time = 0;
links.forEach(function(element){
time = time + 20;
setTimeout(function(){
hideItem(element);
}, time);
});
});
Listens to mouse move and tracks when the underlying element changes.
uses document.elementAtPoint(x,y);
let element = undefined;
document.addEventListener('mousemove', (event) => {
let x = event.pageX;
let y = event.pageY;
let newElement = document.elementFromPoint(x,y);
if(!element || element !== newElement) {
element = newElement;
console.log(element.id||element);
}
});
<div id="navigationBarContainer">
<ul id="navigationBarList">
<li>Naujienos</li>
<li id="dropDownBarControl">Veikla
<ul id="dropDownBar" class="hideList">
<li id="preschool" class="hide">Pradine</li>
<li id="middleschool" class="hide">Pagrindine</li>
<li id="highschool" class="hide">Abiturientai</li>
<li id="grownups" class="hide">Suauge</li>
<li id="conferences" class="hide">Konferencijos</li>
<li id="other" class="hide">Teminiai</li>
</ul><!--end of dropDownBar-->
</li>
<li>Kainorastis</li>
<li>Registracija
<ul>
<li id="forStudents" class="hide">Mokiniams</li>
<li id="forGrownups" class="hide">Suaugusiems</li>
</ul><!--end of dropDownBar-->
</li>
<li>Kontaktai</li>
</ul><!--end of navigationBarList-->
</div><!--end of navigationBarContainer-->

JQUERY getting ID value of LI element from nested ul

HTML code
<ul id='orgCat'>
<li parent-id="0" li-id="16">Anthropology Department</li>
<li parent-id="16" li-id="18">Anthropology Faculty Collections</li>
<li parent-id="16" li-id="23">Shared Collections</li>
<li parent-id="0" li-id="19">Center for Research on Vermont</li>
<li parent-id="19" li-id="24">Collections for Testing</li>
<li parent-id="24" li-id="25">Geology Department</li>
</ul>
Jquery
jQuery(function($){
var $ul = $('ul');
$ul.find('li[parent-id]').each(function () {
$ul.find('li[parent-id=' + $(this).attr('li-id') + ']').wrapAll('<ul />').parent().appendTo(this)
});
});
//to get li-id on double click
$('#orgCat li').dblclick(function(){
alert($(this).attr('li-id'));
})
Problem is
When double click on 'li' element its showing parents 'li-id' also but it should return only current list 'li-id'. Jsfiddle
You need to use e.stopPropagation to stop event bubbling.
$('#orgCat li').dblclick(function(e){
e.stopPropagation();
alert($(this).attr('li-id'));
});
Check this link for more information.

Jquery convert dropdown to select with onchange event

I want to convert a drop down
<ul class="cat-items selectdropdown">
<li class="cat-item cat-item-25">
A-1 Compressor
</li>
<li class="cat-item cat-item-207">
World Hand Dryer
</li>
</ul>
To select menu dynamically. Here is what I am using and it looks perfectly. But The conversion is not being made and drop down is displayed instead of select.Here is jquery code which loads on ready.
$('ul.selectdropdown').each(function() {
var list = $(this),
select = $(document.createElement('select')).insertBefore($(this).hide());
$(select).attr("style","cursor:pointer;display: inline-block; width:99%;");
$('>li', this).each(function() {
var ahref = $(this).children('a'),
target = ahref.attr('target'),
option = $(document.createElement('option')).appendTo(select).val(ahref.attr('href')).html(ahref.html());
});
});
Once select is displayed I will use onchange to make it work.
$('select').bind('change',function () {
//Redirect Page
});
Any help would be appreciated. Here id demo url:restaurantapplianceparts.com
Ahmar.
I used your code with some changes to get this to work.
HTML
<ul class="cat-items selectdropdown">
<li class="cat-item cat-item-25">
A-1 Compressor
</li>
<li class="cat-item cat-item-207">
World Hand Dryer
</li>
</ul>
Javascript
$('ul.selectdropdown').each(function() {
var list = $(this),
select = $(document.createElement('select')).insertBefore($(this).hide());
$(select).attr("style","cursor:pointer;display: inline-block; width:99%;");
$('>li', this).each(function() {
var ahref = $(this).children('a'),
target = ahref.attr('target'),
option = $(document.createElement('option')).appendTo(select).val(ahref.attr('href')).html(ahref.html());
});
$(select).change(function() {
window.location.href = $(this).find('option:selected').val();
});
});
jsFiddle: http://jsfiddle.net/Cf7Pt/1/
Your code is working fine in jsfiddle. i updated your code.
<div id="dropdown">
<ul class="cat-items selectdropdown">
<li class="cat-item cat-item-25">
A-1 Compressor
</li>
<li class="cat-item cat-item-207">
World Hand Dryer
</li>
</ul>
createSelectBox();
function createSelectBox() {
var select = $('<select>');
$('ul.selectdropdown li').each(function() {
var anchor = $(this).find('a')
var option = $('<option>');
option.val(anchor.attr('href')).text(anchor.text());
select.append(option);
});
$('#dropdown').html(select);
}
Demo here
.live is deprecated since.. I don't even remember.
use .on. http://api.jquery.com/on/
also take a look at http://getbootstrap.com/ and use it's dropdown script.
don't reinvent the wheel.
creating a select menu for navigation is also bad practice.

Categories