Jquery Counting child in nested list, Search and Expand Collapse - javascript

I am trying to develop expand collapse, search in nested list and count of child lists but I don't know how to implement all these.
HTML
<div class="searchSection">
<form action="#" novalidate="novalidate">
<input type="text" placeholder="search here...">
</form>
<ul id="orgCat">
<li parent-id="" li-id="1">
<div class="expandBtn"><span id="count"></span>India</div>
<ul>
<li parent-id="1" li-id="2">
<div class="expandBtn"><span id="count"></span>Ap</div>
<ul>
<li parent-id="2" li-id="7">
<div class="expandBtn"><span id="count"></span>vag</div>
</li>
<li parent-id="2" li-id="8">
<div class="expandBtn"><span id="count"></span>tirupati</div>
</li>
</ul>
</li>
<li parent-id="1" li-id="3">
<div class="expandBtn"><span id="count"></span>TN</div>
<ul>
<li parent-id="3" li-id="9">
<div class="expandBtn"><span id="count"></span>chena</div>
</li>
<li parent-id="3" li-id="10">
<div class="expandBtn"><span id="count"></span>India1</div>
</li>
<li parent-id="3" li-id="11">
<div class="expandBtn"><span id="count"></span>India2</div>
</li>
<li parent-id="3" li-id="12">
<div class="expandBtn"><span id="count"></span>India3</div>
</li>
<li parent-id="3" li-id="13">
<div class="expandBtn"><span id="count"></span>India4</div>
</li>
</ul>
</li>
<li parent-id="1" li-id="4">
<div class="expandBtn"><span id="count"></span>TS</div>
<ul>
<li parent-id="4" li-id="5">
<div class="expandBtn"><span id="count"></span>Hyd</div>
</li>
<li parent-id="4" li-id="6">
<div class="expandBtn"><span id="count"></span>warangal</div>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
When I click on the 'div' tag it should be expand or collapse. Count of children should be appear in 'span' tag. When I search an element, it should appear from it's root directory. I hope you guys understand.
JSFIDDLE
Jquery
// counting leafs
$('.searchSection').each(function(){
$('#count').text($('ul').children().length);
})
above jquery displaying total 'li' elements but i need to display number of li elements in each ul.
I don't know how to implement Collapse and Expand functionality. I am new to Jquery.

This code should give you the expand and colapse and count of all list items under a parent.
//Search query
$("input").keyup(function() {
var searchTerms = $(this).val();
$('li').each(function() {
var $li = $(this);
var hasMatch = searchTerms.length == 0 || $li.text().toLowerCase().indexOf(searchTerms.toLowerCase()) > 0;
$li.toggle(hasMatch);
if ($li.is(":hidden")) {
$li.closest("ul").show();
}
});
});
var $expandBtns = $(".expandBtn");
$expandBtns.each(function() {
var $span = $(this).find("span#count");
var $subList = $(this).siblings("ul").find("li")
$span.text($subList.length)
});
$expandBtns.on("click", function() {
var $subList = $(this).siblings("ul");
if ($subList.is(":visible")) {
$subList.hide();
} else {
$subList.show();
}
})

Related

jQuery switching lists with same class

