I am trying to write a function that will combine two children ul#level_2and append them to their parent li#level_1 within a dropdown #navigation.
I currently have the following which does the job, but it means I have to manually target each category. I'm sure there is a far shorter way to produce the same results with very little code.
$('li#furniture ul.level_2').children('li').appendTo('li#furniture ul.level_2:first');
$('li#furniture ul.level_2').children('li').not(':first').remove();
Here is a shortened version of my current html structure & below is the desired result:
Simple Current HTML
<div id="navigation">
<ul id="level_1">
<li class="level_1">
<div class="subnav_wrapper">
<ul class="level_2">
<li class="level_2">
Link A
</li>
</ul>
<ul class="level_2">
<li class="level_2">
Link B
</li>
</ul>
</div>
</li>
</ul>
</div>
Desire HTML
<div id="navigation">
<ul id="level_1">
<li class="level_1">
<ul class="level_2">
<li class="level_2">
Link A
</li>
<li class="level_2">
Link B
</li>
</ul>
</li>
</ul>
</div>
Full Detailed HTML
<div id="navigation">
<ul id="level_1">
<li class="level_1 furniture">
Furniture
<div class="subnav_wrapper">
<ul class="level_2">
<li class="level_2 sofa">
Sofa
</li>
</ul>
<ul class="level_2">
<li class="level_2 bed">
Bed
</li>
</ul>
</div>
</li>
<li class="level_1 bathroom">
Bathroom
<div class="subnav_wrapper">
<ul class="level_2">
<li class="level_2 shower">
<a href="#">Shower/a>
</li>
</ul>
<ul class="level_2">
<li class="level_2 bath">
Bath
</li>
</ul>
</div>
</li>
</ul>
</div>
This should do what you need.
var wrapper = $(".subnav_wrapper").contents();
$(".subnav_wrapper").replaceWith(wrapper );
$('ul.level_2').children('li').appendTo('ul.level_2:first');
$('ul.level_2').not(':first').remove();
JSFIDDLE DEMO
Related
I need to have a responsive sidebar navigation (as part of making the website responsive) for a multilevel menu of depth 3. The html markup is as below,
<nav>
<div data-level="1">
<ul>
<li class="main-menu">
Level1
<div data-level="2">
<ul>
<li class="submodule">
example1.1
<div data-level="3">
<ul>
<li>example1.1.1</li>
<li>example1.1.2</li>
<li>example1.1.3</li>
</ul>
</div>
</li>
<li class="submodule">
example1.2
<div data-level="2">
<ul>
<li>example1.2.1</li>
<li>example1.2.2</li>
<li>example1.2.3</li>
</ul>
</div>
</li>
<li class="submodule">
example1.3
<div data-level="2">
<ul>
<li>example1.3.1</li>
<li>example1.3.2</li>
<li>example1.3.3</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li>
Level2
<div data-level="2">
<ul>
<li>
example2.1
<div data-level="3">
<ul>
<li>example2.1.2</li>
<li>example2.1.3</li>
<li>example2.1.4</li>
</ul>
</div>
</li>
<li>
example2.2
<div data-level="2">
<ul>
<li>example2.2.1</li>
<li>example2.2.2</li>
<li>example2.2.3</li>
</ul>
</div>
</li>
<li>
example2.3
<div data-level="2">
<ul>
<li>example2.3.1</li>
<li>example2.3.2</li>
<li>example2.3.4</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</nav>
At first menu shows only the top level,
Level1
Level2
When Level1 is clicked menu should show,
Back to Main Menu
example 1.1
example 1.2
When example1.1 is clicked,
Back to sublevel
example1.1.1
example1.1.2
example1.1.3
Each of back button takes to the menu before.
How to do the navigation using JS/jQuery?
It was necessary to adjust your navigation a little bit - the navigation for Level 2 was missing the submodule class. In addition you could consider to adjust your usage of <div data-level="3"> as you only use it for the 2nd and 3rd sublevel navigation while the 1st sublevel is in a <div data-level="2">. The following navigation fulfills your requirements while it is not complete - you can adjust it so a visible sublevel navigation gets toggled when the main navigation gets clicked. I already took care about the issue to only have one main navigation and submodule navigation visible at the same time.
$(".main-menu").on("click", function() {
if ($(".main-menu").not(this).find(".submodule").is(":visible")) {
$(".main-menu").not(this).find(" > div[data-level='2'], .submodule").hide();
}
$(this).find(" > div[data-level='2'], .submodule").toggle();
});
$(".submodule").on("click", function(e) {
e.stopPropagation();
$(".submodule").not(this).each(function() {
if ($(this).find(" > div[data-level='3'], > div[data-level='2']").is(":visible")) {
$(this).find(" > div[data-level='3'], > div[data-level='2']").hide();
}
});
$(this).find(" > div[data-level='3'], > div[data-level='2']").toggle();
});
$(".submodule.back").on("click", function(e) {
e.stopPropagation();
$(this).closest(".main-menu").find(" > div[data-level='2'], .submodule").hide();;
});
$(".back").not(".submodule").on("click", function(e) {
e.stopPropagation();
$(this).closest(".submodule").find(" > div[data-level='3'], > div[data-level='2']").hide();
});
div[data-level ="2"]{
display:none;
}
div[data-level ="3"]{
display:none;
}
.submodule {
display:none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<nav>
<div data-level="1">
<ul>
<li class="main-menu">
Level1
<div data-level="2">
<ul>
<li class="submodule back">
Back to main menu
</li>
<li class="submodule">
example1.1
<div data-level="3">
<ul>
<li class="back">Back to sublevel</li>
<li>example1.1.1</li>
<li>example1.1.2</li>
<li>example1.1.3</li>
</ul>
</div>
</li>
<li class="submodule">
example1.2
<div data-level="2">
<ul>
<li class="back">Back to sublevel</li>
<li>example1.2.1</li>
<li>example1.2.2</li>
<li>example1.2.3</li>
</ul>
</div>
</li>
<li class="submodule">
example1.3
<div data-level="2">
<ul>
<li class="back">Back to sublevel</li>
<li>example1.3.1</li>
<li>example1.3.2</li>
<li>example1.3.3</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li class="main-menu">
Level2
<div data-level="2">
<ul>
<li class="submodule back">
Back to main menu
</li>
<li class="submodule">
example2.1
<div data-level="3">
<ul>
<li class="back">Back to sublevel</li>
<li>example2.1.2</li>
<li>example2.1.3</li>
<li>example2.1.4</li>
</ul>
</div>
</li>
<li class="submodule">
example2.2
<div data-level="2">
<ul>
<li class="back">Back to sublevel</li>
<li>example2.2.1</li>
<li>example2.2.2</li>
<li>example2.2.3</li>
</ul>
</div>
</li>
<li class="submodule">
example2.3
<div data-level="2">
<ul>
<li class="back">Back to sublevel</li>
<li>example2.3.1</li>
<li>example2.3.2</li>
<li>example2.3.4</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
</ul>
</div>
</nav>
I have a menu populating from MySQL table and PHP up to some nested sub levels.
my menu like this:
A
B
C
If click on A first time it is showing all the child elements and again I click child elements of A it displaying child elements also fine.
But the problem is when I click on the B after open all the levels items of A it shows B sub elements fine. But again if I click A it showing all the elements except child child elements also.
I used jQuery for this.
So I want to bring back to the original state? ( only expand the top child elements, not the sub child elements ),
how to do that?
//this is my jquery code for elements clickable in menu.
$(document).ready(function() {
$(".lichild").parent().hide();
$(".limain").click(function() {
$(this).children('ul').show();
$(this).siblings(".limain").children('ul').hide();
});
$(".lichild").click(function() {
$(this).children('ul').show();
$(this).siblings().children('ul').hide()
});
});
<!-- This is the html I am generating using a PHP function -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="limain">A
<ul>
<li class="lichild">A1
<ul>
<li class="lichild">a2</li>
<li class="lichild">a1
<ul>
<li class="lichild">aaaaaa</li>
<li class="lichild">abbbbbb</li>
</ul>
</li>
</ul>
</li>
<li class="lichild">A2</li>
<li class="lichild">A3</li>
<li class="lichild">A4</li>
<li class="lichild">A5</li>
</ul>
<li class="limain">B
<ul>
<li class="lichild">B1</li>
<li class="lichild">B2</li>
</ul>
</li>
<li class="limain">C
<ul>
<li class="lichild">C1</li>
<li class="lichild">C2</li>
<li class="lichild">C3</li>
<li class="lichild">A6
<ul>
<li class="lichild">A8
<ul>
<li class="lichild">A10
<ul>
<li class="lichild">A13
</li>
<li class="lichild">A14
</li>
</ul>
</li>
<li class="lichild">A11
</li>
</ul>
</li>
<li class="lichild">A9
</li>
</ul>
</li>
<li class="lichild">A7
</li>
</ul>
</li>
<li class="limain">D
<ul>
<li class="lichild">D1</li>
<li class="lichild">D2
</li>
</ul>
</li>
</ul>
Use find inside siblings and hide it.
$(".lichild").parent().hide();
$(".limain").click(function() {
$(this).children('ul').show();
$(this).siblings(".limain").find('ul').hide(); // Change in this line
});
$(".lichild").click(function() {
$(this).children('ul').show();
$(this).siblings().children('ul').hide()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<ul>
<li class="limain">
A
<ul>
<li class="lichild">
A1
<ul>
<li class="lichild">a2</li>
<li class="lichild">
a1
<ul>
<li class="lichild">aaaaaa</li <li class="lichild">abbbbbb</li>
</ul>
</li>
</ul>
</li>
<li class="lichild">A2</li>
<li class="lichild">A3</li>
<li class="lichild">A4</li>
<li class="lichild">A5</li>
</ul>
<li class="limain">
B
<ul>
<li class="lichild">B1</li>
<li class="lichild">B2</li>
</ul>
</li>
<li class="limain">
C
<ul>
<li class="lichild">C1</li>
<li class="lichild">C2</li>
<li class="lichild">C3</li>
<li class="lichild">
A6
<ul>
<li class="lichild">
A8
<ul>
<li class="lichild">
A10
<ul>
<li class="lichild">A13
</li>
<li class="lichild">A14
</li>
</ul>
</li>
<li class="lichild">A11
</li>
</ul>
</li>
<li class="lichild">A9
</li>
</ul>
</li>
<li class="lichild">A7
</li>
</ul>
</li>
<li class="limain">
D
<ul>
<li class="lichild">D1</li>
<li class="lichild">D2
</li>
</ul>
</li>
</ul>
$(document).ready(function () {
$(".lichild").parent().hide();
$(".limain").click(function () {
$(this).children('ul').show();
$(this).siblings().find('ul').hide();
});
$(".lichild").click(function () {
$(this).children('ul').show();
$(this).siblings('li').find('ul').hide()
});
});
I would like to add some html content within a selected div like most of the plugins are.
Eg:
<div id="selected-div">
</div>
$('#selected-div').foo();
When the div (selected-div) is passed to the function, I would like to add the below html content inside that div (selected-div).
<div id="lorem-ipsum-wrapper">
<ul id="lorem-ipsum-main">
<li id="btn-header-wrapper" class="main-btn">
T
<ul>
<li>
T1
</li>
<li>
T2
</li>
<li>
T3
</li>
<li>
T4
</li>
</ul>
</li>
<li class="main-btn">
<b>E</b>
</li>
<li id="btn-justify-wrapper" class="main-btn">
Gender
<ul>
<li>
M
</li>
<li>
F
</li>
<li>
other
</li>
</ul>
</li>
<li class="main-btn" id="btn-list-wrapper">
List
<ul>
<li>
List 1
</li>
<li>
List 2
</li>
</ul>
</li>
<span class="clear_both"></span>
</ul>
</div>
Demo at codepen.
Which after execution should become like this
<div id="selected-div">
<div id="lorem-ipsum-wrapper">
<ul id="lorem-ipsum-main">
...
...
...
</ul>
</div>
</div>
How can I achieve this feature using jquery? Your help and guidance will be very much appreciated. Thank you.
Use .html()
$("#selected-div").html('<div id="lorem-ipsum-wrapper">..');
or .load()
$("#selected-div").load("/path/to/html")
var data = '<div id="lorem-ipsum-wrapper">
<ul id="lorem-ipsum-main">
<li id="btn-header-wrapper" class="main-btn">
T
<ul>
<li>
T1
</li>
<li>
T2
</li>
<li>
T3
</li>
<li>
T4
</li>
</ul>
</li>
<li class="main-btn">
<b>E</b>
</li>
<li id="btn-justify-wrapper" class="main-btn">
Gender
<ul>
<li>
M
</li>
<li>
F
</li>
<li>
other
</li>
</ul>
</li>
<li class="main-btn" id="btn-list-wrapper">
List
<ul>
<li>
List 1
</li>
<li>
List 2
</li>
</ul>
</li>
<span class="clear_both"></span>
</ul>
</div>';
$("#selected-div").html(data);
You can use the JQuery text() method like this
$("#selected-div").text($('#lorem-ipsum-wrapper').text());
Here is the JS code :
$(document).ready(function(){
$("#selecteddiv").load('add.html');
});
and in add.html, you can have your html code which you want to append.
here is the working Plnkr link.
hope it helps you
append would also be an option
http://api.jquery.com/append/
$("#selected-div").append($("<h1>Some content</h1>"));
I've this code
$('.item_has_children a').first().css("color","red");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<ul>
<li class="item_has_children">
Category 1
<ul class="submenu">
<li class="menu_item">
Hello
</li>
<li class="menu_item">
Hello
</li>
</ul>
</li>
<li class="item_has_children">
Category 2
<ul class="submenu">
<li class="menu_item">
Hello
</li>
<li class="menu_item">
Hello
</li>
</ul>
</li>
</ul>
I want to color the first links : "category 1" and "category 2".
I try but only the first link is coloring red.
Thanks for your help !
You can use immediate child selector > to target immediate anchor elements both using CSS and jquery.
Using CSS:
.item_has_children > a{color:red;}
Working Demo using CSS:
.item_has_children>a {
color: red
}
<ul>
<li class="item_has_children">
Category 1
<ul class="submenu">
<li class="menu_item">
Hello
</li>
<li class="menu_item">
Hello
</li>
</ul>
</li>
<li class="item_has_children">
Category 2
<ul class="submenu">
<li class="menu_item">
Hello
</li>
<li class="menu_item">
Hello
</li>
</ul>
</li>
</ul>
Using Jquery:
$('.item_has_children > a').css("color","red");
Working Demo using Jquery:
$('.item_has_children > a').css("color","red")
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="item_has_children">
Category 1
<ul class="submenu">
<li class="menu_item">
Hello
</li>
<li class="menu_item">
Hello
</li>
</ul>
</li>
<li class="item_has_children">
Category 2
<ul class="submenu">
<li class="menu_item">
Hello
</li>
<li class="menu_item">
Hello
</li>
</ul>
</li>
</ul>
No need to use javascript for this, you can use CSS.(Better Performance and User Experience)
.item_has_children > a {
color: red;
}
> here will select direct children of .item_has_children element.
Demo:
.item_has_children>a {
color: red;
}
<ul>
<li class="item_has_children"> Category 1
<ul class="submenu">
<li class="menu_item"> Hello
</li>
<li class="menu_item"> Hello
</li>
</ul>
</li>
<li class="item_has_children"> Category 2
<ul class="submenu">
<li class="menu_item"> Hello
</li>
<li class="menu_item"> Hello
</li>
</ul>
</li>
</ul>
operator > is used for select immediate started DOM element of selector.
$("li.item_has_children > a").css("color","red");
I would like to add that class "last-item" every last li.
Im trying this but without sucess:
<script>
$(".cbp-tm-submenu .product-categories li .children li:last-child").addClass("last-item");
<script>
I tried put on header and on footer.
HTML:
<ul class="cbp-tm-submenu">
<img class="backgroundtooltiptop" alt="background tooltip" src="http://localhost:8888/era420/wp-content/themes/era420/images/tooltipbackgroundtop.png">
<li id="woocommerce_product_categories-4" class="widget woocommerce widget_product_categories">
<ul class="product-categories">
<li class="cat-item cat-item-16 current-cat cat-parent">
Lançamentos
<ul class="children">
<li class="cat-item cat-item-17">
teste
</li>
<li class="cat-item cat-item-18">...</li>
<li class="cat-item cat-item-19">...</li>
</ul>
</li>
</ul>
</li>
<img class="backgroundtooltipbot" alt="background tooltip bot" src="http://localhost:8888/era420/wp-content/themes/era420/images/tooltipbackgroundbot.png">
</ul>
This is enough:
$(".cbp-tm-submenu li:last-child").addClass("last-item");