I am dynamically adding UL elements to a DIV element. I would like to be able to count how many UL elements there are inside the DIV so that once all the ULs are removed dynamically I can delete the DIV that they are contained in.
<div id="000">
<ul id="000-1">
<li>Stuff</li>
<li>Stuff</li>
</ul>
<ul id="000-2">
<li>Stuff</li>
<li>Stuff</li>
</ul>
</div>
Is there a simple Javascript solution that counts the amount of ULs so that I can do something like this.. ?
if(ulcount == 0){
var remove = document.getElementById("000");
remove.innerHTML = '';
results.parentNode.removeChild("000");
}
Thanks.
#Cheeso's answer is a good pure-JS solution. But, if you're using jQuery, the process can be made simpler.
jQuery('div#000').children('ul').length;
The above code will return the number of child ul elements of the div#000.
To update the count when you add elements dynamically, you will have to create a function and call it to update the number whenever a change occurs:
function countUls() {jQuery('div#000').children('ul').length;}
Bind that to an event so that it will be called when you want to update the number.
Code:
function getDirectChildrenByTagName(elt,tagname) {
var allChildren = elt.children, wantedChildren=[], i, L;
tagname = tagname.toUpperCase();
for(i=0, L=allChildren.length; i<L; i++) {
if (allChildren[i].tagName.toUpperCase() == tagname) {
wantedChildren.push(allChildren[i]);
}
}
return wantedChildren;
}
use it like this:
var zero = document.getElementById("000");
var uls = getDirectChildrenByTagName(zero, 'UL');
var ulCount = uls.length;
....
Try this:
var x = document.getElementById("000-1").querySelectorAll("li").length
console.log(">>>>", x);
Related
An HTML div element contains lists of endangered species grouped by continent and the species population status.
<div>
<ul data-continent="North America">
<li data-species="California condor">Critically Endangered</li>
<li data-species="American bison">Near Threatened</li>
</ul>
<ul data-continent="Europe">
<li data-species="Cave bear">Extinct</li>
</ul>
</div>
I want to write a function that returns how endangered a species is on a particular continent. For example endangeredSpecies('North America', 'American bison') would return 'Near Threatened'.
This should be trivial
function endangeredSpecies( continent, species )
{
return $( "ul[data-continent='" + continent + "'] li[data-species='" + species + "']" ).html();
}
Here are the pieces of information that you might need in order to solve that problem:
Attribute Selectors
You can select elements based on their attribute names and values. For example if you want to select elements that has a data-continent attribute, you can use (using jQuery) $('[data-continent]'). If you want to check the value as well, you can do $('[data-continent="somevalue"]').
jQuery .text()
Given an element that was selected using jQuery, you can get its text content by calling the .text() method on it, like so: $('li').text()
Using these, you can achieve what you want. I know that I am not answering your question directly, but that's for you to figure out :)
After getting div children, you can filter for ul element that contains the specified continent and then look for li element that contains the specified species.
function getStatus(elementChildren, species) {
var i;
for (i = 0; i < elementChildren.length; i++) {
if ($(elementChildren[i]).data("species") === species) {
return $(elementChildren[i]).text();
}
}
}
function endangeredSpecies(continent, species) {
var divChildren = $("div").children();
var i;
var status = "";
for (i = 0; i < divChildren.length; i++) {
if ($(divChildren[i]).data("continent") === continent) {
status = getStatus($(divChildren[i]).children(), species);
}
}
return status;
}
A bit hard to explain, but here it goes.
I've got a class, .possibleMatch.
I've also got an array, myPicks, with a list of other classes (.silver, .music, .newest).
There is an unordered list, and each li has been assigned certain classes (.possibleMatch, .silver, .music, .gold, .newest, .platinum)
Now what I'm trying to do is find every item in class .possibleMatch from the ul, that is also in classes from myPicks, so .silver, .music and .newest, and update .possibleMatch with only those items.
Here's what I've tried so far:
var i;
for(i=0; i<myPicks.length; i++) {
$('.possibleMatch').has(myPicks[i]);
}
and
var i;
for(i=0; i<myPicks.length; i++) {
$('.possibleMatch').hasClass(myPicks[i]);
}
and
var i;
for(i=0; i<myPicks.length; i++) {
$('.possibleMatch').filter(myPicks[i]);
}
The array, myPicks, is filled with the names in strings of the classes, not the actual classes themselves. Is this the problem when I pair it with filter, has, and hasClass?
The array is updated when a button is clicked, each with the classname:
var myPicks[];
$('.button').click( function() {
var hello = " " + $(this).attr('class').split(' ')[0];
myPicks.push(hello);
}
Thanks, and my apologies if it's hard to understand!
--
Edit: Here's the HTML
<ul id="trueMatch">
<li class="possibleMatch silver music newest" id="uno">VW</li>
<li class="possibleMatch platinum music" id="dos"> AC </li>
<li class="possibleMatch gold music newest" id="tres"> ML</li>
</ul>
what you can try is
if the possibleMatch class is assigned to lis along with myPicks class like <li class="possibleMatch silver">ddd</li> then
var $lis = $('.possibleMatch').filter(myPicks.join(','));
Demo: Fiddle
Try this
$('.possibleMatch').each(function() {
var elment = $(this);
for( var i=0; i<myPicks.length; i++){
if ( elment.hasClass( myPicks[i] ) {
}
}
});
Assuming that array contains class names without the dot
I'm trying to display the full list that have the same id that matches with the select option. But I can't figure out how to get the id from the attribute by using the name to be able to filter it.
The html example:
<select id='groopy' onchange='see();'>
<option>default</option>
<option>lista1</option>
<option>list1</option>
</select>
<ul id='grupo'>
<li id='list1' name="lista">Playground (Rangbhoomi)</li>
<li id='default' name="lista">Empire Made Me</li>
<li id='default' name="lista">Transmission</li>
<li id='lista1' name="lista">Hostel Room 131</li>
<li id='default' name="lista">A Disobedient Girl</li>
<li id='default' name="lista">Travels in the Land of Kubilai Khan</li>
<li id='list1' name="lista">The Indian Mutiny</li>
<li id='lista1' name="lista">Beauty and Sadness</li>
<li id='default' name="lista">The Collaborator</li>
<li id='list1' name="lista">I, Lalla</li>
<li id='default' name="lista">No Full Stops in India</li>
<li id='lista1' name="lista">For Lust of Knowing</li>
<li id='default' name="lista">On the Road to Kandahar</li>
</ul>
And the script I'm trying:
<script>
function see(){
var listita = document.getElementById('groopy').options[document.getElementById('groopy').selectedIndex].value;
var items = document.getElementsByName("lista");
var items_id = document.getElementsByName("lista").getAttribute('id');
if(listita==items_id){
for(var i = 0; i < items.length; i++)
{
document.getElementById("description").innerHTML = items[i].outerHTML;
}
}
}
onload= see();
</script>
By the way, the select and the ul are generated dynamically so I don't actually now the id's that could be provided. I'm trying a little different approach here .
When I manage to make the select filter work, the for stop working. WHY? I'm going crazy with this. Please help!!
Firstly you are having multiple elements with same id's which is wrong.. Cause getElementbyId will only fetch the first element encountered by it.
Replace then with class instead
Next you are overwriting the HTML for every iteration, so you will always have the last item appended to it.
Instead store that in a variable and append it after the for loop.
you need to bind your element with a change event, otherwise your call only works once when the page loads for the first time.
Try this
// Cache the selector as you are using it multiple times
var dropdown = document.getElementById('groopy');
function see() {
// set the selected option
var listita = dropdown.options[dropdown.selectedIndex].value
items = document.getElementsByClassName(listita);
html = '';
// For each item with class name, iterate over it and store in a string
for (var i = 0; i < items.length; i++) {
if (items[i].className == listita) {
console.log((items[i].outerHTML));
html += items[i].outerHTML
}
}
// set the html after the for loop
document.getElementById("description").innerHTML = html;
}
onload = see();
// attach the change event handler
dropdown.addEventListener('change', see);
Check Fiddle
try changing the id's to class in the li tags and use this function...
function see(){
var selectedVal = document.getElementById('groopy').options[document.getElementById('groopy').selectedIndex]. value;
var items = document.getElementsByClassName(selectedVal);
var html = '';
for(var i = 0; i < elements.length; i++)
{
html += items[i].outerHTML;
}
document.getElementById("description").innerHTML = html;
}
onload= see();
Step1 - Change id to class
Step2 - Traverse DOM elements with jQuery class selector. In this way replace document.getElementId('id) with $('.className')
I have a lot of <ul> list and try to get from every first li of this list the text.
the markup is simple like:
<ul>
<li>abc</li>
<li>def</li>
<li>ghi</li>
</ul>
and so on.
my jQuery attempt is:
var elems = $('ul'); // returns a nodeList
var arr = jQuery.makeArray(elems);
arr.reverse(); // use an Array method on list of dom elements
for( var i=0; i < elems.length; i++) {
console.log($(this).find('li:lt(1)').text());
}
But I have a mistake in the for loop with $(this). I don't know how to get the first text of ul number 1 or 3 if i don't use $(this).
So how can point it correctly in the for loop?
.each will give you this.
$('ul').each(function() {
console.log($(this).find('li').eq(0).text());
})
Alternative sytax using :first instead of :eq(0)
$('ul').each(function() {
console.log($(this).find('li:first').text());
});
or, to forgo the find() function.
$('ul').each(function() {
console.log( $('li:first', this).text() );
});
you can also use:
$("li:nth-child(1)").each(function()
{
console.log($(this).text());
});
notes:
with :nth-child(n), all children are counted, regardless of what they are.
with :nth-child(n), n is 1-based (the first index is 1 instead of 0)
I have ul list and I need to change the class of one of <li> tags with javascript:
<ul>
<li>...</li>
<li class="something"> <- need to change this class to "myclass" (javascript goes here)</li>
<li>..</li>
</ul>
Thank you.
using jQuery (naturally):
$(function(){
$("li.something").removeClass("something").addClass("myclass");
});
As there seems to be alot of jquery answers and it's not always possible to use jquery (for example if your customer/company won't let you use it arrgh!), here is a plain javascript example.
// Where 'e' is the element in question, I'd advise using document.getElementById
// Unless this isn't possible.
// to remove
if ( e.className.match(/something/) ) {
e.className = e.className.replace("something", "")
}
// to add back in
if ( !e.className.match(/something/) ) {
e.className += " something"
}
This will work with multiple classes, for example:
<li class="something another">...</li>
Using regular javascript:
var listitems = document.getElementsByTagName("li");
for (int i = 0; i < listitems.length; i++)
{
if (listitems[i].className == "something")
{
listitems[i].className = "new class name";
break;
}
}
If your <li> tag had an id attribute, it would be easier, you could just do
document.getElementById("liID").className = "newclassname";
Using JQuery:
$('ul li:nth-child(2)').attr('class', 'myclass');