jQuery SlideDown only if another `ul` is clicked - javascript

I've an unordered list.
<div class="categories-list">
<ul class="display_categories">
<li>
<a class="title"><span><b>1</b></span></a>
<ul class="display_subcategories">
<li><a>22</a></li>
<li><a>22</a></li>
</ul>
</li>
<li>
<a class="title"><span><b>1</b></span></a>
<ul class="display_subcategories">
<li><a>22</a></li>
<li><a>22</a></li>
</ul>
</li>
</ul>
</div>
I want that when a user clicks on any category, its sub-category should slidedown and whenever the same category is clicked, nothing should happen. Here's my jQuery
$('.display_subcategories').hide()
$('.title').click(function(){
$('.display_categories').children().children('ul').slideUp('fast');
$(this).next().slideDown('fast');
})
but what happens is that upon clicking on the already slideDown category, it again slides up and then slides down.
Here is the jsFiddle link

You can slideDown the current submenu, then use not() to slideUp() all except the current, like this:
$('.display_subcategories').hide()
$('.title').click(function() {
var $submenu = $(this).next().slideDown('fast');
$('.display_categories').find('> li > ul').not($submenu).slideUp('fast');
});
Updated fiddle
Note also the use of find() with the descendant selector over chained children() calls.

Try this
$('.display_subcategories').hide();
$('.title').click(function(){
if(!$(this).hasClass('down')){
$('.title').removeClass('down');
$('.display_categories').children().children('ul').slideUp('fast');
$(this).next().slideDown('fast');
$(this).addClass('down');
}
})
Updated JS Fiddle

I would suggest letting CSS manage your animations by triggering or disabling classes. A simple example would be adding the .active class to an open <ul>, and the following CSS:
.display_subcategories { max-height: 0; overflow: hidden; transition: all 300ms; }
.display_subcategories.active { max-height: 50px; }
Here is a modified JSFiddle with my suggestion.

Related

Add class and display block on click menu item

i have html menu with submenu for ex:
<li id="item-3" class="menu-item has-children-3">
<span>Auto</span>
<ul class="sub-menu fadeOut animated fast" id="cpx" style="">
<li id="menu-item-9" class="menu-item"><span>Reno яхту</span></li>
<li id="menu-item-6" class="menu-item"><span>Audi</span></li>
</ul>
</li>
When i make mouseover on menu Auto, i need to replace for ul fadeOut to fadeIn and add to style="display:block" and after mouseout add to style="display:none" and to class add fadeOut to ul element?
You can try to achieve this only with css and element+element selector
https://www.w3schools.com/cssref/sel_element_pluss.asp
eg:
.sf-with-ul:hover + .sub-menu {
display: block;
opacity: 1;
}
however this might not be the effect you want as the moment you mouse out of anchor element with class sf-with-ul trying to click on some of the sub menu items the whole sub menu will go back to "display:none; state"
maybe better apply this to the whole parent li like
.menu-item.has-children-3:hover .sub-menu {
display: block;
opacity: 1;
}

Add/Remove all classes except class on current event

