jQuery switching lists with same class - javascript

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>

Related

How to check the continue classes in set?

I have 10 items in a list with this kind of structure where any item can have active class depending on some situations and this active class will add on item when user click on it. I want to get the number of set of 3 continue active classes. in the given example the 3 continue active classes are 2 times on items 4,5,6 and 8,9,10.
So the output should be 2 only.
How to achieve this.
I know I can get the total number of Active classes just by getting its length, but how to get if its how many times in continuity?
$(document).ready(function(){
let totalActivce = $('.active').length;
console.log(totalActivce);
});
.active {color: red;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="active">item1 </li>
<li>item2 </li>
<li>item3 </li>
<li class="active">item4 </li>
<li class="active">item5 </li>
<li class="active">item6 </li>
<li>item7 </li>
<li class="active">item8 </li>
<li class="active">item9 </li>
<li class="active">item10 </li>
</ul>
If you want to count the elements between your first element with the class active and the next you can use $('.active:first').nextUntil(".active")
Demo
$(document).ready(function() {
let totalActivce = $('.active:first').nextUntil(".active").length;
console.log(totalActivce);
});
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="active">item1 </li>
<li>item2 </li>
<li>item3 </li>
<li class="active">item4 </li>
<li class="active">item5 </li>
<li class="active">item6 </li>
<li>item7 </li>
<li class="active">item8 </li>
<li class="active">item9 </li>
<li class="active">item10 </li>
</ul>
Demo 2
$(document).ready(function() {
var f = 0;
$("ul li").each(function() {
if ($(this).is(".active") && $(this).nextUntil(':not(.active)').addBack().length == 3) {
f++;
}
});
console.log(f);
});
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="active">item1 </li>
<li>item2 </li>
<li>item3 </li>
<li class="active">item4 </li>
<li class="active">item5 </li>
<li class="active">item6 </li>
<li>item7 </li>
<li class="active">item8 </li>
<li class="active">item9 </li>
<li class="active">item10 </li>
</ul>
Demo 3
$(document).ready(function() {
var f = 0;
var s = 1;
$("ul li").each(function(i) {
if (s <= i) {
if ($(this).is(".active") && $(this).nextUntil(':not(.active)').addBack().length >= 3) {
s = s + 3;
f++;
}
}
});
console.log(f);
});
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li>item1 </li>
<li class="active">item2 </li>
<li class="active">item3 </li>
<li class="active">item4 </li>
<li class="active">item5 </li>
<li class="active">item6 </li>
<li class="active">item7 </li>
<li class="active">item8 </li>
<li class="active">item9 </li>
<li class="active">item10 </li>
</ul>
You can loop your elements and check if previous elements where active:
$(document).ready(function() {
let totalActivce = $('.active').length;
let sets = 0;
let isPreviousActive = 0;
console.log(totalActivce);
$('ul li').each(function() {
let isActive = $(this).is('.active');
if (isActive) {
isPreviousActive++;
if (isPreviousActive == 2) {
sets++;
}
}
if (!isActive) {
isPreviousActive = 0;
}
});
console.log(sets);
});
.active {
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li class="active">item1 </li>
<li>item2 </li>
<li>item3 </li>
<li class="active">item4 </li>
<li class="active">item5 </li>
<li class="active">item6 </li>
<li>item7 </li>
<li class="active">item8 </li>
<li class="active">item9 </li>
<li class="active">item10 </li>
</ul>

Removing items by its contained text from html

I'm looking for a solution to remove items from my html when the page is loaded.
<ul class="nav navbar-nav">
<li class="dropdown">
Модули <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>
<strong>blabla</strong>
</li>
<li>
blabla6
</li>
<li role="presentation" class="divider"></li>
<li>
<strong>blabla5</strong>
</li>
<li>
blabla4
</li>
<li>
blabla3
</li>
<li>
blabla2
</li>
<li>
blabl1
</li>
</ul>
</li>
So I want to remove for example blabla4, blabla2, blabla1 including their <li> tags
This is what I've tried so far
<script type="text/javascript">
// select relevant elements
var elements = $('content-main');
// go through the elements and find the one with the value
elements.each(function(index, domElement) {
var $element = $(domElement);
// does the element have the text we're looking for?
if ($element.text() === "blabla2") {
$element.hide(); // hide the element with jQuery return false;
// jump out of the each
}
});
</script>
Just collect the list items, cast the resulting NodeList to an Array, and iterate over it, removing items whose innerHTML contains 'blabla'.
const listitems = Array.from(document.querySelectorAll('.dropdown-menu li'));
for (const listitem of listitems) {
if (listitem.innerHTML.indexOf('blabla') != -1) {
listitem.parentNode.removeChild(listitem);
}
}
<ul class="dropdown-menu" role="menu">
<li>
<strong>blabla</strong>
</li>
<li>
blabla6
</li>
<li role="presentation" class="divider"></li>
<li>
<strong>blabla5</strong>
</li>
<li>
blabla4
</li>
<li>
blabla3
</li>
<li>
blabla2
</li>
<li>
blabl1
</li>
</ul>
Use JQuery .remove() to delete HTML tags, But you should have a selector on the tags that you want to remove:
$( document ).ready(function() {
$('.dropdown-menu').find("li").slice(4, 5).remove();
$('.dropdown-menu').find("li").slice(5, 6).remove();
$('.dropdown-menu').find("li").slice(5, 6).remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav navbar-nav">
<li class="dropdown">
Модули <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>
<strong>blabla</strong>
</li>
<li>
blabla6
</li>
<li role="presentation" class="divider"></li>
<li>
<strong>blabla5</strong>
</li>
<li>
blabla4
</li>
<li>
blabla3
</li>
<li>
blabla2
</li>
<li>
blabl1
</li>
</ul>
</li>
</ul>
You can create a array data structure that will hold the values for which <li> should be removed then loop over to all the <li> tags inside the class dropdown-menu and remove them based on their content match with the array value:
$(document).ready(function(){
var removeText = ['blabla4', 'blabla2', 'blabla1'];
$('.dropdown-menu li').each(function(){
var text = $(this).find('a').text().trim();
if(removeText.indexOf(text) !== -1){
$(this).remove();
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav navbar-nav">
<li class="dropdown">
Модули <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>
<strong>blabla</strong>
</li>
<li>
blabla6
</li>
<li role="presentation" class="divider"></li>
<li>
<strong>blabla5</strong>
</li>
<li>
blabla4
</li>
<li>
blabla3
</li>
<li>
blabla2
</li>
<li>
blabl1
</li>
</ul>
</li>
You can do it using JQuery:
$(".dropdown-menu > li > a").each(function () {
var $this = $(this);
if ($this.html() == 'bla bla bla') {
$this.parent().remove();
}
});
An alternative is using the selector :contains and the function closest to select the parent element li.
This approach removes the element li with text blabla4
$('#remove').on('click', function() {
$("li a:contains(blabla4)").closest('li').remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav navbar-nav">
<li class="dropdown">
Модули <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>
<strong>blabla</strong>
</li>
<li>
blabla6
</li>
<li role="presentation" class="divider"></li>
<li>
<strong>blabla5</strong>
</li>
<li>
blabla4
</li>
<li>
blabla3
</li>
<li>
blabla2
</li>
<li>
blabl1
</li>
</ul>
</li>
</ul>
<button id='remove'>remove blabla4</button>
You can select the items using querySelectorAll, convert the NodeList to Array with Array.from, then iterate over each item and remove it.
const wordsToRemove = ['blabla3', 'blabla2'];
const items = Array.from(document.querySelectorAll('li > a'));
const result = items
.filter(item => wordsToRemove.includes(item.textContent))
.forEach(item => item.parentNode.parentNode.removeChild(item.parentNode));
<ul class="nav navbar-nav">
<li class="dropdown">
Модули <span class="caret"></span>
<ul class="dropdown-menu" role="menu">
<li>
<strong>blabla</strong>
</li>
<li>
blabla6
</li>
<li role="presentation" class="divider"></li>
<li>
<strong>blabla5</strong>
</li>
<li>
blabla4
</li>
<li>
blabla3
</li>
<li>
blabla2
</li>
<li>
blabl1
</li>
</ul>
</li>

Filter li elements in ul and preserve path

I'm trying to expand my filtering function for li elements in ul.
My ul structure looks like this:
<ul>
<li class="root"><span class="text">Root1</span>
<ul>
<li class="list"><span class="text">li1.1</span></li>
</ul>
</li>
<li class="root"><span class="text">Root2</span>
<ul style="display: block;">
<li class="root"><span class="text">Root2.1</span>
<ul style="display: block;"></ul>
</li>
<li class="root"><span class="text">Root2.2</span>
<ul style="display: block;">
<li class="list"><span class="text">li2.2.1</span></li>
</ul>
</li>
<li class="root"><span class="text">Root2.3</span>
<ul style="display: block;">
<li class="list"><span class="text">li2.3.1</span></li>
<li class="list"><span class="text">li2.3.2</span></li>
</ul>
</li>
</ul>
</li>
<li class="root"><span class="text">Root3</span>
<ul>
<li class="list"><span class="text">li3.1</span></li>
</ul>
</li>
<li class="root"><span class="text">Root4</span>
<ul>
<li class="list"><span class="text">li4.1</span></li>
<li class="list"><span class="text">li4.2</span></li>
</ul>
</li>
</ul>
Currently I have filter function that filters based on query among .list elements. Now I'm trying to implement it in a way, that while filtering list (still only .list elements), there would be structure history.
For example: searching for "li2.3.2" would return:
<ul>
<li class="root"><span class="text">Root2</span>
<ul style="display: block;">
<li class="root"><span class="text">Root2.3</span>
<ul style="display: block;">
<li class="list"><span class="text">li2.3.2</span></li>
</ul>
</li>
</ul>
</li>
</ul>
EDIT: For clarification and since I failed to mention that in original post...I'm trying to filter by users input (partial matching counts).
My current method works by taking users input in text input box, taking all .list elements in ul and comparing for each element if span.text contains searching text.
you should give class every floor,and use CSS filter :parent and :nth-chiled find what you want
#pc9529, yes it is possible. but here you want o display only parent li node html. So give different class to the li which is belonging from your parent UL. Look at the given solution,
$(document).ready(function(){
$("li").click(function(e){
e.stopPropagation();
if($(this).hasClass("root1"))
{
alert($('<div>').append($(this).clone()).html());
}
else{
alert($('<div>').append($(this).closest(".root1").clone()).html());
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="root1"><span class="text">Root1</span>
<ul>
<li class="list"><span class="text">li1.1</span></li>
</ul>
</li>
<li class="root1"><span class="text">Root2</span>
<ul style="display: block;">
<li class="root"><span class="fa fa-chevron-down"></span><i class="fa root-checkbox fa-square-o"></i><span class="text">Root2.1</span>
<ul style="display: block;"></ul>
</li>
<li class="root"><span class="text">Root2.2</span>
<ul style="display: block;">
<li class="list"><span class="text">li2.2.1</span></li>
</ul>
</li>
<li class="root"><span class="text">Root2.3</span>
<ul style="display: block;">
<li class="list"><span class="text">li2.3.1</span></li>
<li class="list"><span class="text">li2.3.2</span></li>
</ul>
</li>
</ul>
</li>
<li class="root1"><span class="text">Root3</span>
<ul>
<li class="list"><span class="text">li3.1</span></li>
</ul>
</li>
<li class="root1"><span class="text">Root4</span>
<ul>
<li class="list"><span class="text">li4.1</span></li>
<li class="list"><span class="text">li4.2</span></li>
</ul>
</li>
</ul>
Please have a look at this JSFiddle
The JQuery finds your item by text, then find all parents that contain the ".root" class, and finally gets the last parent i.e. the root ul element of the hierarchy.
$('.list:contains("li2.3.2")').parents('.root').last().html()

JQuery - Creating parent grandparent level text as object

I am trying to create previous parent and grandparent level text as object using function
For example on element grandchild11
<a class="level-12" href="#" parobj="['Child1','Child','Grandparent']" other="getOther(this)"> Grandchild11</a>
I am facing issue in creating object for attribute parobj as shown above for every anchor tag and I have even tried adding class with levels but failing to get exact output
is there anyway to get parobj as mentioned above either by hover or clicking anchor tag?
Codepen URL for reference:
http://codepen.io/divyar34/pen/bqMaQY
HTML:
$('a').attr('parObj', 'getParent(this)'); //adding attr parentObject with function to get parent,grandparent details
$('a').attr('other', 'getOther(this)'); //other Info attribute for ajax call
function getParent(val) {
var obj = [val];
obj.push($(val).parent().text());
return obj
}
function getOther(val) {
//just for reference, but originaly using internal api
$.get('otherinfo.html', {
option: val
}, function(data) {
console.log(data);
return data.name
});
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="level-1">Parent1
<ul class="level-2">
<li class="level-3"><a class="level-4" href="#">Grandparent</a>
<div class="level-4">
<ul class="level-5">
<li class="level-6">
<a class="level-7" href="#">Child</a>
<div class="level-7">
<ul class="level-8">
<li class="level-9"> <a class="level-10" href="#">Child1</a>
<ul class="level-10">
<li class="level-11"><a class="level-12" href="#"> Grandchild11</a></li>
<li class="level-11"><a class="level-12" href="#"> Grandchild11</a></li>
</ul>
</li>
<li class="level-9"> <a class="level-10" href="#">Child2</a>
<ul class="level-10">
<li class="level-11"><a class="level-12" href="#">GrandChild21</a></li>
<li class="level-11"><a class="level-12" href="#">grandchild22</a></li>
</ul>
</li>
</ul>
</div>
</li>
<li class="level-6">
<a class="level-7" href="#"> Child2 </a>
<ul class="level-7">
<li class="level-8"><a class="level-9" href="#">GrandChild21</a></li>
<li class="level-8"><a class="level-9" href="#">grandchild22</a></li>
</ul>
</li>
</ul>
</div>
</li>
</ul>
</div>
<!-- Parent1 -->
<div class="level-1">Parent2
<ul class="level-2">
<li class="level-3"><a class="level-4" href="#">Grandparent</a>
<div class="level-4">
<ul class="level-5">
<li class="level-6">
<a class="level-7" href="#">Child</a>
<div class="level-7">
<ul class="level-8">
<li class="level-7"> <a class="level-8" href="#">Child1</a>
<ul class="level-8">
<li class="level-9"><a class="level-10" href="#"> Grandchild11</a></li>
<li class="level-9"><a class="level-10" href="#"> Grandchild11</a></li>
</ul>
</li>
<li class="level-7"> <a class="level-8" href="#">Child2</a>
<ul class="level-8">
<li class="level-9"><a class="level-10" href="#">GrandChild21</a></li>
<li class="level-9"><a class="level-10" href="#">grandchild22</a></li>
</ul>
</li>
</ul>
</div>
</li>
<li class="level-6">
<a class="level-7" href="#"> Child2 </a>
<ul class="level-7">
<li class="level-8"><a class="level-9" href="#">GrandChild21</a></li>
<li class="level-8"><a class="level-9" href="#">grandchild22</a></li>
</ul>
</li>
</ul>
</div>
</li>
</ul>
</div>
<!-- Parent2 -->

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