Menu with ajax load not working properly - javascript

I create a menu with ajax load. I have 4 zones and each zone have states. What i want is on hover on zone, i need to display all states in that zone. I write following code
HTML
<ul class="zoneLevel">
<li id="1" onmouseover="get_states_list(this.id);">East Zone
<span id="stateContainer" style="display:none;">States</span>
</li>
<li id="2">West Zone</li>
<li id="3">North Zone</li>
<li id="4">South Zone</li>
</ul>
JAVASCRIPT
<script>
function get_states_list(zone_id) {
//alert(zone_id);
var last_slug_a1 = $(".homeLeftContainer .single:last").attr("id");
$('span#stateContainer').html('<img src="img/loader.gif">');
$.post("modules/frontend/ajax/load_state.php?action=get&zone_id="+zone_id,
function(data){
if (data != "") {
$("span#stateContainer").html(data);
}
});
$(".stateContainer").css("display", "block");
$(".stateHederMenu").css("display", "block");
}
</script>
everything's good.
Problem started when i mouse hover to state (which i get with ajax file), it again call get_states_list(this.id) function. Can you please point the error.

It's because again you are hovering the li, the actual span is inside the li and hence the function is triggered again. So just use another tag maybe <a>,<p>,<span> or anything after li and close the word. so it wont trigger again unless you mouse over to the word.
<ul class="zoneLevel">
<li id="1" >
<a onmouseover="get_states_list(this.id);">East Zone</a>
<span id="stateContainer" style="display:none;">
States
</span>
</li>
<li id="2">West Zone</li>
<li id="3">North Zone</li>
<li id="4">South Zone</li>
</ul>

Example with jQuery
$('.zoneLevel li').one('mouseover',function (){
get_states_list($(this).attr('id'));
})
And fiddle for this situation fiddle

Related

I need help hiding an element when hovering over another non child/parent/sibling element

