Complex DOM selection jQuery - javascript

I have a structure like this in my DOM:
<ul>
<li>
<div class="truc"></div>
<div class="machin"></div>
<div class="chose"></div>
</li>
<li>
<div class="truc"></div>
<div class="machin"></div>
<div class="chose"></div>
</li>
<li>
<div class="truc"></div>
<div class="machin"></div>
<div class="chose"></div>
</li>
<li>
<div class="truc"></div>
<div class="machin"></div>
<div class="chose"></div>
</li>
<li>
<div class="truc"></div>
<div class="machin"></div>
<div class="chose"></div>
</li>
<li>
<div class="truc"></div>
<div class="machin"></div>
<div class="chose"></div>
</li>
</ul>
I want to select all the ul child (it include the elements, except the class called "chose". I tried something like:
$('ul').children().not('.chose')
but i didn't success...

The children() of the ul element are li elements, not the div elements you're after. You need to use jQuery's find() method instead:
$('ul').find('div').not('.chose')
JSFiddle demo.
But i want to select the li elements to... i want that the complete return be: <li> <div class='truc'></div> <div class='machin'></div> </li>
In that case you can use this:
$('ul').find('li, div').not('div.chose')
JSFiddle demo.

Try using $('ul li') . <li> are the immediate children of <ul> not<div>
$('ul li').children().not('.chose')
If you want to remove these <div>s
$('ul li').children('.chose').remove();

Related

How to set array or multiples var inside jquery .html() method?

I've got a array with content [a,b,c] and I need to put it inside a .html()
and my original place its 3 child
When i put it directly - this way:
$('#listProducts div ul li').html(newElements); (not esactly this code, but I short it)
whats happens (return like this [abc]):
<div id=listProducts>
<ul>
<li>A,B,C</li>
<li>A,B,C</li>
<li>A,B,C</li>
</ul></div>
result i want:
<div id=listProducts>
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
</ul></div>
I tried this:
$('#listProducts ul li ul li div').html(function(newElements){
for(let i = 0; i < newElements.length; i++){
newElements[i];
}
});
but i research about functions inside .html() and it seems only accept index parameters.
i think about something like
$().html(newElements[0],newElements[1],newElements[2]) or
separe in 3 variables $().html(element1,newElements2,newElements3) // but i guess its not possible with .html()
Is there a way to do that?
Ps: I cant change the HTML, and i cant just send directly someting like <li> + newElements[i]; because its atached with backend parameters uniques with every div, ul, etc.
Its my first question at SO, and english is not my first language. So if a make any mistake, please advice me and I'll change. Thank you so much!!
Edit1:
testing:
.html(function(i) {
return arr[i];
});
FULL CODE:
const arr = $('#listProducts ul li ul li div a').get().sort(function(a, b) {
return a.getAttribute('href') > b.getAttribute('href') ? 1 : -1;
}).map(function(el) {
return $(el).clone(true)[0];
});
$('#listProducts ul li ul li div').html(function(i) {
return arr[i];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<body>
<div id="listProducts" class="listagem borda-alpha ">
<ul data-produtos-linha="3">
<li class="listagem-linha ">
<ul class="">
<li class="span4">
<div class="listagem-item">
2TH ELEMENT
<div class="another 1">another div 1</div>
<div class="another 2">another div 2</div>
</div>
</li>
<li class="span4">
<div class="listagem-item">
3RD ELEMENT
<div class="another 1">another div 1</div>
<div class="another 2">another div 2</div>
</div>
</li>
<li class="span4">
<div class="listagem-item">
1st ELEMENT
<div class="another 1">another div 1</div>
<div class="another 2">another div 2</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
expected:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<body>
<div id="listProducts" class="listagem borda-alpha ">
<ul data-produtos-linha="3">
<li class="listagem-linha ">
<ul class="">
<li class="span4">
<div class="listagem-item">
1st ELEMENT
<div class="another 1">another div 1</div>
<div class="another 2">another div 2</div>
</div>
</li>
<li class="span4">
<div class="listagem-item">
2ND ELEMENT
<div class="another 1">another div 1</div>
<div class="another 2">another div 2</div>
</div>
</li>
<li class="span4">
<div class="listagem-item">
3RD ELEMENT
<div class="another 1">another div 1</div>
<div class="another 2">another div 2</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>
ADD:
The .get().sort is to sort the results alphabetically, according to the URL and is working fine.
"another div 1" and "another div 2" are not the same as those "another div 1" and "another div 2" on the other li.
There are much more than 3 items.
If the <li> items are already in the <ul>, you can pass a function into .html() and use the index i it gives to access the content you want to place into each <li> like so:
const arr = ['A','B','C'];
$("#listProducts ul li").html(function(i) {
return arr[i];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=listProducts>
<ul>
<li></li>
<li></li>
<li></li>
</ul>
</div>
If the <li>s aren't already inside your <ul> you can map your arr to a list of elements, and then use .html() to add these elements to the <ul>:
const arr = ['A','B','C'];
$("#listProducts ul").html($.map(arr, function(text) {
return $('<li>', {text});
}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id=listProducts>
<ul>
</ul>
</div>
EDIT:
You can get all the <li> and sort these by the anchor tags href attribute. You can then use .append() to append the sorted elements to your DOM. The purpose of using .append() rather than .html() is that .append() will insert the elements into the DOM, thus removing the old element and adding the new one (so no need to .clone())
const arr = $('#listProducts ul li ul li').get().sort(function(a, b) {
const anchorA = $("a", a);
const anchorB = $("a", b);
return anchorA.attr('href') > anchorB.attr('href') ? 1 : -1;
});
$('#listProducts ul li ul').append(arr);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<body>
<div id="listProducts" class="listagem borda-alpha ">
<ul data-produtos-linha="3">
<li class="listagem-linha ">
<ul class="">
<li class="span4">
<div class="listagem-item">
2TH ELEMENT
<div class="another 1">1. another div 1</div>
<div class="another 2">1. another div 2</div>
</div>
</li>
<li class="span4">
<div class="listagem-item">
3RD ELEMENT
<div class="another 1">2. another div 1</div>
<div class="another 2">2. another div 2</div>
</div>
</li>
<li class="span4">
<div class="listagem-item">
1st ELEMENT
<div class="another 1">3. another div 1</div>
<div class="another 2">3. another div 2</div>
</div>
</li>
</ul>
</li>
</ul>
</div>
</body>
</html>

css selector for visible only first section content

I have a JavaScript toggle so T need to tried to collapse all sections on load by default - by inserting
ul.section-content{
display:none;
}
and it is working. But when I tried to hide first-child or not first-child it is not working.
.cscr .csec .section ul:first-of-type {
display: none;
}
<div class="cscr">
<ul class="csec">
<li class="section">
<div class="section-header">
<div class="section-left">
<h5>section01</h5>
<p>hello1</p>
</div>
<div class="section-meta">
</div>
</div>
<ul class="section-content">
<li class="course-item">
<h1>lesson01</h1>
</li>
</ul>
</li>
<li class="section">
<div class="section-header">
<div class="section-left">
<h5>section02</h5>
<p>hello1</p>
</div>
<div class="section-meta">
</div>
</div>
<ul class="section-content"> /* to hide this */
<li class="course-item">
<h1>lesson02</h1>
</li>
</ul> /* to hide this */
</li>
</ul>
</div>
second case:
and how to display only first and not others with help of not-first-child
screenshot of what is needed
Do you want something like this? https://codepen.io/anon/pen/YOOXOv. Change the CSS properties to whatever you want.
Here you are selecting all sections except the first one and then selecting ul inside them.

jQuery: How to create a menu and a submenu where the classes toggle on each click

I have this JS fiddle:
https://jsfiddle.net/zczwjdrw/7/
Menu 1:
When clicking on AAA it opens a menu.
When clicking on BBB it opens an other menu and removes AAAs style back to default. When clicking on BBB again it closes the submenu but doesn't change back to default. How do I solve this?
Menu 2:
When clicking on a sub menu option - it colors it. when clicking on an other option - it doesn't remove the class from the previous element. and you can continue coloring all submenu options. What can be the solution for this? I have used the same functionality on jQuery as .sidebar1.
jQuery:
$('.sidebar1 a').click(function(){
$(this).addClass('active-sb1').siblings().removeClass('active-sb1');
});
$('.sidebar2 a').click(function(){
$(this).addClass('active-sb2').siblings().removeClass('active-sb2');
});
HTML:
<div class="main-wrapper">
<div class="sidebar1">
<a href="ssb1" class="category" id="sb1" onclick="return false">
<div>AAA</div>
</a>
<a href="ssb2" class="category" id="sb2" onclick="return false">
<div>BBB</div>
</a>
<a href="ssb3" class="category" id="sb3" onclick="return false">
<div>CCC</div>
</a>
</div>
<div class="sidebar2" id="ssb1" style="display: none;">
<div class="sb2-content">
<h3>Choose Something:</h3>
</div>
<div class="sb2-menu">
<ul>
<li>
AAAAAAAAAAAAA
</li>
<li>
AAAAAAAAAAA
</li>
<li>
AAAAAAAAAAA
</li>
</ul>
</div>
</div>
<div class="sidebar2" id="ssb2" style="display: none;">
<div class="sb2-content">
<h3>Choose Something:</h3>
</div>
<div class="sb2-menu">
<ul>
<li>
BBBBBBBBBB
</li>
<li>
BBBBBBBBBB
</li>
<li>
BBBBBBBBBB
</li>
</ul>
</div>
</div>
<div class="sidebar2" id="ssb3" style="display: none;">
<div class="sb2-content">
<h3>Choose Something:</h3>
</div>
<div class="sb2-menu">
<ul>
<li>
CCCCCCCCC
</li>
<li>
CCCCCCCC
</li>
<li>
CCCCCCCC
</li>
</ul>
</div>
</div>
<div class="main-content">
<div class="user-bar">
</div>
<div class="content">
</div>
</div>
</div>
In .sidebar2 your <a> elements are inside a <li> so the <a> has no other siblings. But instead the parent <li> has siblings.
So, you could try something like this:
$('.sidebar2 a').click(function() {
var e = $(this);
e.addClass('active-sb2');
e.parent().siblings().children().removeClass('active-sb2');
});
And for your first problem, you could test if the element already has the class active-sb1, which means that the element is open, in which case you remove the class.
$('.sidebar1 > a').click(function() {
var e = $(this);
if (e.hasClass("active-sb1")) {
e.removeClass('active-sb1');
} else {
e.addClass('active-sb1');
}
e.siblings().removeClass('active-sb1');
});
Updated Fiddle link

How can I separate div from another class?

In my WordPress based website a plugin automatically wraps every element in the post content with <ul></ul>. That wraps everything even the <div>s which is invalid.
I want to unwrap certain elements and tried jQuery .unwrap . But I am able to unwrap some elements except a few div elements.
Here is the code:
<div class="post-content">
<p>Example post content</p>
<ul class="plugin_class">
<li>test</li>
<li>test</li>
<ul>
<div class="button-main-wrap">
<span class="button-abc">
<span>
Website link
</span>
</span>
<span class="button-abc"></span>
<span class="button-abc"></span>
</div>
</ul>
<ul>
<div class="number">hundred</div>
<div class="number">thosand</div>
</ul>
</ul>
<div>
<div>This content is okay</div>
<div>This content is okay</div>
</div>
</div>
From the above code, I want to separate <div class="button-main-wrap"> from <ul class="plugin_class"> or stop the <ul class="plugin_class"> to wrap elements which doesn't belong to it. ex: the div <div class="button-main-wrap"> or other elements like <div class="number">.
I tried these:
jQuery("ul").find('.button-main-wrap').unwrap();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="post-content">
<p>Example post content</p>
<ul class="plugin_class">
<li>test</li>
<li>test</li>
<ul>
<div class="button-main-wrap">
<span class="button-abc">
<span>
Website link
</span>
</span>
<span class="button-abc"></span>
<span class="button-abc"></span>
</div>
</ul>
<ul>
<div class="number">hundred</div>
<div class="number">thosand</div>
</ul>
</ul>
<div>
<div>This content is okay</div>
<div>This content is okay</div>
</div>
</div>
This unwraps all the <ul> elements in .post-content which I don't want.
jQuery(".plugin_class").find('.button-main-wrap').unwrap();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="post-content">
<p>Example post content</p>
<ul class="plugin_class">
<li>test</li>
<li>test</li>
<ul>
<div class="button-main-wrap">
<span class="button-abc">
<span>
Website link
</span>
</span>
<span class="button-abc"></span>
<span class="button-abc"></span>
</div>
</ul>
<ul>
<div class="number">hundred</div>
<div class="number">thosand</div>
</ul>
</ul>
<div>
<div>This content is okay</div>
<div>This content is okay</div>
</div>
</div>
This doesn't do anything.
I put all the code together in this Fiddle.
How to separate the div and stop the to wrap elements un-necessarily?
It is because div is not a valid child of ul, so wrap the contents of the ul with li then unwrap the li elements so that the parent ul will get removed
$('.plugin_class > ul').each(function(){
$(this).wrapInner('<li />').contents().unwrap()
})
Demo: Before, After

jQuery find closest ul

My HTML structure is like this:
<div class="product-slider-title">
<div><span class="left"> </span></div>
<div>Sample title</div>
<div><span class="right"> </span></div>
</div>
<div id="prslider1" class="product-slider-wrapper">
<div class="left-prduct-slider-nav sprites"></div>
<div class="right-prduct-slider-nav sprites"></div>
<div class="product-slider">
<ul>
<li class="product-holder"></li>
</ul>
</div>
</div>
How can i find the closest .product-slider ul from .left-prduct-slider-nav when i click on .left-prduct-slider-nav?
if this is .left-prduct-slider-nav then
var ul = $(this).siblings('.product-slider').find('ul')
Demo: Fiddle
You can use nextAll() to search the siblings after current element and use find() to searched the children in the matched element returned by nextAll.
Live Demo
$(this).nextAll('.product-slider').find('ul');
This should work
var ul = $('.left-prduct-slider-nav').closest('ul');
Hmm try this:
$('.left-prduct-slider-nav').click(function () {
var closest_ul = $(this).parent().find('.product-holder ul');
});
The closest .product-slider ul from .left-prduct-slider-nav is just the first one in the list, so you can use :first:
$('.left-prduct-slider-nav').click(function() {
$(this).parent().find('.product-slider ul:first')
})
Try first-child:
HTML:
<div class="product-slider-title">
<div><span class="left"> </span>
</div>
<div>Sample title</div>
<div><span class="right"> </span>
</div>
</div>
<div id="prslider1" class="product-slider-wrapper">
<div class="left-prduct-slider-nav sprites">Left Slider Nav</div>
<div class="right-prduct-slider-nav sprites"></div>
<div class="product-slider">
<ul>
<li class="product-holder1"></li>
</ul>
<ul>
<li class="product-holder"></li>
</ul>
<ul>
<li class="product-holder"></li>
</ul>
<ul>
<li class="product-holder"></li>
</ul>
</div>
</div>
<div class="product-slider-title">
<div><span class="left"> </span>
</div>
<div>Sample title</div>
<div><span class="right"> </span>
</div>
</div>
<div id="prslider1" class="product-slider-wrapper">
<div class="left-prduct-slider-nav sprites"></div>
<div class="right-prduct-slider-nav sprites"></div>
<div class="product-slider">
<ul>
<li class="product-holder"></li>
</ul>
</div>
</div>
JS:
$(document).ready(function () {
$(".left-prduct-slider-nav").click(function () {
alert($(".product-slider").find("ul:first-child").find("li").prop("class"));
});
});
jsFiddle.
Explanation:
I handle the .click() function of .left-prduct-slider-nav then I alert the class of the closest or in other words the first ul:first-child's li.
Proof:
The proof is that I changed the class of the first ul's li and then alert() it and then the output I get is this: product-holder1.
Try this:
$(this).next().next().find('ul');

Categories