How to count span inside ul which have li inside it - javascript

have a code structure like this :
<ul class="ulNotif">
<span id="notiftype1"></span>
<span id="notiftype2"></span>
<span id="notiftype3"></span>
</ul>
I sent li with jquery to each span. Every span will have li if the data match with the condition.
I tried to count with $(".ulNotif span li").length but still 0 value.
How to count span which have li inside it with javascript? Thanks

#junkfoodjunkie is correct. You should use <li> tags as direct descendants of <ul>. Nonetheless, your code should look like this:
$(".ulNotif span li").length
Your <ul> has a .class, not an #ID
EDIT: This works totally find for me: returns 3
$('.ulNotif span').each((index, child) => {
$(child).append('<li>')
})
console.log($('.ulNotif span li').length)

Related

CSS Affect only parent list in the nested list

I have a nested list, as shown below. I'm struggling to find a specific CSS selector that I can use in querySelectorAll() JavaScript function, which will only affect all <li> tags that do NOT contain <ul> tag. So in this case it should be just the lines
<li>foot</li>
<li>leg</li>
<li>tiger</li>
<li>elephant</li>
<li>food</li>
I tried querySelectorAll("ol > li") and some others ways with the :not() selector, but to no success.
querySelectorAll("ol > li ul") is the opposite of what I want, because when I use
console.log(document.getElementById("translation").querySelectorAll("ol > li ul").length) it returns 3.
I need code of the following type console.log(document.getElementById("translation").querySelectorAll(blank).length) which will return 5. I don't know if that's possible, and I can't find it anywhere online.
Another way of looking at it is to let this code of CSS only color items which do not contain other nested lists (so that only points 2-6 will have colored background):
#translation ol > li ul{
background-color: cyan;
}
The entire list:
<div id="translation">
<ol>
<li>
<ul>
<li>parting</li>
<li>parting</li>
<li>parting</li>
<li>separation</li>
<li>separation</li>
<li>separation</li>
<li>farewell</li>
<li>(lateral) branch</li>
<li>fork</li>
<li>offshoot</li>
</ul>
</li>
<li>foot</li>
<li>leg</li>
<li>tiger</li>
<li>elephant</li>
<li>food</li>
<li>
<ul>
<li>branch</li>
<li>parting</li>
<li>disaffiliation</li>
<li>disaffiliation</li>
<li>separation</li>
<li>(lateral) branch</li>
<li>farewell</li>
<li>branch</li>
<li>division</li>
</ul>
</li>
<li>
<ul>
<li>dissociation</li>
<li>disaffiliation</li>
<li>dissociation</li>
</ul>
</li>
</ol>
</div>
You need to check each li is childNodes has ul. For example like this:
const test = [...document.querySelectorAll("ol > li")].filter(
li => ![...li.childNodes].find(child => child.localName === "ul")
);
if you are able to use jQuery then make the :not selector to catch elements that have ul as childs.
something like this:
$("translation").find("ol > li:not(:has(>ul))")
Notice this solution will work for jQuery selectors but not for the Vanilla JS (Vanilla JS doesn't support :has as a seclctor).
With Vanilla JS you might want to do something like this:
const elems = document.getElementById("translation").querySelectorAll('ol > li');
let items = Array.from(elems); // convert to Array type
items.filter(item => { // filter the array
item.querySelectorAll('ul').length == 0
})

How to add a class to a span element which is part of an existing <li> tag with jQuery

How can I add a class to a span element for only these spans which are part of li tags with class='error'
per example, this is the HTML which is generated:
<li class="error">
<!--if list has class error, then add also class error to span which is part of that list tag-->
<span class="error"></span>
</li>
This is the code I have so far:
if(status == 'error') {
data.context.addClass('error'); // adds class error to li tag
}
This is easy using JQuery, just select all li items that have the class .error and then use find() to find all the spam elements inside it, finally add the class .error to those:
$(document).ready(function()
{
$("li.error").find("span").addClass("error");
});
span.error {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li class="">
<span>Parent "li" do not have class error</span>
</li>
<li class="error">
<span>Parent "li" have class error</span>
</li>
This should achieve the expected result. Iterate through all li elements with the error class and find any spans, then add the class error to it.
$('li.error').each(function() {
$(this).find('span').addClass('error');
})
For a pure vanilla JavaScript solution, you can use an attribute selector to find all your li elements that have a class called error. Once you have that list of li elements, just loop thru (using forEach or a for-loop) and append an a span element as a child of the li. The span element should also be given a class attribute called "error" via setAttribute.
function appendErrorSpan(li) {
var errorEl = document.createElement('span');
errorEl.setAttribute('class', 'error');
errorEl.appendChild(document.createTextNode('Error span added!'));
li.appendChild(errorEl);
};
var errorListItems = document.querySelectorAll('li[class="error"]');
errorListItems.forEach(appendErrorSpan);
<li class="">
<span></span>
</li>
<li class="error">
</li>
Instead of using loops you can do it like this-
let a=document.querySelectorAll("li.error > span");
$(a).addClass('error');
Easiest way-
$("li.error > span").addClass('error');

Inline block not displaying

I am trying to have a li element and a div be "inline", but right now the div text keeps being put right below the li element. I'm using display: inline block and jQuery as below:
$('#list').append(
'<div class="spanish">\
<li>'+new_task+'</li>\
<div>Test</div>\
</div>');
.spanish {
display:inline-block;
}
As #ValeriySiestov mentioned, div is a block element, and li is a block element as well.
One way to fix your problem is to change the structure of the html you are appending, so it is a span element within the li element.
Note that list elements (i.e. uls or ols) can only have lis as their children, but lis can have anything as their children. Reference: Can I use a div inside a list item?
Assuming you have an unordered list with id #list, you can append a new list item to it like so:
var new_task = "walk the dog"
var li_string = `<li>${new_task}: <span>Test</span></li>`
$('#list').append(li_string);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul id="list">
<li>make bed</li>
<li>brush teeth</li>
</ul>
Note the variable new_task is being interpolated within the string of html being appended to the list using template literals.
Template literals syntax:
string text ${expression} string text
div - is a block (display: block) element by default. It stretches to 100% of parent's width
li - is an item of the list (display: list-item) and also stretches to 100% of parent's width
If you want to change this behaviour, you need to add to div and li another display value, like this
.spanish div, .spanish li {
display: inline;
}
or
.spanish div, .spanish li {
display: inline-block;
}
In your code, you use inslide , this is not actualy right, this is not critical, it will work, but must be inside
It seems from you code. You want to print div below li. There are few things to note:
Li should always come inside UL or OL tag. You current code is semantically wrong.
There can be only Li come as sibling of Li. No any other tag (You are using div)
For position use css.
Please check below answer if its helpful to you.
$( document ).ready(function() {
var new_task = "<div class='row'>row</div>";
$('#list').append(
'<div class="spanish">\
<ul>\
<li>'+new_task+'<div class="sub-row">Test</div></li>\
</ul>\
</div>');
});
.row {
display: inline;
clear:both:
widht:100%
}
.sub-row {
display:inline;
clear:both;
margin-left:2px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="list"></div>

Adding a class to a <li> element that contains <strong> tag

I am trying to add a class to a list element, only if it consists of a strong element within the li opening and closing brackets. I feel like I'm pretty close but that I am missing something.
Here's the code that I've got so far:
$('.section-header__subtext ul li').each(function() {
if ($(this).is('strong')) {
$(this).addClass('selected');
}
});
Thanks in advance!
As li can't ever be strong, thus $(this).is('strong') will always be false, hence the CSS class is not added to the element.
You can use :has() selector
Selects elements which contain at least one element that matches the specified selector.
$('.section-header__subtext ul li:has(strong)').addClass('selected');
$('.section-header__subtext ul li:has(strong)').addClass('selected');
.selected {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="section-header__subtext">
<ul>
<li>1</li>
<li><strong>2</strong></li>
<li>3</li>
<li><strong>4</strong></li>
</ul>
</div>
I think this is what you are looking for. jQuery find() searches in the given element. The .length part will return the amount of elements found.
$('.section-header__subtext ul li').each(function() {
if ($(this).find('strong').length > 0) {
$(this).addClass('selected');
}
});
$('.section-header__subtext ul li').each(function() {
if ($(this).find('strong').length > 0) {
$(this).addClass('selected');
}
});
Use find() method to search for elements inside of another one.

Jquery, Insert an <li> tag at the beginning and remove the last tag keeping only 3 li tags at a time

I am using socket.io and twitter streaming API.
Now I have to keep the recent three tweets in a list
<ul>
<li></li>
<li></li>
<li></li>
</ul>
My Question is how to do this in Jquery? Whenever there is a new tweet I want to insert it in to first li and move the first li tweet in to second li and so on and remove the 4th tweet.
Use .prepend to insert new element at the beginning of the target element.
Use :gt() to remove the element if length is greater than expected
length.
var count = 0;
$('button').on('click', function() {
var li = '<li>Data New' + count + '</li>';
++count;
$('ul').prepend(li);
if ($('ul li').length > 3) {
$('ul li:gt(2)').remove();
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<ul>
<li>Data</li>
<li>Data</li>
<li>Data</li>
</ul>
<button>Add</button>
Use .prepend() method in jQuery. This adds HTML element as the first node of the target.
$("ul").prepend("<li>new item</li>");
And as #Kartikeya suggested, remove the last one like:
$("ul > li:last").remove();

Categories

Resources