I'm a beginner when it comes to javascript and I'm trying to write a script to hide a class when I hover over another class. I've written this piece of code however it isn't working as I'd like it to.Could someone give me some pointers as to why this code isn't working and some advice on how to get it to achieve the results I'm looking for.
$(document).ready( function () {
"use strict";
document.getElementsByClassName('nav-bar').onmouseover = function(){
document.getElementsByClassName('site-title').style.display="none";
};
document.getElementsByClassName('nav-bar').onmouseout = function(){
document.getElementsByClassName('site-title').style.display="inline";
};
});
edit
#Jonas
$(document).ready( function () {
"use strict";
document.getElementsByClassName('nav-bar').forEach(function(el){el.onmouseover = function(){
document.getElementsByClassName('site-title').forEach(function(el){el.style.display="none";}
);
};
}
);
document.getElementsByClassName('nav-bar').forEach(function(el){el.onmouseout = function(){
document.getElementsByClassName('site-title').forEach(function(el){el.style.display="inline";});
};});
});
this is your adapted code. I'm not sure why it isn't working have i done it correctly?
edit 2
<body>
<Header>
<div class="navigation-wrap">
<div class="logo"><img src="../images/logo2.jpg" alt="Lewis Banks Logo" title="Lewis Banks & Sons Ltd"></div>
<div class="navigation">
<nav class="nav-menu">
<ul class="clearfix" >
<li class="nav-button"><a class="nav-bar" href="../index.html">Home</a></li>
<li class="nav-button">
<a id="product-button">Products</a>
<ul id="product-list">
<li class="menu-dropdown2"> AC
<ul id="AC-sublist">
<li class="dropdown-content"><a href="../CSW1-Switch.html">CSW1 Switch (15mm)<a>
</li>
<li class="dropdown-content"><a href="../CSW2-Switch.html">CSW2 Switch (20mm)<a>
</li>
<li class="dropdown-content"><a href="../CSW10-Switch.html">CSW10 Switch (30mm)<a>
</li>
</ul>
</li>
<li class="menu-dropdown2"><a href="../DC-Products.html" >DC</a>
<ul id="DC-sublist">
<li class="dropdown-content"><a href="../Cartridge-Brush-Holders.html">Cartridge Brush Holders<a>
</li>
<li class="dropdown-content">Brush Holder Caps
</li>
<li class="dropdown-content">Extruded Brush Holders
</li>
<li class="dropdown-content">Pressed Brass Brush Holders</li>
<li class="dropdown-content">Aluminium Brush Rockers
</li>
<li class="dropdown-content">Pressed Brass Brush Rockers</li>
<li class="dropdown-content">Tachometer Brush Rocker
</li>
<li class="dropdown-content">Carbon Brushes
</li>
<li class="dropdown-content">Constant Force Springs
</li>
</ul>
</li>
</ul>
</li>
<li class="nav-button"><a class="nav-bar" href="../Applications.html">Applications</a></li>
<li class="nav-button"><a class="nav-bar" href="../Old-and-New.html">Old & New</a></li>
<li class="nav-button"><a class="nav-bar" href="../About-Us.html">About Us</a></li>
</ul>
</nav>
</div>
</div>
</Header>
<div class="site-title">
<h1>Lewis Banks & Sons</h1>
<h3><q>Labor Omnibus Unus</q></h3>
<h4><i>Company motto since 1916</i></h4>
</div>
</body>
This is my html code, I apologize in advanced for the confusing state it is in this is the first website i've ever tried to to make and I've had to do a lot of trial and error and other acts of desperation when i came unstuck.
I have a top menu bar which has submenu's. I managed to do that using CSS.
The problem i have is as i hover over the sub-menus they overlap with the site title which makes the page look ugly. I don't want to move the site titel down so instead i'd like to remove it whenever you hover over the initial menu buttons. I want to to do this whilst maintaining the page structre (ie there's whitespace where the tite was).
It seems you are using jQuery. Why not use jQuery selectors and methods to achieve your goal. It is easier to read and understand. Take a look at the following pages for more information:
http://api.jquery.com/on/
https://api.jquery.com/mouseover/
https://api.jquery.com/mouseout/
Try this for example:
$(document).ready( function () {
$(document).on('mouseover', '.nav-bar', function() {
jQuery('.site-title').css('display', 'none');
});
$(document).on('mouseout', '.nav-bar', function() {
jQuery('.site-title').css('display', 'inline-block');
});
});
GetElementsByClassName returns a HTMLCollection. You need to loopover, and add to each:
document.getElementsByClassName('nav-bar').forEach(function(el){el.onmouseover = function(){
document.getElementsByClassName('site-title').forEach(function(el){el.style.display="none";});
};});
Like Dais mentioned in his answer, it looks like you are using jQuery so why not use the built in jQuery mouse events. Either that or you copied your code from somewhere and didn't realize that $ is a shortcut for jQuery and for your javascript to work you need to include jQuery. To include jQuery you need a statment similar to below in your html. This will include jQuery from google's content delivery network (CDN). There are other CDN's available including ones directly from jQuery.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
https://api.jquery.com/category/events/mouse-events/
Below is a working example using jQuery events and selectors.
$(document).ready(function() {
"use strict";
$('#site-title').mouseover( function() {
$('#site-title').hide(500);
});
$('#nav-bar').mouseleave( function() {
$('#site-title').show(500);
});
});
#site-title {
position:absolute;
background:red;
width:100%;
height:50px;
}
#nav-bar {
position:absolute;
background:green;
width:100%;
height:50px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav id="nav-bar">I am the nav bar
<button>Nav1</button>
<button>Nav2</button>
<button>Nav3</button>
</nav>
<header id="site-title">I am the site title</header>

jQuery Animated List - Cant click nested items

