Jquery show/hide/toggle elements "near by" - javascript

I'm trying to set this up so that "Click me 1" only shows "Expand me 1", "Click me 2" only shows "Expand me 2", etc. What I have now makes each one toggle everything. I think I need to use $(this) but nowhere I've put it has worked.
Markup
<div class="submission">
<ul>
<li class="click">Click me 1</li>
<li>foo</li>
<li>bar</li>
<li class="expand">Expand me 1</li>
</ul>
</div>
<div class="submission">
<ul>
<li class="click">Click me 2</li>
<li>foo</li>
<li>bar</li>
<li class="expand">Expand me 2</li>
</ul>
</div>
<div class="submission">
<ul>
<li class="click">Click me 3</li>
<li>foo</li>
<li>bar</li>
<li class="expand">Expand me 3</li>
</ul>
</div>
Jquery
$(document).ready(function() {
$(".submission").find(".click").click(function() {
$(".expand").slideToggle();
});
});
CSS
.expand {display: none;}
http://jsfiddle.net/4k9uukL8/

You can use .parent() selector
FIDDLE
$(document).ready(function() {
$(".submission .click").click(function() {
$(this).parent().find(".expand").slideToggle();
});
});
More information in documentation

You want to target one of the following sibling element so
$(document).ready(function() {
$(".submission .click").click(function() {
$(this).nextAll(".expand").slideToggle();
//or $(this).siblings(".expand").slideToggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="submission">
<ul>
<li class="click">Click me 1</li>
<li>foo</li>
<li>bar</li>
<li class="expand">Expand me 1</li>
</ul>
</div>
<div class="submission">
<ul>
<li class="click">Click me 2</li>
<li>foo</li>
<li>bar</li>
<li class="expand">Expand me 2</li>
</ul>
</div>
<div class="submission">
<ul>
<li class="click">Click me 3</li>
<li>foo</li>
<li>bar</li>
<li class="expand">Expand me 3</li>
</ul>
</div>

Try utilizing Next Siblings Selector ("prev ~ siblings") selector $("~ .expand", this) within click handler to call .slideToggle()
$(".submission .click").click(function() {
$("~ .expand", this).slideToggle()
})
.expand {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<div class="submission">
<ul>
<li class="click">Click me 1</li>
<li>foo</li>
<li>bar</li>
<li class="expand">Expand me 1</li>
</ul>
</div>
<div class="submission">
<ul>
<li class="click">Click me 2</li>
<li>foo</li>
<li>bar</li>
<li class="expand">Expand me 2</li>
</ul>
</div>
<div class="submission">
<ul>
<li class="click">Click me 3</li>
<li>foo</li>
<li>bar</li>
<li class="expand">Expand me 3</li>
</ul>
</div>

Pekka's answer is probably the simplest (and therefore best).
An alternate could be to use "closest" when not addressing the immediate parent.
$(this).closest(".submission").find(".expand").slideToggle();

Related

Find ul with a specific li item in a collection of ul and than add class to it

I have a collection of unordered lists. I would like to iterate through this list and than find an specific li item and than add a class to the ul containing that li.
I hope I was clear enough for you guys. Let me show you my code for better understanding.
This is a fiddle I created to help you understand my problem.
https://jsfiddle.net/wdwn9swu/
This is what I tried to target the ul I need but it didn't work.
if ($('ul.sub-tab').find('ul.sub-tab > li.super-active')) {
$('ul.sub-tab').find('li.super-active').addClass('super-active');
}
I would like that on of the lists that corresponds with the id, to always be open.
Any idea guys ?? Thanks!!
I think the easiest and simplest way is:
$("li.super-active").parent().addClass("super-active");
According the fact you are using valid html <li> element parent must be <ul> element in that case (can also be <ol>).
$('.main-tab>li a').click(function() {
$(this).siblings('.sub-tab').slideToggle(200);
$(this).parent().siblings('li').children('.sub-tab').slideUp(200);
});
$('.main-tab li').each(function() {
id = '10';
$links = $(".main-tab li[data-id =" + id + "]");
$links.addClass("super-active");
//console.log("1234");
});
$("li.super-active").parent().addClass("super-active");
console.log($(".super-active"));
.main-tab ul {
padding-left: 10px;
}
.sub-tab {
display: none;
}
.super-active img {
display: block !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="center">
<ul class="main-tab">
<li data-id="5">
Main 1
<ul class="sub-tab">
<li data-id="7">
Main 1 Sub 1
<ul class="sub-tab">
<li data-id="10">Sub 2</li>
<li data-id="11">Sub 2</li>
</ul>
</li>
<li>
Main 1 Sub 2
<ul class="sub-tab">
<li data-id="12">Sub 2</li>
<li data-id="13">Sub 2</li>
</ul>
</li>
</ul>
</li>
<li data-id="8">
Main 2
<ul class="sub-tab">
<li data-id="9">
Main 2 Sub 1
<ul class="sub-tab">
<li data-id="14">Sub 2</li>
<li data-id="15">Sub 2</li>
</ul>
</li>
</ul>
</li>
<li data-id="3">
Main 3
<ul class="sub-tab">
<li data-id="25">
Main 3 Sub 1
<ul class="sub-tab">
<li data-id="17">Sub 2</li>
<li data-id="18">Sub 2</li>
</ul>
</li>
</ul>
</li>
</ul>
Use jQuery's :has selector:
Selects elements which contain at least one element that matches the
specified selector.
Find ul.sub-tab that has a list item with .super-active class, and add the class .super-active to the ul as well:
$('ul.sub-tab:has(li.super-active)').addClass('super-active');
Example:
$('ul.sub-tab:has(li.super-active)').addClass('super-active');
.sub-tab.super-active {
background: gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="center">
<ul class="main-tab">
<li data-id="5">
Main 1
<ul class="sub-tab"> <!-- this will be removed -->
<li data-id="7" class="super-active">
Main 1 Sub 1
<ul class="sub-tab">
<li data-id="10">Sub 2</li>
<li data-id="11">Sub 2</li>
</ul>
</li>
<li>
Main 1 Sub 2
<ul class="sub-tab">
<li data-id="12">Sub 2</li>
<li data-id="13">Sub 2</li>
</ul>
</li>
</ul>
</li>
<li data-id="8">
Main 2
<ul class="sub-tab">
<li data-id="9">
Main 2 Sub 1
<ul class="sub-tab">
<li data-id="14">Sub 2</li>
<li data-id="15">Sub 2</li>
</ul>
</li>
</ul>
</li>
<li data-id="3">
Main 3
<ul class="sub-tab">
<li data-id="25">
Main 3 Sub 1
<ul class="sub-tab">
<li data-id="17">Sub 2</li>
<li data-id="18">Sub 2</li>
</ul>
</li>
</ul>
</li>
</ul>

List order rearrangement using jquery

Can anyone please help me on this problem.
I have a list order like:
<ul>
<li class="parent">Parent item 1</li>
<li class="no-parent">item 1</li>
<li class="no-parent">item 2</li>
<li class="parent">Parent item 2</li>
<li class="no-parent">item 3</li>
<li class="no-parent">item 4</li>
<li class="no-parent">item 5</li>
<li class="parent">Parent item 3</li>
<li class="no-parent">item 6</li>
<li class="no-parent">item 7</li>
</ul>
I want this like :
<ul>
<li class="parent">Parent item 1</li>
<div>
<li class="no-parent">item 1</li>
<li class="no-parent">item 2</li>
</div>
<li class="parent">Parent item 2</li>
<div>
<li class="no-parent">item 3</li>
<li class="no-parent">item 4</li>
<li class="no-parent">item 5</li>
</div>
<li class="parent">Parent item 3</li>
<div>
<li class="no-parent">item 6</li>
<li class="no-parent">item 7</li>
</div>
</ul>
is this possible to make it using jQuery?
Thanks in Advance.
If you are able to accept a semantically correct nested list, you could achieve that by using jQuery to loop through each .parent element and select each item after it until it hits the next .parent item using nextUntil(). Then, you create a new <ul> and append those children to it and then append the new <ul> to the parent <li>.
// Select all of the .parents and loop through them.
$('.parent').each(function() {
// Select all the following siblings starting from this .parent element until you reach the next .parent element.
var $children = $(this).nextUntil('.parent');
// Take the results and append them to a new ul element and then append that ul element to the current .parent li element.
$children.appendTo($('<ul>').appendTo($(this)));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="parent">Parent item 1</li>
<li class="no-parent">item 1</li>
<li class="no-parent">item 2</li>
<li class="parent">Parent item 2</li>
<li class="no-parent">item 3</li>
<li class="no-parent">item 4</li>
<li class="no-parent">item 5</li>
<li class="parent">Parent item 3</li>
<li class="no-parent">item 6</li>
<li class="no-parent">item 7</li>
</ul>

DOM traversal from a span element inside an anchor to list

I can't figure how to travers the DOM, starting from <span class = "open-menu-link">, I want to reach <ul class="sub-menu"> .
The script
<script> $('.open-menu-link').click(function(e){
alert(e.currentTarget);
});
</script>
return a Object HTMLSpanElement, but if I code e.currentTarget.parentNode; it returns http://localhost/mysite/home.php. Doing e.currentTarget.children; I get Object HTMLCollection, but if I try e.currentTarget.children[1] I get undefined... so how can I reach <ul class="sub-menu">?
The snippet is the follow:
<ul class="menu">
<li>Work</li>
<li class="menu-item-has-children">Haschildren <span class = "open-menu-link">+</span>
<ul class="sub-menu">
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
</ul>
</li>
<li>Careers</li>
<li>Contact</li>
</ul>
$(function() {
$('.open-menu-link').click(function(e){
console.log(e.target.parentNode.nextElementSibling);
console.log(e.target.parentNode.parentNode.children[1]);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li>Work</li>
<li class="menu-item-has-children">
Haschildren <span class="open-menu-link">+</span>
<ul class="sub-menu">
<li>Child 1</li>
<li>Child 2</li>
<li>Child 3</li>
</ul>
</li>
<li>Careers</li>
<li>Contact</li>
</ul>
There are couple of options:
$('.open-menu-link').click(function(e){
console.log(e.target.parentNode.nextElementSibling);
console.log(e.target.parentNode.parentNode.children[1]);
});
The <span class = "open-menu-link"> in your code has only one child i.e text node + this is the reason why e.currentTarget.children[1] is giving you undefined.
Coming to the dom traversal, you should start with node <li class="menu-item-has-children"> . Well that is what I can infer from your question.
You need to use preventDefault() because you'r class is a link. By clicking, it'll redirect you to the link.
$('.open-menu-link').click(function(e) {
console.log($(this).parent().next())
e.preventDefault()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
<li>Work
</li>
<li class="menu-item-has-children">
Haschildren <span class = "open-menu-link">+</span>
<ul class="sub-menu">
<li>Child 1
</li>
<li>Child 2
</li>
<li>Child 3
</li>
</ul>
</li>
<li>Careers
</li>
<li>Contact
</li>
</ul>

Drag nested li doesn't work

I am using jquery-ui for sort and drag https://johnny.github.io/jquery-sortable/.. But it doesn't append in li..
The code is like
$("#example3 ul").sortable({
placeholder: "ui-state-highlight",
connectWith: '#example3 ul'
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<div id="example3">
<ul>
<li >Item 1
<ul>
<li>Item 1 1</li>
<li>Item 1 2</li>
<li>Item 1 3</li>
</ul>
</li>
<li >Item 2<ul></ul></li>
<li >Item 3<ul></ul></li>
<li >Item 4<ul></ul></li>
</ul>
</div>
If I drag item 3 to under item 2 then it doesn't work..How can I solve this?? and also I have to detect that which li goes under which li.. please Help..
Problem is, that the empty 'ul'-Tags does not have any space and are hidden (size is equals zero). Just add a small padding to each element, then you can drag your element there. Here, have a look:
$("#example3 ul").sortable({
placeholder: "ui-state-highlight",
connectWith: '#example3 ul'
});
#example3 ul{
padding-bottom: 0.3em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
<div id="example3">
<ul>
<li >Item 1
<ul>
<li>Item 1 1</li>
<li>Item 1 2</li>
<li>Item 1 3</li>
</ul>
</li>
<li >Item 2<ul></ul></li>
<li >Item 3<ul></ul></li>
<li >Item 4<ul></ul></li>
</ul>
</div>

Mega Menu built from scratch - Jquery reSizing

I am building a mega menu and would like for it to be at lightweight as possible.
HTML:
<div id="menu-wrapper">
<ul class="nav">
<li>Category A
<div class="block">
<h3>Category A</h3>
<div class="nav-column">
<ul>
<li>Sub-Category
<div class="sub-column">
<ul>
<li>Link #1</li>
<li>Link #2</li>
<li>Link #3</li>
</ul>
</div>
</li>
<li>Sub-Category
<div class="sub-column">
<ul>
<li>Link #1</li>
<li>Link #2</li>
<li>Link #3</li>
<li>Link #4</li>
<li>Link #5</li>
</ul>
</div>
</li>
<li>Sub-Category
<div class="sub-column">
<ul>
<li>Link #1</li>
<li>Link #2</li>
<li>Link #3</li>
<li>Link #4</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="home">
<h3>Featured Products</h3>
<div class="featured">
<p>Lorum Ipsum...</p>
</div>
</div>
</div>
</li>
<li>Category B
<div class="block">
<h3>Category B</h3>
<div class="nav-column">
<ul>
<li>Sub-Category
<div class="sub-column">
<ul>
<li>Link #1</li>
<li>Link #2</li>
<li>Link #3</li>
</ul>
</div>
</li>
<li>Sub-Category
<div class="sub-column">
<ul>
<li>Link #1</li>
<li>Link #2</li>
<li>Link #3</li>
<li>Link #4</li>
<li>Link #5</li>
</ul>
</div>
</li>
<li>Sub-Category
<div class="sub-column">
<ul>
<li>Link #1</li>
<li>Link #2</li>
<li>Link #3</li>
<li>Link #4</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="home">
<h3>Featured Products</h3>
<div class="featured">
<p>Lorum Ipsum...</p>
</div>
</div>
</div>
</li>
<li>Category C
<div class="block">
<h3>Category C</h3>
<div class="nav-column">
<ul>
<li>Sub-Category
<div class="sub-column">
<ul>
<li>Link #1</li>
<li>Link #2</li>
<li>Link #3</li>
</ul>
</div>
</li>
<li>Sub-Category
<div class="sub-column">
<ul>
<li>Link #1</li>
<li>Link #2</li>
<li>Link #3</li>
<li>Link #4</li>
<li>Link #5</li>
</ul>
</div>
</li>
<li>Sub-Category
<div class="sub-column">
<ul>
<li>Link #1</li>
<li>Link #2</li>
<li>Link #3</li>
<li>Link #4</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="home">
<h3>Featured Products</h3>
<div class="featured">
<p>Lorum Ipsum...</p>
</div>
</div>
</div>
</li>
</ul>
</div>
Of course there are many more nested onordered lists, but that is your basic heirarchy.
What I'm trying to do is create a jQuery function that will perform a height check:
When you HOVER on a .nav > li > a, the jQuery checks the heights of ALL .sub-columns AND .home that fall under it, and ONLY THOSE, when you roll off, the height check resets, so you can check the next .nav > li > a.
I was recently pointed to THIS possible solution, but it was checking ALL of the .sub-columns and not just the .sub-columns that fall under the .nav > li > a I was hovering over.
I feel that I'm 90% of the way there, but I'm just not pointing or reference the correct parent-child-sibling elements to make it work properly.
Thanks in advance.
If i understood right you want something like the following.
$(".nav > li > a").hover(function(){
var subColumns = $(this).next().find(".sub-column");
});
The next() function gets the div block(nav-column) which contains all the sub-columns for that link. Then i did a find() since it's several elements nested under that.
Here's a fiddle that alerts out the number of sub-columns it finds.

Categories

Resources