I created a bit complex list and I wish after clicking on element with class ".recipes", display it inside paragraph but after clicking on button prev or next, I wish to switch to previous or next element with same class name. I know already how to switch the list if they are next to each other but after putting them inside different parents it seems more complicated:
<div>
<button class="prev">prev</button>
<button class="next">next</button>
<p class="showRecipies"></p>
<ul class="listOfRecipies">
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Drinks</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Vegetables</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Meat</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Fruits</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Others</li>
</ul>
</li>
</ul>
</div>
To show clicked element:
$(".recipies").on("click", function() {
$(".recipies.active").add($(this)).toggleClass("active");
var recipieValue = $(this).text();
var showRecipies = document.querySelector(".showRecipies");
showRecipies.innerHTML = recipieValue;
});
and to show previous element with class "recipes" I got from another person on this forum is here however because classes have different parents now, it doesn't work, I thought that i can add more parents() and because of that find previous or next ".recipes" but it didn't work out:
$(".prev").click(function() {
var isFirst = $(".recipies.active").is(":first-child");
if(isFirst){
$(this).parent().find(".recipies:last").trigger("click");
} else {
$(".recipies.active").prev().trigger("click");
}
});
Check this out:
$(".recipies").on("click", function() {
$(".recipies.active").add($(this)).toggleClass("active");
var recipieValue = $(this).text();
var showRecipies = document.querySelector(".showRecipies");
showRecipies.innerHTML = recipieValue;
});
$(".prev").click(function() {
var isFirst = $(".recipies.active").text() == $($(".recipies").get(0)).text();
if (isFirst) {
$(this).parent().find(".recipies:last").trigger("click");
} else {
$(".recipies.active").parent().parent().prev().find(".recipies").trigger("click");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<button class="prev">prev</button>
<button class="next">next</button>
<p class="showRecipies"></p>
<ul class="listOfRecipies">
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Drinks</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Vegetables</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Meat</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Fruits</li>
</ul>
</li>
<li>
<ul class="particularRecipie">
<li class="timeOfPreparation">3:20</li>
<li class="recipies">Others</li>
</ul>
</li>
</ul>
</div>

How to add a new list item before another specific list item with class?

Using jQuery, I need to add a new list item within the below UL but it needs to be before the last list item that has the class="more".
<div class="nav nav-tabs">
<ul class="nav nav-tabs sub-nav" >
<li class="hor-menu">
<span class="class-a" >AA</span>
</li>
<li class="hor-menu">
<span class="class-a" >BB</span>
</li>
<li class="hor-menu">
<span class="class-a" >CC</span>
</li>
**<<< --- new list item entry to go here --- >>>**
<li class="more" style="display: none;">
<span>...</span>
<ul id="overflow"></ul>
</li>
</ul>
</div>
I have tried the following:
$("#nav-tabs ul").append('<li class="hor-menu"><span class="class-a" >DD</span></li>')
but am unsure how to insert it before the last li.more item.
First option
$('.more').before('<li class="hor-menu"><span class="class-a" >DD</span></li>');
Second option
First let's get the position of the more class.
var pos = $('nav-tabs > li').index($('.more'));
And then add it to the DOM
$('ul > li:eq('+pos+')')
.before('<li class="hor-menu"><span class="class-a" >DD</span></li>');
You can use the :last pseudo selector like this to select the last element of a set
$("li.more:last")
then you can use before to insert it before the last li more item.
$("li.more:last").before('<li class="hor-menu"><span class="class-a" >DD</span></li>');
Here is a working JSfiddle:
https://jsfiddle.net/mervinsamy/0n4g51hk/5/
I also added code snippet here:
$(document).ready(function(){
$("li.more:last").before('<li class="hor-menu"><span class="class-a" >DD</span></li>');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="nav nav-tabs">
<ul class="nav nav-tabs sub-nav" >
<li class="hor-menu">
<span class="class-a" >AA</span>
</li>
<li class="hor-menu">
<span class="class-a" >BB</span>
</li>
<li class="hor-menu">
<span class="class-a" >CC</span>
</li>
<li class="more">
<span>...</span>
<ul id="overflow"></ul>
</li>
<li class="more">
<span>...</span>
<ul id="overflow"></ul>
</li>
<li class="more">
<span>...</span>
<ul id="overflow"></ul>
</li>
<li class="more">
<span>...</span>
<ul id="overflow"></ul>
</li>
</ul>
</div>

Get an list of datas and store in array in jquery

I have a struture of html like below,This is what there will be list of option
<div class='col-sm-4'>
<div id='selectiondata' class="panel panel-default">
<div class="panel-body">
<h2 class='headerText'>Selections</h2>
<p style="font-size: 14px;">Select only that apply to you.</p>
<ul>
<li id="item1" data-cat="fruits">Banana</li>
<li id="item2" data-cat="fruits">Pineapple</li>
<li id="item3" data-cat="fruits">Oragne</li>
<li id="item4" data-cat="fruits">MAngo</li>
<li id="item5" data-cat="Vegetables">Beans</li>
<li id="item6" data-cat="fruits">jackfruit</li>
<li id="item7" data-cat="Vegetables">carrot</li>
</ul>
</div>
</div>
</div>
From above div when user clicks it moves to adjacent div,this has a sturcture like below.
<div id="categories" class="panel-default">
<div class="panel-body">
<div class="alert alert-info hidden endMsg">Your data categorized. Once done, click the next button to continue.</div>
<h2 class='headerText'>Categories</h2>
<ul>
<li id="cat-fruits">
<span>fruits</span>
<ul>
<li id="item5" data-cat="fruits">MAngo</li>
<li id="item1" data-cat="fruits">Banana</li>
<li id="item3" data-cat="fruits">Oragne</li>
<li class="no-expenses" style="display: none;">No items selected</li>
</ul>
</li>
<li id="cat-Vegetables">
<span>Vegetables</span>
<ul>
<li id="item4" data-cat="Vegetables">Beans</li>
<li class="no-expenses" style="display: none;">No items selected</li>
</ul>
</li>
<li id="cat-dolls">
<span>dolls</span>
<ul>
<li class="no-expenses">No items selected</li>
</ul>
</li>
<li id="cat-medical">
<span>Medical</span>
<ul>
<li class="no-expenses">No items selected</li>
</ul>
</li>
</ul>
</div>
</div>
jquery function to fetch array of data
function saveData() {
userData = [];
$('#categories ul li ul li.selected').each(function(index, element) {
if ($.inArray($(this).text(), userData) < 0) {
userData.push($(this).html());
}
});
I want to fetch datas like
[MAngo,banana,Oragne,beans]
Here i will be having two divs,one div shows list of selection as shown in below figure, when user click on particular elemnet, that elemnet will be moved to next adjacent div(categories).I want to get this datas.
----------- ----------
|Banana | | MAngo |
|Pineapple | | Banana |
|Oragne | | Oragne |
|MAngo | | Beans |
|Beans | |_________|
|jackfruit |
|carrot |
-----------
The above jquery used is not fetching any data from html, How could i acheive this. Please help me.
Would it be easier to add each item to the array when that item is clicked (and doesn't exist yet in the array)?
var arr = [];
$("#categories [id^=item]").click(function() {
if(arr.indexOf($(this).html())<0) arr.push($(this).html());
})
console.log(arr);
If you want to use data attr in #nicael code use
var arr = [];
$("#categories").data("cat").each(function() {
arr.push($(this).html());
})
console.log(arr);
var arr = [];
$('li[data-cat]').each(function() {
arr.push($(this).html());
});
console.log(arr);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="categories" class="panel-default">
<div class="panel-body">
<div class="alert alert-info hidden endMsg">Your data categorized. Once done, click the next button to continue.</div>
<h2 class='headerText'>Categories</h2>
<ul>
<li id="cat-fruits">
<span>fruits</span>
<ul>
<li id="item1" data-cat="fruits">Mango</li>
<li id="item2" data-cat="fruits">Banana</li>
<li id="item3" data-cat="fruits">Oragne</li>
<li class="no-expenses" style="display: none;">No items selected</li>
</ul>
</li>
<li id="cat-Vegetables">
<span>Vegetables</span>
<ul>
<li id="item4" data-cat="Vegetables">Beans</li>
<li class="no-expenses" style="display: none;">No items selected</li>
</ul>
</li>
<li id="cat-dolls">
<span>dolls</span>
<ul>
<li class="no-expenses">No items selected</li>
</ul>
</li>
<li id="cat-medical">
<span>Medical</span>
<ul>
<li class="no-expenses">No items selected</li>
</ul>
</li>
</ul>
</div>
</div>

display none if null using data-id

I have a menu which list items which display the the content on the other list.
MENU
<ul id="gallery-list" style="display: none;">
<li class="close"></li>
<li data-id="9425"><strong>item 1</strong></li>
<li data-id="9426"><strong>item 2</strong></li>
<li data-id="9488"><strong>item 3</strong></li>
<li data-id="9489"><strong>item 4</strong></li>
<li data-id="9495"><strong>item 5</strong></li>
<li data-id="9427"><strong>item 6</strong></li>
</ul>
CONTENT:
<ul id="gallery-container">
<li data-id="9425">
<h3 style="display: none;">Item 1</h3>
<div class="content">Content here</div>
</li>
<li data-id="9426">
<h3 style="display: none;">Item 2</h3>
</li>
<li data-id="9488">
<h3 style="display: none;">Item 3</h3>
</li>
<li data-id="9489">
<h3 style="display: none;">Item 4</h3>
</li>
<li data-id="9495">
<h3 style="display: none;">Item 5</h3>
<div class="content">Content here</div>
</li>
<li data-id="9427">
<h3 style="display: none;">Item 6</h3>
<div class="content">Content here</div>
</li>
</ul>
In the content some have .content in the li. How can I use the data-id in that to hide the item in the menu section? Basically items in the menu should only be display if it has a .content
OUTPUT of the MENU should be like this.
<ul id="gallery-list" style="display: none;">
<li class="close"></li>
<li data-id="9425"><strong>item 1</strong></li>
<li data-id="9495"><strong>item 5</strong></li>
<li data-id="9427"><strong>item 6</strong></li>
</ul>
Or this should be okay too.
<ul id="gallery-list" style="display: none;">
<li class="close"></li>
<li data-id="9425"><strong>item 1</strong></li>
<li data-id="9425" style="display:none;"><strong>item 2</strong></li>
<li data-id="9425" style="display:none;"><strong>item 3</strong></li>
<li data-id="9425" style="display:none;"><strong>item 4</strong></li>
<li data-id="9495"><strong>item 5</strong></li>
<li data-id="9427"><strong>item 6</strong></li>
</ul>
Take not that Item in the content are always display:none; onload trigger.
Also using this script:
$("#gallery-list li").click(function() {
var id = $(this).data('id');
$("#gallery-container").find('li').each(function() {
$(this).find('.content').toggle($(this).data('id') === id);
$(this).find('h3').toggle($(this).data('id') === id);
});
});
window.onload = function () {
$("#gallery-container li .content").css("display", "none");
$("#gallery-container li h3").css("display","none");
$("#gallery-container li p").css("display","none");
}
$('.gallery-menu h3, #gallery-list li').click(function(){
$("#gallery-list, .gallery-menu h3").toggle();
});
This controls the contents of the list also activate the menu.
My frist idea:
Loop the content list items and when no .content is available inside, remove the related menu item.
$(function() {
$("#gallery-container li[data-id]").each(function() {
if( $(".content", this).length == 0 ) {
$("#gallery-list li[data-id=" + $(this).data("id") + "]").remove();
}
});
});
As #XerenNarcy noticed in the comments, you can even use a not() and has() combined selector:
$(function() {
$("#gallery-container li[data-id]:not(:has(.content))").each(function() {
$("#gallery-list li[data-id=" + $(this).data("id") + "]").remove();
});
});
Instead of remove() you yould even use hide().
Working example.

Wrap n-th or less element, wrong result

I have drop down menu in wordpress and I have small problem with wrap nth(every 4th element) li.
My code
<li id="item1"> ... </li>
<li id="item2"> ... </li>
<li id="item3">
<ul class="sub-menu">
<li> Test1</li>
<li> Test2</li>
</ul>
</li>
<li id="item4">
<ul class="sub-menu">
<li> Test3</li>
<li> Test4</li>
<li> Test5</li>
<li> Test6</li>
<li> Test7</li>
<li> Test8</li>
<li> Test9</li>
<li> Test10</li>
<li> Test11</li>
<li> Test12</li>
</ul>
</li>
jQuery code
var divs = $("ul.sub-menu > li");
for(var i = 0; i < divs.length; i+=4) {
divs.slice(i, i+4).wrapAll("<div class='column'></div>");
}
My results (wrong)
<li id="item1"> ... </li>
<li id="item2"> ... </li>
<li id="item3">
<ul class="sub-menu">
<div class="column">
<li> Test1</li>
<li> Test2</li>
<li> Test3</li>
<li> Test4</li>
</div>
</ul>
</li>
<li id="item4">
<ul class="sub-menu">
<div class="column">
<li> Test5</li>
<li> Test6</li>
<li> Test7</li>
<li> Test8</li>
</div>
<div class="column">
<li> Test9</li>
<li> Test10</li>
<li> Test11</li>
<li> Test12</li>
</div>
</ul>
</li>
What I try achieve:
<li id="item1"> ... </li>
<li id="item2"> ... </li>
<li id="item3">
<ul class="sub-menu">
<div class="column">
<li> Test1</li>
<li> Test2</li>
</div>
</ul>
</li>
<li id="item4">
<ul class="sub-menu">
<div class="column">
<li> Test3</li>
<li> Test4</li>
<li> Test5</li>
<li> Test6</li>
</div>
<div class="column">
<li> Test7</li>
<li> Test8</li>
<li> Test9</li>
<li> Test10</li>
</div>
<div class="column">
<li> Test11</li>
<li> Test12</li>
</div>
</ul>
</li>
any idea what I do wrong? It's necessary because "item3" and "item4" are diffrents category and with my code li elements are mix if in first ul is less then 4 items
Wow, what you just did, I didn't know it was possible. :)
Anyway:
$('.sub-menu').each(function() {
var children = $(this).find('> li');
for (var i = 0; i < children.length; i+=4) {
children.slice(i, i+4).wrapAll("<div class='column'></div>");
}
});
This will use the functionality you tried, but it will loop through every submenu independently and the items will be properly grouped.
http://jsfiddle.net/9NUwJ/

Categories

Resources