I'm trying to create an animated nested list using jQuery Animations but I'm not sure what the best way to go about solving this problem is.
The way I've been doing this is by changing the length of the parent list-item and then making the nested list items visible.
The problem is that the length of the parent list item covers the nested list-items. I want to be able to click on a nested list item (such as Edit Profile, Add Music, Playlists, etc) and have it perform something else. For now, I'm trying to just get alerts to prompt to the screen for testing.
HTML
<div id="sidebar-menu" class="col-md-12">
<ul>
<li class="sidebar-menu-item" data-length="2"><span id="IWantToClickHere">Profile</span>
<ul class="blue-special sublist">
<li>Edit Profile</li>
<li>Other</li>
</ul>
</li>
<li class="sidebar-menu-item" data-length="2">Library [<span class="purple-special">3537</span>]
<ul class="blue-special sublist">
<li>Add Music</li>
<li>Playlists</li>
</ul>
</li>
<li class="sidebar-menu-item" data-length="0">Friends</li>
<li class="sidebar-menu-item" data-length="0">Stations</li>
<li></li>
<li class="sidebar-menu-item" data-length="0">Settings</li>
<li class="sidebar-menu-item" data-length="0">Logout</li>
</ul>
</div>
JS
$(document).ready(function() {
$('.sidebar-menu-item').click(function() {
//When: Menu is opened,
if ($(this).hasClass('opened-menu-item')) {
$(this).removeClass('opened-menu-item');
//Reset Menu-Item to default height of 20px per menu-item
$(this).animate({
height: "20px"
},
1000,
//Hide nested content
function() {
$(this).find('.sublist').css('display', 'none');
});
} else {
//When: Menu is closed
$(this).addClass('opened-menu-item');
$(this).find('.sublist').css('display', 'inherit');
//Set Menu-Item length to be the number of nested li * 35
var animateHeight = Number($(this).data("length")) * 35;
if (animateHeight != 0) {
$(this).animate({
height: animateHeight + "px"
},
1000);
}
}
});
});
I put together a simple jsfiddle here: http://jsfiddle.net/W4Km8/8065/
Use event.stopPropagation()
http://jsfiddle.net/W4Km8/8066/
$('.blue-special.sublist').click(function(e){
alert('click');
e.stopPropagation();
})
This prevents the click event from "bubbling" up to the parent. Without this function, an alert would fire, but the parent list would also close.

How to get the value of data attribute using jquery

