my codes are working correctly but in the change of requirement.
i need to keep current active class active which is removed again i mouseover at active <li>
i am not good in JQuery so can somebody help doing this??
(function($){
$(document).ready(function(){
$('a.form').on('mouseover', function(event) {
event.preventDefault();
event.stopPropagation();
$(this).parent().siblings().removeClass('active');
$(this).parent().toggleClass('active');
});
});
})(jQuery);
li.active .btncss, .btncss:hover {
color: #FFAE00;
background: #ffffff;
border: 2px solid;
text-decoration: none;
}
li{display:inline}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list-inline">
<li class="active">With In City</li>
<li class="">Full Day Hire</li>
<li class="">Half Day Hire</li>
<li class="">InterCity Hire</li>
</ul>
Use addClass instead of toggleClass.
.toggleClass Add or remove one or more classes from each element in the set of matched elements, depending on either the class's presence or the value of the state argument.
.addClass() Adds the specified class(es) to each element in the set of matched elements.
It's important to note that this method does not replace a class. It simply adds the class, appending it to any which may already be assigned to the elements.
Try this:
(function($) {
$(document).ready(function() {
$('a.form').on('mouseover', function(event) {
event.preventDefault();
event.stopPropagation();
$(this).parent().siblings().removeClass('active');
$(this).parent().addClass('active');
});
});
})(jQuery);
li.active .btncss,
.btncss:hover {
color: #FFAE00;
background: #ffffff;
border: 2px solid;
text-decoration: none;
}
li {
display: inline
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list-inline">
<li class="active">With In City
</li>
<li class="">Full Day Hire
</li>
<li class="">Half Day Hire
</li>
<li class="">InterCity Hire
</li>
</ul>
It's a little hard to understand your question -- do you want the <li> that is originally active to be reset as active on mouseout? To do this, you need to record what was originally active and add a mouseout handler:
(function($){
$(document).ready(function(){
var originally_active = $('li.active');
$('a.form').on('mouseover', function(event) {
event.preventDefault();
event.stopPropagation();
$(this).parent().siblings().removeClass('active');
$(this).parent().toggleClass('active');
});
$('a.form').on('mouseout', function() {
$(this).parent().removeClass('active');
originally_active.toggleClass('active');
});
});
})(jQuery);
li.active .btncss, .btncss:hover {
color: #FFAE00;
background: #ffffff;
border: 2px solid;
text-decoration: none;
}
li{display:inline}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="list-inline">
<li class="active">With In City</li>
<li class="">Full Day Hire</li>
<li class="">Half Day Hire</li>
<li class="">InterCity Hire</li>
</ul>
Related
I have a nav menu that needs to trigger with clicks rather than hovers. When the links are clicked, an .open class would be added to the parent li. If that parent already has the .open class, then it would get removed. It would also be removed if another link is clicked on. So far I can get the class added when clicked and removed when a sibling is clicked, but not removed when it's already .open.
I tried adding a hasClass conditional, but that didn't work either. Seemed like it reruns the function every time it's clicked and therefore ignores the hasClass conditional.
Can anyone provide help? I tried toggleClass, but that didn't work.
$('li a').on('click', function() {
$('li a').parent().removeClass('open');
$(this).parent().addClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>
To do what you require you can use toggleClass() on the parent li when the element is clicked. To remove the class from all other li elements you can use removeClass() along with not() to exclude the current li. Try this:
$('li a').on('click', function() {
let $li = $(this).parent().toggleClass('open');
$('li').not($li).removeClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>
You can use
jquery toggleClass() to toggle yellow highlight (.open css class) on click/unclicking the same link.
jquery siblings() to remove .open class on all the other li items.
Below is the link for the demo
https://jsfiddle.net/so1u8hq6/
$('li a').on('click', function() {
$(this).parent().siblings().removeClass('open');
$(this).parent().toggleClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 2
</li>
<li>
Item 3
</li>
</ul>
</nav>
Late to the party, but, after seeing the provided answers and some of the CSS you use I had to urge with my suggestions:
UX. Avoid styling LI tags in general, or at least set the desired display and move on. Style directly the a tag (with the necessary paddings etc.). You'll not only get less CSS to take care of, but also a larger touch interaction area. Makes no sense to style something yellow if it's not a UI part of something interactable. Also in JS, you don't need to take care about the LI wrappers any more - but only about the actual A Elements.
Don't use common selectors like $('li a') - those might target any LI→A elements in your app. Instead be more specific and use a Class like i.e: .tabs for the parent UL. Both in CSS and JS.
Try to use Event Delegation (in jQuey using the .on() method). Not only it will help you to catch the Event.delegateTarget parent UL where needed, but also the this (the clicked element), but mainly reference all the "group" of a elements enclosed in the common parent. That way you can have as many .tabs in a single page as you like. And yes, thanks to Event delegation you can even add dynamically LI Elements - and your JS will still work as expected.
Since you're using <a href="#"> Anchor elements, instead of (more properly) <button type="button>" Elements, you need to also use Event.preventDefault() in order to prevent the browser its default behavior and that's to follow anchors (scroll the page, navigate, etc...)
Use the selector "a.open" when you want to target and remove the "open" class. By just using "a" (or in other answers on this page - "li") you're uselessly touching elements trying to remove a class that's not there in the first place.
Finally, here's the CSS retouch and the proper jQuery needed for your task:
$(".tabs").on("click", "a", function(ev) {
ev.preventDefault();
$("a.open", ev.delegateTarget).not(this).removeClass("open");
$(this).toggleClass("open");
});
.tabs {
display: flex;
list-style: none;
padding: 0;
}
/* Style your Anchors, not the dummy LI wrappers */
.tabs a { padding: 10px; }
.tabs a.open { background-color: yellow; }
<ul class="tabs">
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
To explain the only complicated line:
$(
"a.open", // Target just the ones (if any) of class "open"
ev.delegateTarget // inside the common ".tabs" ancestor
)
.not(this) // ... not the clicked element (since later we'll use .toggleClass on it)
.removeClass("open"); // ... remove that class "open"
the rest is pretty self explanatory.
Further read:
jQuery Event Delegation
jQuery event.delegateTarget
Event.preventDefault
So you only want the yellow background to appear as a signifier of user interaction rather than for the background color to be displayed? Have you tried using the mousedown/mouseup functions instead of .on('click', function(){...}?
I was able to simulate the click event where the color showcases via this method:
$('li a').mousedown(function() {
$('li a').parent().removeClass('open');
$(this).parent().addClass('open');
});
$('li a').mouseup(function() {
$('li a').parent().removeClass('open');
});
ul {
list-style: none;
}
li {
display: inline-block;
padding: 10px;
}
.open {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<ul>
<li>
Item 1
</li>
<li>
Item 1
</li>
</ul>
</nav>
I have a tree list where the user can open or close the branches by clicking. The tree has many levels and sub-levels. I want to be able to collapse all branches (down to the first level) or expand all branches for the class "my-clickable" when the user clicks on the Collapse All or Expand All button.
I can get the individual branches to close or open. But I can't get them all to open or close at once.
Here is my jsfiddle:
https://jsfiddle.net/dyrh325f/65/
One thing to note is that the Expand All button is being used after an ajax call that populates the entire tree. I have the 'Expand All' code in the "done" portion of the ajax call, so it applies to the generated html.
I want the user to be able to expand the entire tree out after he has closed one or more nodes. I've tried several variations of what I have in my jsFiddle. Nothing seems to work. What am I doing wrong?
I am a jQuery newbie so - thanks for any and all help!!!
Code:
HTML:
Expand Tree
<font face="calibri" size="3pt" >
<ul id="tree1" class="mytree">
<li id="theJob" class="my-clickable mytree liParOpen">My Job</li>
<ul id="treeList" class="mytree" name="treeList">
<li id='0' class='mytree child-click'>Batcher</li>
<li id='1' class='mytree child-click'>Retriever</li>
<li id='2' class='my-clickable mytree liParOpen'> TASK 2</li>
<ul class='mytree'>
<li id='2a' class='mytree child-click'>Prep1</li>
<li id='2b' class='mytree child-click'>Prep2</li>
<li id='2c' class='mytree my-clickable liParOpen'>PREP3</li>
<ul class='mytree'>
<li id='2b1' class='mytree child-click'>PREP3a</li>
<li id='2b2' class='mytree child-click'>PREP3b</li>
</ul>
</ul>
<li id='3' class='mytree child-click' > task 3</li>
<li id='4' class='my-clickable mytree liParOpen'> TASK 4</li>
<ul class='mytree'>
<li id='4a' class='mytree child-click'>Edit1</li>
<li id='4b' class='mytree child-click'>Edit2</li>
</ul>
<li id='5' class='my-clickable mytree liParOpen'> TASK 5</li>
<ul class='mytree'>
<li id='5a' class='mytree my-clickable liParOpen'>Del1</li>
<ul class='mytree'>
<li id='5a1' class='mytree child-click'>Del1a</li>
<li id='5a2' class='mytree child-click'>Del1b</li>
</ul>
<li id='5b' class='mytree child-click'>Del2</li>
</ul>
<li id='6' class='mytree child-click'>DocEjector-3</li>
</ul>
</ul>
</font>
Jquery:
$(document).ready(function(){
// expand button
$('#expandTree').on('click', function(event) {
var all = $('.my-clickable');
var closed = all.filter('.liParClosed');
closed.find("ul").each(function(){
$(this).next('ul').attr("class", "liParOpen");
$(this).nextAll('ul').toggle();
});
}); // end expand button
// collapse button
$('#collapseTree').on('click', function(event) {
var all = $('.my-clickable');
var open = all.filter('.liParOpen');
open.find("ul").each(function(){
$(this).next("ul").attr("class", "liParClosed");
$(this).nextAll('ul').slideToggle();
});
}); // end collapse button
// this is the top most level parents
$(".my-clickable").on('click', function(event) {
var taskId=$(this).closest("li").attr('id');
var tsk = '#'.concat(taskId);
if (taskId != "theJob") {
if ($(tsk).next('ul').length <= 0) {
$(tsk).toggleClass("liParOpen liParClosed");
$(tsk).next('ul').slideToggle();
}
else {
//$(event.target).find('ul').toggle();
$(tsk).toggleClass("liParOpen liParClosed");
$(tsk).children('li').slideToggle();
$(tsk).next('ul').slideToggle();
}
} // end if taskId != "theJob"
else {
$(tsk).toggleClass("liParOpen liParClosed");
$(tsk).slideToggle();
}
event.cancelBubble=true;
event.stopPropagation();
});
//2nd level parents
$(".my-clickable").on('click', ".my-clickable", function(event) {
var taskId=$(this).closest("li").attr('id');
var tsk = '#'.concat(taskId);
//$(event.target).find('ul').slideToggle();
$(tsk).toggleClass("liParOpen liParClosed");
//event.cancelBubble=true;
event.stopPropagation();
});
// first level child w/no children (parent=job)
$(".child-click").on('click', function(event) {
event.stopPropagation();
});
});
CSS:
ul.mytree li.liParClosed {
background-color: green;
fontWeight: normal;
}
ul.mytree li.liParOpen {
background-color: cyan;
fontWeight: normal;
}
.selected{
border: 3px solid yellow;
background-color: yellow;
fontWeight: bold;
}
ul.mytree liParOpen selected{
border: 3px solid red;
background-color: yellow;
fontWeight: bold;
}
ul.mytree li selected{
border: 3px solid red;
background-color: yellow;
fontWeight: bold;
}
ul.mytree li {
background-color: white;
fontWeight: normal;
}
ul.mytree {
background-color: white;
fontWeight: normal;
}
You almost got it but the toggling of classes "liParClosed" and "liParOpen" wasn't being done right.
Here's a fiddle fixing that issue:
JS Fiddle
Relevant code changes:
// expand button
$('#expandTree').on('click', function(event) {
var all = $('.my-clickable');
var closed = all.filter('.liParClosed');
closed.each(function(){
$(this).removeClass('liParClosed').addClass('liParOpen');
$(this).next('ul').slideToggle();
});
}); // end expand button
// collapse button
$('#collapseTree').on('click', function(event) {
var all = $('.my-clickable');
var open = all.filter('.liParOpen');
open.each(function(){
$(this).removeClass('liParOpen').addClass('liParClosed');
$(this).next('ul').slideToggle();
});
}); // end collapse button
Look at the way the classes are being added/removed. Also, you were
looking for open.find("ul") BUT open itself had to be looped through as it is a list of open li's.
Hope this helps. :)
Sorry if this is an extremely simple question, but for some reason, I cant get this working.
What I'm trying to do is to add the activeButton class to each list item you click and remove the activeButton class to the list-item that had the activeButton class before the list-item was clicked.
Here is a code snippet of my problem
$(document).ready(function () {
$('.buttons').click(function () {
$('.activeButton').removeClass('.activeButton');
$(this).addClass('.activeButton');
});
});
.buttons {
/*This is for decorative and visual purposes.
So you can ignore the CSS for now.*/
display: inline-block;
margin: 10px;
}
.activeButton {
border-bottom: 1px solid black;/*I use border-bottom to provide underlines for my text. This allows the underline to be transitioned or animated*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="buttons activeButton">Link1</li>
<li class="buttons">Link2</li>
<li class="buttons">Link3</li>
<li class="buttons">Link4</li>
</ul>
For the sake of clarification, I will explain my goal and the current problem.
GOAL: Once a list item is clicked, the class .activeButton will be added to the list item that was clicked and the JS will remove .activeButton from the list item that originally had the activeButton class.
PROBLEM: The attempted solution that I have coded does not work.
Like this you mean?
$(document).ready(function () {
$('.buttons').click(function () {
$('.buttons').removeClass('activeButton'); // <-- remove from all .buttons class
$(this).addClass('activeButton'); // <-- add to clicked link only
});
});
.buttons {
/*This is for decorative and visual purposes.
So you can ignore the CSS for now.*/
display: inline-block;
margin: 10px;
}
.activeButton {
border-bottom: 1px solid black;/*I use border-bottom to provide underlines for my text. This allows the underline to be transitioned or animated*/
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="buttons activeButton">Link1</li>
<li class="buttons">Link2</li>
<li class="buttons">Link3</li>
<li class="buttons">Link4</li>
</ul>
You don't need the class selector in the strings you pass to addClass() and removeClass().
Update as follows:
$(function () {
$('.postalProvider').click(function () {
$('.activeButton').removeClass('activeButton');
$(this).addClass('activeButton');
});
});
Update :
$(document).ready(function () {
var $buttons = $('.buttons');
$buttons.click(function () {
$buttons.removeClass('.activeButton');
$(this).addClass('.activeButton');
});
});
I think this is what you were after.
HTML:
<div class="selectContainer">
<ul>
<li class="init">Select</li>
<li data-value="value 1">Option 1</li>
<li data-value="value 2">Option 2</li>
</ul>
</div>
CSS:
.selectcontainer ul li
{
border:1px solid green;
width:100%;
cursor:pointer;
}
.selectcontainer ul li:not(.init){
display:none;
float:left;
}
li.init{cursor:pointer; background:url("../images/arrow-down.png") right no-repeat;}
li.init1 { cursor: pointer; background:url("../images/arrow-up.png") right no-repeat;}
JQuery:
jQuery(document).ready(function () {
$( "ul" ).click(function() {
$(this).closest("ul").children('li:not(.init)').slideToggle(200);
});
$( "li" ).click(function() {
$("li .init").addClass("li .init1");
});
});
Hi I just have to change my image when dropdown is open up arrow and when close down arrow.
This code is not working please help.
Solved:
You were not toggling "init1" class (first <li>) on click of <ul>, so your arrows were not changing on click.
$("ul").click(function () {
$(this).children('li:not(.init)').slideToggle(200);
$(this).find("li.init").toggleClass("init1");
});
Below is the JS fiddle working example, i have used special characters and :after pseudo class for up/down arrows , you can change as it suits you.
http://jsfiddle.net/4C5ND/
SO simple .U could use transform:rotate(180deg); CSS on click.
You could try:
if($(this).hasClass("class1")){
$(this).removeClass("class1").addClass("class2");
}else{
$(this).removeClass("class2").addClass("class1");
}
demo for reference: http://greg-j.com/static-content/accordian/
When viewed in any other browser, the toggler works as you would expect it to. However, in IE (I'm using 8), you can only contract the currently expanded sub menu, and then you get undesired results once it is closed.
Example html:
<!DOCTYPE html>
<html>
<head>
<script class="jsbin" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Untitled</title>
<link type="text/css" rel="stylesheet" href="http://meyerweb.com/eric/tools/css/reset/reset.css" />
<style type="text/css">
body{margin: 50px; font-family: arial; font-size: 12px}
div{width: 172px; margin: 0 auto;}
a{text-decoration: none; color: #006ecf}
.gMenu{
background: #fafbfc;
border-left: solid 1px #abc1d6;
border-right: solid 1px #abc1d6;
padding: 5px 0;
}
.gMenu ul{
background: white;
border-top: solid 1px #dbe6f0;
border-bottom: solid 1px #dbe6f0;
position: relative;
top: 4px;
}
.gMenu li{
line-height: 16px;
padding: 4px 0;
position: relative;
}
.gMenu li li{
padding-left: 10px;
font-size: 11px;
}
.gMenu a{
padding: 0 4px;
}
.gMenu ul a{
padding: 0;
}
.gMenu a:hover{
color: #000;
text-decoration: underline;
}
.gMenu em{
color: #abc1d6;
}
</style>
</head>
<body>
<div>
<ul class="gMenu">
<li class="gm-active">Bodywork
<ul>
<li>Fairing Bolt Kits <em>(23)</em></li>
<li>Fairing Brackets <em>(2)</em></li>
<li>Fairings <em>(17)</em></li>
<li>Fender Eliminator Kits <em>(6)</em></li>
<li>Front Fenders <em>(5)</em></li>
<li>Graphics Kits <em>(223)</em></li>
<li>Huggers <em>(40)</em></li>
<li>Under Trays <em>(7)</em></li>
<li>Windscreens <em>(3)</em></li>
</ul>
</li>
<li>Books
<ul>
<li>Service Manuals</li>
</ul>
</li>
<li>Brakes
<ul>
<li>Brake Hardware</li>
<li>Brake Lines</li>
<li>Brake Pads</li>
<li>Brake Rotors</li>
</ul>
</li>
<li>Controls
<ul>
<li>Bar Ends</li>
<li>Cables</li>
<li>Handlebars</li>
<li>Levers</li>
<li>Mirrors</li>
<li>Pedals</li>
<li>Quick Shift Kits</li>
<li>Rearsets</li>
<li>Stabilizers</li>
<li>Throttles</li>
<li>Triple Clamps</li>
</ul>
</li>
<li>Caps, Covers, Guards
<ul>
<li>Axle Covers</li>
<li>Chain Guards</li>
<li>Heel Guards</li>
<li>Mirror & Signal Block Offs</li>
<li>Oil Caps and Dipsticks</li>
<li>Reservoir Covers</li>
</ul>
</li>
<li>Drive
<ul>
<li>Chain and Sprocket Kits</li>
<li>Front Countershaft Sprockets</li>
<li>O-Ring Chains</li>
<li>Rear Drive Sprockets</li>
<li>Roller Chains</li>
</ul>
</li>
<li>Electrical
<ul>
<li>Accessory Lighting</li>
<li>Alarms</li>
<li>Batteries</li>
<li>Gauges</li>
<li>Marker Lights</li>
<li>Radar Detectors</li>
<li>Spark Plugs</li>
<li>Taillights</li>
<li>Turn Signals</li>
</ul>
</li>
<li>Engine
<ul>
<li>Clutch Discs</li>
<li>Clutch Kits</li>
<li>Clutch Springs</li>
<li>Oil Filters</li>
</ul>
</li>
<li>Exhaust
<ul>
<li>Complete Exhaust Systems</li>
<li>Heat Shields</li>
<li>Slip-On Mufflers</li>
</ul>
</li>
<li>Frame & Swingarm
<ul>
<li>Frame Sliders</li>
<li>Kickstands</li>
<li>License Plate Kits</li>
<li>Stand Adapters</li>
<li>Swingarm Extensions</li>
<li>Swingarm Spools</li>
</ul>
</li>
<li>Fuel Systems
<ul>
<li>Fuel Injection Mapping</li>
</ul>
</li>
<li>Suspension
<ul>
<li>Fork Seals</li>
<li>Rear Lowering Kits</li>
<li>Shock Absorbers</li>
</ul>
</li>
<li>Tanks
<ul>
<li>Gas Caps</li>
<li>Tank Bras</li>
<li>Tank Protectors</li>
<li>Traction Pads</li>
</ul>
</li>
<li>Intake
<ul>
<li>Air Filters</li>
<li>Velocity Stacks</li>
</ul>
</li>
<li>Tires
<ul>
<li>Front Tires</li>
<li>Rear Tires</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
Example JS:
(function($){
$.fn.gMenu = function(options) {
var o = $.extend({
speed: "fast"
}, options);
return this.each(function() {
var $ul = $('ul', this), // Get this ul's decendant ul's
$li = $(this).children('li'); // Get only the first decendant li's in this ul
$ul.not('.gm-active ul').hide();
// Create toggler elements for the first decendant li's only
$li.children('a').after(
$('<span>', { html: "toggle", 'class': "gm-toggler"}).hide()
);
var $toggler = $li.find('.gm-toggler');
// Only show the toggler when a collapsed menu item is hovered
$li.hover(function(){
$('.gm-toggler', this).toggle();
});
// Only show one child menu at a time. Never collapse them all
$toggler.click(function(){
// get this togglers parent ul
var $current = $(this).parent().find('ul');
// slide all other child menu up and remove its .active class
$($ul).not($current).slideUp(o.speed)
.parent().removeClass('gm-active');
// Stop sliding this togglers menu if it is animating and slide it the other direction
$current.stop(false,true).slideToggle(o.speed);
// If this togglers menu is active ...
$(this).parent('li').toggleClass('gm-active');
});
});
};
})(jQuery);
$(document).ready(function(){
$('.gMenu').gMenu({
speed: 200
});
});
Maybe this can point you in the right direction.
You don't need a return this.each(function() {}); since you are already passing the DOM element in the plug-in aka "gMenu" you just work from there on.
For brevity I left out a lot of code and minimized it to the features that matter.
Also you don't want to hide other opened menu items, since it breaks common patterns in UI design.
(function($){
$.fn.gMenu = function(options) {
var o = $.extend({
speed: "fast"
}, options);
$('ul', this).not('.gm-active ul').hide();
$('a', this).click(function(){
$(this).next().slideToggle(o.speed);
});
return this;
};
})(jQuery);
Solution found.
The issue was that I wasn't specifically cycling through each list element found. I reworked the jQuery a bit to put everything inside an $.each() function and now all seems well. I'm not sure if this is the most efficient way of doing it now though, so if anyone see's any room for improvement, please let me know.
http://jsbin.com/edago3/8/
(function($){
$.fn.extend({
gMenu: function (options) {
var o = $.extend({
speed: "fast"
}, options);
// Get this ul's decendant ul's
var $ul = $('ul', this);
// Hide decendant ul's that are not active
$ul.not('.gm-active ul').hide();
// loop through this lists list elements
$.each($(this).children('li'), function(){
// Create toggler elements for the first decendant li's only
$(this).children('a').after(
$('<span>', { html: "toggle", 'class': "gm-toggler"})
);
// find the togglers and hide them
var $toggler = $(this).find('.gm-toggler').hide();
// Only show the toggler when a menu item is hovered
$(this).hover(function(){
$('.gm-toggler', this).toggle();
});
// Only show one child menu at a time. Never collapse them all
$($toggler, this).click(function(){
// get this togglers parent ul
var $current = $(this).parent().find('ul');
// slide all other child menu up and remove its .active class
$($ul).not($current).slideUp(o.speed)
.parent().removeClass('gm-active');
// Stop sliding this togglers menu if it is animating and slide it the other direction
$current.stop(false,true).slideToggle(o.speed);
// If this togglers menu is active ...
$(this).parent('li').toggleClass('gm-active');
});
});
}
});
})(jQuery);