so i'm a bit confused as why the code im working off isn't working as expected, so any help would be good.
so let me explain im working on an expanding/ collapsing menu, when the a tag is clicked a class is added and css is added to make this happen, and also the class is removed from the other links.
CSS code:
a {
max-height: 0;
overflow: hidden;
transition: 0.5s ease-in-out
}
a.clicked {
max-height: 600px;
}
html code:
<ul>
<li><a onclick='mobileMenu(event)'>link 1</a><li>
<li><a onclick='mobileMenu(event)'>link 2</a><li>
<li><a onclick='mobileMenu(event)'>link 3</a><li>
<li><a onclick='mobileMenu(event)'>link 4</a><li>
</ul>
for this post i kept the html pretty simple but if it needs to be more detailed let me know.
Each link has a onclick attached.
Javascript code:
function mobileMenu(event) {
event.currentTarget.classList.toggle("clicked");
[].forEach.call(document.querySelectorAll('ul li a'), function(a){
a.classList.remove('clicked');
});
}
so this code mostly works where you click a link is adds 'clicked' class and also removes the 'clicked' class from any other links except the current link, which is good because im using this as a collapse-able menu so you click another link it opens it while also closing any other link currently open.
My problem is is the js code above to add the clicked class i'm using a '.toggle' but this only adds the 'clicked' class but does not toggle it. I want to be able to toggle the 'clicked' class and also remove it from others links. so im not sure if its a simple oversight on my part but im not sure where im going wrong and why the '.toggle' isn't actually toggling the class.
Thanks.
You can try a if statement. It will always remove the checked from all links, and if the event.target is not checked, it will add the class checked.
function mobileMenu(event) {
const checked = event.currentTarget.classList.contains('clicked')
[].forEach.call(document.querySelectorAll('ul li a'), function(a){
a.classList.remove('clicked');
});
if (checked) return;
event.currentTarget.classList.toggle("clicked");
}
As per comment the right way to add event listeners is using .addEventListener().
In the event listener you can search for an anchor with a class clicked and if any remove the class. After you can add the class to the current element:
document.querySelectorAll('ul li a').forEach(function(ele, idx) {
ele.addEventListener('click', function(e) {
var clickedEle = document.querySelector('ul li a.clicked');
if (clickedEle != null)
clickedEle.classList.remove('clicked');
this.classList.add('clicked');
})
});
a {
max-height: 0;
overflow: hidden;
transition: 0.5s ease-in-out
}
a.clicked {
max-height: 600px;
color: blue;
}
<ul>
<li><a>link 1</a><li>
<li><a>link 2</a><li>
<li><a>link 3</a><li>
<li><a>link 4</a><li>
</ul>

JQuery show delete button on appended div