I am working on a node.js application which generates a html page. This html page displays a list of associates built according to the data passed onto this page. A list is built something like as follows:
<ul class="notification-body" style="">
//loop for all assocaite id's passed to this page
<li class="testClass" data-associateid="<%= assocID %>">
<span>
<span class="subject">
<label class="btnClass label label-info">ClickMe!</label>
</span>
</span>
</li>
The generated html src looks something like this:
<ul class="notification-body" style="">
<li class="testClass" data-associateid="AA01">
<li class="testClass" data-associateid="AA02">
<li class="testClass" data-associateid="AA03">
I am trying to get the value of the data attribute using Jquery & I tried the following:
$(".btnClass").click(function(){
console.log($".testClass").attr("data-associateid"));
});
But this outputs'AA01'everytime i click on the btn and I am not getting the expected output in the console:
AA01
AA02
AA03
I tried the following also but it gives me undefined:
$(".btnClass").click(function(){
console.log($(this).find(".testClass").attr("data-associateid"));
});
You need to use jQuery.data().
I've created a jsFiddle to show this working.
I've closed the LI because AR.
<ul class="notification-body" style="">
<li class="testClass" data-associateid="AA01">1</li>
<li class="testClass" data-associateid="AA02">2</li>
<li class="testClass" data-associateid="AA03">3</li>
</ul>
Here's the JavaScript:
$(document).ready(function() {
$('.testClass').on('click', function(){
alert( $(this).data('associateid') );
});
});
Anytime you have an attribute that starts with data-, you can reference the string after the dash as a data container. Here, I'm calling jQuery.data() on an object (the LI) and asking for the data in the container associateID.
What you are currently doing:
$(".btnClass").click(function(){
console.log($(".testClass").attr("data-associateid"));
});
Will match the first instance of .testClass and print the data-associateid attribute. What you seem to want to do is to iterate over all .testClass and print their data-associateid values:
$(".btnClass").click(function(){
$(".testClass").each(function() {
console.log($(this).attr('data-associateid'));
});
});
Based on your updated HTML you would do this:
$(".btnClass").click(function() {
var id = $(this).parents('.testClass').attr('data-associateid');
console.log(id);
});
This will search the parents of the clicked on .btnClass to find elements with the class .testClass.
To get the data for that instance you simply need to traverse to the parent <li>.
Within an event handler, this is the element that the event occured on. Use closest() to access the parent <li>
$(".btnClass").on('click', function(){
alert( $(this).closest('li').data('associateid') );
});
Assign different classes to your li elements like this:
<ul class="notification-body" style="">
<li class="testClass1" data-associateid="AA01">test 1</li>
<li class="testClass2" data-associateid="AA02">test 2</li>
<li class="testClass3" data-associateid="AA03">test 2</li>
</ul>
Note, that I closed your li and ul tags to have valid HTML.
And then you can select an element with its own class:
console.log($(".testClass2").attr("data-associateid"));
I created a JSFiddle for you:
http://jsfiddle.net/8rLpbk5m/
I had hoped you could do it with just a find but apparently not. You have to use each to loop through all the elements.
$(".btnClass").click(function(){
$(".testClass").each(function() {
console.log($(this).attr('data-associateid'));
});
});
View it here: http://jsfiddle.net/rt677qp5/
Using .data() is more logical in this case.
$(".btnClass").click(function() {
$(".testClass").each(function() {
alert($(this).data("associateid"));
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul class="notification-body" style="">
<li class="testClass" data-associateid="AA01"></li>
<li class="testClass" data-associateid="AA02"></li>
<li class="testClass" data-associateid="AA03"></li>
</ul>
<button class="btnClass"></button>

Javascript event handler on list item li parent node

I'm new to javascript and I wanted to create an event onclick to list items. The problem is that I want to create an event to the li tag, but it keeps firing when I click the descendent ul's.
Here goes part of my code:
<li id="1660761" class="HTMLFirstLevel HTMLHorizontalArrowDown">
<ul id="ul1223945" class="HTMLItem">
<li id="1490659" class="HTMLRemainingLevels"></li>
<li id="483463" class="HTMLRemainingLevels"></li>
<li id="80919" class="HTMLRemainingLevels"></li>
<li id="1280053" class="HTMLRemainingLevels"></li>
<li id="1799353" class="HTMLRemainingLevels"></li>
<li id="1882209" class="HTMLRemainingLevels"></li>
<li id="462917" class="HTMLRemainingLevels"></li>
</ul>
</li>
<li id= ......>
<ul....>
<ul...>
</li>
and my javascript:
var parentNode = document.getElementById('1660761');
parentNode.addEventListener("click",function(e) {
alert('Hi There');
});
}
Now I only want it to fire on the item li with the id 1660761, and not the items inside the list.
The list is an imported component and I can't create events inside the html, that's why I'm accessing it outside with javascript.
Now here's how I've done it by scaning the div by tag name and then adding a "click" event listener if the content equals the tag inner html that I was searching for.
I leave the rest of the html that it's important to this aproach:
<div id="MainMenu" class="HTMLMenuContainer HTMLMenuHorizontal">
<ul id="ul1351387" class="HTMLMenu">
<li id="1660761" class="HTMLFirstLevel HTMLHorizontalArrowDown">
<a href="#">
<span>Back Office</span>
</a>
<ul id="ul1172716" class="HTMLItem">
<li id="1490659" class="HTMLRemainingLevels">
<a href="#">
<span>
Some submenu Here
</span>
</a>
</li>
.....
and the code:
var divs = document.getElementsByClassName('HTMLMenuHorizontal');
var span = divs[0].getElementsByTagName('span');
//I iterate till 19 cause its more than all the spans in the page.
for(var i=0; i<20; i++) {
var sp= span[i];
if(sp.innerHTML==('Back Office')){
sp.addEventListener("click",function back(){
//do something here like
alert('Back Office');
});
}
}
This works fine and it doesn't fire on the itens inside.
This works because in my case the itens doesn't change the content, only the visibility.
I do the same for all the other itens that have descendents.
Thank you all.
Below is my jQuery code for this problem:
$(function(){
$("li.1660761").live("click", onListItemLink);
}
function onListItemLink(){
alert('Hello World!');
}
This one is for JavaScript:
var parentNode = document.getElementById('1660761');
parentNode.onclick = onListItemLink;
function onListItemLink(){
alert('Hello World!');
}
take a look at this page to undersand correctly:
capture event
and what's function(e-->??)
I hope it helps.
$('#1660761').unbind('click').click(function(e) {
if (e.target !== this) return;
alert('Hey There!');
});
Try This code : http://jsfiddle.net/sd5LZ/

jQuery - Building a tree style list

My DOM is as follows
<ul>
<li id="Browse">
Browse
<ul id="browse-one">
</ul>
</li>
</ul>
My jQuery in a in the bottom of the page is:
$("#Browse").click(function() {
$("#browse-one").html('<div class="ui-widget">Loading...</div>');
$("#browse-one").load('../api/browse.php?do=getFirst');
});
This script goes into the database and spits out raw LIs. After this runs the DOM is modified as follows
<ul>
<li id="Browse">
Browse
<ul id="browse-one">
<li id="one-1" data-id="1">SOMETHING</li>
<li id="one-2" data-id="2">SOMETHING</li>
<li id="one-3" data-id="3">SOMETHING</li>
<li id="one-4" data-id="4">SOMETHING</li>
.
.
.
<li id="one-N" data-id="N">SOMETHING</li>
</ul>
</li>
</ul>
What is the proper jqueryish way to track clicks on these LIs. I want to extract the data-id of the clicked element and make a second API call to construct part two of the tree. For example if data-id="1"'s LI is clicked the DOM should be:
<ul>
<li id="Browse">
Browse
<ul id="browse-one">
<li id="one-1" data-id="1">SOMETHING
<ul id="Something Here">
<li id="two-1" data-id="1">HMM</li>
<li id="two-2" data-id="2">HMM</li>
<li id="two-3" data-id="3">HMM</li>
.
.
.
<li id="two-M" data-id="M">HMM</li>
</ul>
</li>
<li id="one-2" data-id="2">SOMETHING</li>
<li id="one-3" data-id="3">SOMETHING</li>
<li id="one-4" data-id="4">SOMETHING</li>
.
.
.
<li id="one-N" data-id="N">SOMETHING</li>
</ul>
</li>
</ul>
Im having trouble thinking of how i'de keep each of the inner UL's IDs unique. Sure I can do the "LEVEL-ID" as in "two-1" but I feel this is hackish and not the proper jquery way.
EDIT:
But now how do I track the children's clicks?? This doesn't seem valid but I hope you understand wht I'm trying to do
$("#Browse").click(function() {
$("#locations-browse").html('<div class="ui-widget">Loading...</div>');
$("#locations-browse").load('../api/browse.php?do=getFirst');
//Child is tracked
$("#locations-browse").delegate("li","click",function(evt){
var inner = $(this).append("<ul></ul>");
inner.html('<div class="ui-widget">Loading...</div>');
inner.load('../api/browse.php?do=getSecond');
$(this).delegate("li","click", function(evt) {
alert("Child ". $(this).data("id") . " is clicked";
});
});
});
EDIT 2:
Hmm this still is not working:
$("#Browse").click(function() {
$("#locations-browse").html('<div class="ui-widget">Loading...</div>');
$("#locations-browse").load('../api/browse.php?do=getFirst');
//Child is tracked
$("#locations-browse").delegate("li","click",function(evt){
$(this).append("<ul></ul>");
$(this).children("ul").load('../api/browse.php?do=getSecond?location-id='.$(this).data("id"));
$(this).delegate("li","click", function(evt) {
alert($(this).data("id"));
});
});
});
Delegate the event via li#Browse and reference the data-id attribute relative to the event's contextual element.
$('#Browse').on('click', 'li', function(evt) {
alert($(this).data('id'));
});
Incidentally, there's several out-of-the-box plugins that do what you need, just in case you didn't want to build you own, e.g. YUI Treeview or the one I wrote.

Categories