I have so far able to remove each appened elements using .remove() function of JQuery. my problem is the delete button is always showing on the first element.
I want to hide the delete button on first element and show the delete button when I append a new element.
I have set the delete button on the first element to
.delete-button:first-child{
display:none;
}
in my css but all succeeding appends do not show the delete button..
how can I do this with JQuery can it be done using CSS only?
li:first-child .delete-button { display:none }
<ul>
<li>
First <button class="delete-button">Delete</button>
</li>
<li>
Second <button class="delete-button">Delete</button>
</li>
</ul>
Making assumptions on your markup since none was provided. You can accomplish it using css.
My interpretation of your requirement: If there is only one item, do not show a delete button; if there are multiple items, show a delete button for every item.
Your attempt didn't work because .delete-button:first-child selects all elements with the delete-button class that are also the first-child of their parent element. Presumably this would be all of your buttons.
You can instead use the :only-of-type selector on the elements that contain the delete buttons, e.g., assuming they have the item class:
.item:only-of-type .delete-button { display: none; }
Or if they are li elements:
li:only-of-type .delete-button { display: none; }
That way if the item/li/whatever is the only item then its delete button will be hidden automatically, but as soon as you add additional items the delete button will be shown automatically for all items.
Here's a simple demo with a bit of JS to mock up the add and delete functionality:
$("#parent").on("click", ".delete-button", function() {
$(this).parent().remove();
});
$(".add-button").on("click", function() {
$("#parent").children().first().clone().appendTo("#parent");
});
.item:only-of-type .delete-button { display: none; }
.item { margin: 3px; padding: 2px; width: 100px; border: thin black solid; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="add-button">Add Item</button>
<div id="parent">
<div class="item">
<button class="delete-button">Delete</button>
<div>An item</div>
</div>
</div>
You can try,
div ul:not(:first-child) {
.delete-button{
display:none;
}
}
You might wanna consider browser compatibility before using CSS - Browser support for CSS :first-child and :last-child
Having said that, With jQuery you can write an event handler to change css of all the child elements except the last.
Consider this example from jQuery: How to listen for DOM changes?
$("element-root").bind("DOMSubtreeModified", "CustomHandler");
Yes, Its possible by css only. I hope this snippet helps.
$(document).on('click','#AppendList', function(){
$("ul").append('<li>List <button class="delete-button">Delete</button></li>');
})
li .delete-button { display:none }
li:last-child .delete-button { display: inline-block;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
First <button class="delete-button">Delete</button>
</li>
<li>
Second <button class="delete-button">Delete</button>
</li>
</ul>
<hr>
<button type="button" id="AppendList">Add List</button>

Adding link class on href using jQUERY

I researched quite a bit on onClick changes for links but couldn't quite figure out the solution I need. I have a side bar menu that contains multiple links. I have a default class added to the content I want to appear as default. However when I click another link in the sidebar, I want the previous link's "cur" class to be removed, replaced with nothing, then apply "cur" to the new link. Here's my code:
<li data-bind="attr:{'data-key':key, 'data-code':bankcode}, css: memberModel.bankCssClass($data)" data-key="工商银行" data-code="ICBC-NET-B2C" class="bank_2">
</li>
jQUERY :
$(function(){
$('a').click(function(){
$('a').removeClass('');
$(this).addClass('cur');
});
});
$(function(){
$('a').click(function(){
$(this).parent('li').siblings().find('a').removeClass('cur');
$(this).addClass('cur');
});
});
Hope it will work :)
parent method
siblings method
Try this:
$(function(){
$('a').click(function(){
$('li.blank-2 a').removeClass('cur');
$(this).addClass('cur');
});
});
If your other lis also have the class blank-2
removeClass(className) takes the name of class you want to remove. So try this:
$('a').removeClass('cur');
First you could change yout HTML to something like this
HTML
<!-- add a parent class (if you dit not do already) You can give it a class like parent -->
<ul class="parent">
<!-- give you're child also a class (and one of them is active) -->
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
Jquery
$(function(){
// find you're specific group you want to click
$('a.child').click(function(event){
// catch and stop the default action
event.preventDefault();
// find the specific parent (upstream the dom) (in this case ul with class parent)
var $parent = $(this).closest("ul.parent");
// search within your dom structure (downstream) for a child with a class that is active
// and remove the class
$parent.find("a.active").removeClass("active");
// add the class to the clicked a
$(this).addClass('active');
});
});
i figure out whats the solution for this . I might wanna share it out .
HTML :
<ul data-bind="foreach: thirdPayBank" class="bank_list" style="height: 102px;">
<li data-bind="attr:{'data-key':key, 'data-code':bankcode}, css: memberModel.netbankCssClass($data), click: $root.netBankSelectBank" data-key="工商银行" data-code="ICBC" class="bank_2"></li>
<li data-bind="attr:{'data-key':key, 'data-code':bankcode}, css: memberModel.netbankCssClass($data), click: $root.netBankSelectBank" data-key="农业银行" data-code="ABC" class="bank_3"></li>
CSS :
.bank_list li a.cur {
width: 198px;
height: 48px;
float: left;
border: 1px solid #f0bebe;
background: url(../images/zijin_icon.png) no-repeat -897px -188px;
}
jQUERY :
$(".bank").click(function(){
$(".bank").removeClass('bankcur')
$(this).addClass('bankcur')
})
RESULT :

Get closest div inside clicked <li>

I'm trying to get the closest DIV inside a li item, to apply a new class:
<ul id="menu">
<li class="here">
<img src="image">
<div class="border selected"></div>
</li>
<li class="here">
<img src="image">
<div class="border"></div>
</li>
.....
I wanted to be able to click inside the li tag and apply the class 'selected' to the div that already has class border.
I was trying to use .closest and .find but I couldn't get the good result.
Is there any recommendation? Thanks!
EDIT: https://jsfiddle.net/a8pm1aj7/
Please look at this jsfiddle.
The relevant code is:
$("#menu li").on("click", function(){
$("#menu li div.border").removeClass("selected");
$(this).find("div.border").addClass("selected");
});
This code removes the .selected class from all previously selected elements.
If I understand your question correctly, this should work for you.
.children() seems to work fine.... You may have more of an issue with CSS hierarchy. Make certain the selected class is defined after the border class in the CSS.
$(document).ready(function() {
$( '.here' ).on('click', function() {
var theDiv = $(this).children('.border');
$('.border').not(theDiv).removeClass('selected');
$( theDiv ).toggleClass('selected');
});
});
li { display: block; margin: 10px; width: 80%; }
.border { height: 20px; background: #eee; }
.selected { background: #fee; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="menu">
<li class="here">
Text/image
<div class="border"></div>
</li>
<li class="here">
Text/image
<div class="border"></div>
</li>
</ul>
Updated your fiddle and fixed issues with it.
- You had the div positioned absolute and set at 100% width and 100% height. S0 basically, it was the size of the window. Actually linked the jQuery library to the fiddle.

Categories