How to map every element and its children - javascript

I am trying to get every element and alls its children and there children and add them to a list. But at the moment its only showing the first two children.
Is there a better way for doing this?
here is jsfiddle, http://jsfiddle.net/7mNsH/2/
here is what i have so far
$('#main').children().each(function(){
var classs = $(this).attr('class');
$('#hell ul').append('<li class="'+classs+'">'+classs+'</li>');
});
<div id="main">
<div class="inner">
<div class="innerinner"></div>
</div>
<div class="inner2">
<div class="inner2inner2">
<div class="inner2inner2inner2"></div>
</div>
</div>
</div>
so at the moment its currently showing this
<ul>
<li class="inner">inner</li>
<li class="inner2">inner2</li>
</ul>
but i need it to look like this
<ul>
<li class="inner">inner
<ul>
<li class="innerinner">innerinner</li>
</ul>
</li>
<li class="inner2">inner2
<ul>
<li class="innerinner">innerinner
<ul>
<li class="inner2inner2inner2">inner2inner2inner2</li>
</ul>
</li>
</ul>
</li>
</ul>

You seem to be looking for a recursive solution. If you look at your current code, what you are accomplishing is iterating over #main's children, appending them to a ul, and then finishing. You need to be sure to keep checking each child for their own children (and all of their children!) in order to get the fully recursive list of children.
Check out working JSFiddle here: http://jsfiddle.net/uK6kG/5/
function listChildren(element, container) {
//Get the current node's class
var parentClass = element.attr('class');
//Go ahead and construct a list element
var parentContainer = $('<li class="' + parentClass + '">' + parentClass + '</li>');
//Now iterate over the current node's children (if there are any)
if (element.children().length > 0) {
var childList = $('<ul></ul>');
element.children().each(function () {
//Recursively call the list children function!
listChildren($(this), childList);
});
//Actually add the children to the current node
parentContainer.append(childList);
}
//Add us to our own container
container.append(parentContainer);
}
$('#main').children().each(function () {
listChildren($(this), $('#list-container #top-ul'));
});

Related

remove duplicate elements through javascript

how to remove duplicate li in div using js?
<div id="tags">
<li id="tag">sport</li>
<li id="tag">news</li>
<li id="tag">sport</li>
<li id="tag">sport</li>
<li id="tag">cars</li>
</div>
must become:
sport
news
cars
You can do that in following steps:
Select all the elements and create Set containing all the texts of <li>
Then loop through elements list using forEach
Check if the Set doesn't contain the innerHTML of current element then remove the element
If set contains the text then don't remove the element but remove the text from Set
Note: id of element should be unique in the whole document. Two elements can't have same id
const tags = [...document.querySelectorAll('#tags > li')];
const texts = new Set(tags.map(x => x.innerHTML));
tags.forEach(tag => {
if(texts.has(tag.innerHTML)){
texts.delete(tag.innerHTML);
}
else{
tag.remove()
}
})
<div id="tags">
<li>sport</li>
<li>news</li>
<li>sport</li>
<li>sport</li>
<li>cars</li>
</div>
you can just iterate over the selected node list without much overhead using one loop, like this:
let elements = document.querySelectorAll("li");
textArr = [];
elements.forEach(function(d, i) {
if(textArr.indexOf(d.innerText) > -1) {
d.remove();
}
else {
textArr.push(d.innerText);
}
});
<div id="tags">
<li id="tag">sport</li>
<li id="tag">news</li>
<li id="tag">sport</li>
<li id="tag">sport</li>
<li id="tag">cars</li>
</div>

How Get Name Class With Javascript?

Hi everyone i need get name class menu li for load this page
html
<body>
<div class="menu">
<ul>
<li class="page2" id="page2">PAGE TOW</li>
<li class="page3" id="page3">PAGE THREE</li>
</ul>
</div>
<div class="load"></div>
</body>
js
$(document).on('click','.menu li',function(){
var Get_Name_Class = //Get Name Class
if(/* var Get_Name_Class*/).hasClass("page2")) {
$(".load").load('page2.php');
}
else if(/* var Get_Name_Class*/).hasClass("page3")) {
$(".load").load('page3.php');
}
});
how can i this ( get id or class not difference )
Use this to refer the clicked element inside the handler callback.
$(document).on('click','.menu li',function(){
// cache the reference
var $this = $(this);
// check using the cached element
if($this.hasClass("page2")) {
$(".load").load('page2.php');
}
else if($this.hasClass("page3")) {
$(".load").load('page3.php');
}
});
You can do it using jQuery. If it is class you can do:
$(".className")
if it is id you can do:
$("#idName")
if it is just html element you can do:
$("elementName")
Pass this.className with ".php" concatenated to .load()
$(document).on('click','.menu li',function() {
$(".load").load(this.className + ".php")
});
$(document).on('click','.menu li',function(){
// cache the reference
var $this = $(this);
// check using the cached element
if($this.hasClass("page2")) {
$(".load").load('page2.php');
}
else if($this.hasClass("page3")) {
$(".load").load('page3.php');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="menu">
<ul>
<li class="page2" id="page2">PAGE TOW</li>
<li class="page3" id="page3">PAGE THREE</li>
</ul>
</div>
<div class="load"></div>
</body>
use "#" symbol for id so your code becomes
("#idname")
or u can use "this" which points to the present class u are working on
Don't use classnames. One day you'll add an extra class to those elements and your site will stop working and you'll be left wondering why - or in the worst case it'll slip unnoticed.
Say you have one or even more buttons for page2 triggering - than it's the perfect place to use the data-* attribute!
$(document).on('click', '[data-load]', function() {
var page = $(this).data("load");
console.log(page); // Just to test
$(".load").load(page +'.php');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a data-load="page2">PAGE TWO :) me too</a>
<div class="menu">
<ul>
<li data-load="page2">PAGE TOW</li>
<li data-load="page3">PAGE THREE</li>
</ul>
</div>
<div class="load"></div>

Add extra pair of UL using JavaScript/JQuery

I have done coding the first part HTML then JavaScript/JQuery. Now I want to surround the final common list with a UL need to be done using JavaScript/JQuery. So the final common list will be surrounded by two UL instead of one. Eg
Final Outcome
<ul id="CommonLister">
<ul> <!--Need to add this-->
<li class="columnItem">John</li>
<li class="columnItem">Mark</li>
</ul><!--Need to add this-->
</ul>
Current Code
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<ul id="listOne">
<li class="columnItem">John</li><!--will be removed and put under CommonLister-->
<li class="columnItem">James</li>
<li class="columnItem">Mary</li><!--will be removed and put under CommonLister-->
</ul>
<ul id="listTwo">
<li class="columnItem">John</li><!--will be removed and put under CommonLister-->
<li class="columnItem">Mark</li>
<li class="columnItem">Mary</li><!--will be removed and put under CommonLister-->
</ul>
<ul id="CommonLister">
<li class="columnItem">John</li>
<li class="columnItem">Mark</li>
</ul>
</div>
$(function() {
$('#run-code').on('click', function(e) {
e.preventDefault();
//What were you doing? nope.
var currentItems = {}; //Blank object
var $mergeColumn = $('#CommonLister'); //Common list reference
$('.columnItem').each(function(i, el) {
var $el = $(el); //Notation I use to differentiate between the regular HTML Element and jQuery element
if (!currentItems.hasOwnProperty($el.html())) {
//Has this name come up before? if not, create it.
currentItems[$el.html()] = []; //Make it equal to a brand spanking new array
}
currentItems[$el.html()].push(el);
//Add the item to the array
});
$.each(currentItems, function(name, data) {
//Loop through each name. We don't actually use the name variable because we don't care what someone's name is
if (data.length > 1) {
//Do we have more than 1 element in our array? time to move some stuff
$.each(data, function(i, el) {
var $el = $(el); //See note above
if (i == 0) {
//If this is the first element, let's just go ahead and move it to the merge column ul
$el.appendTo($mergeColumn);
} else {
$el.remove(); //Otherwise, we've already got this element so delete this one.
} //end if/else
}); //end $.each(data)
} //end if data.length >1
}); //end $.each(currentItems)
}); //end $.on()
}); //end $(
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="run-code" class="btn btn-success">Click Me</button>
<h4>List 1</h4>
<ul id="listOne">
<li class="columnItem">John</li>
<!--will be removed and put under CommonLister-->
<li class="columnItem">James</li>
<li class="columnItem">Mary</li>
<!--will be removed and put under CommonLister-->
</ul>
<h4>List 2</h4>
<ul id="listTwo">
<li class="columnItem">John</li>
<!--will be removed and put under CommonLister-->
<li class="columnItem">Mark</li>
<li class="columnItem">Mary</li>
<!--will be removed and put under CommonLister-->
</ul>
<h4>Common List</h4>
<ul id="CommonLister">
<!--Extra ul will be added here-->
</ul>
It's invalid nesting a ul directly in a ul like this but if you have to, you could use jquery wrapAll:
$( "li" ).wrapAll( "<ul></ul>" );
See fiddle: https://jsfiddle.net/9xLt6d9f/
I agree with charlietfl that it seems strange to do it this way. However, to answer your question, the best way to force this improperly formatted HTML code would be hardcode it into your original file. Try the following code for the end of your file:
<h4>Common List</h4>
<ul id="CommonLister">
<ul id="CommonListerSub">
<!--Extra ul will be added here-->
</ul>
</ul>
Then, simply change one line of your code:
var $mergeColumn = $('#CommonListerSub'); //Common list reference
This will force it to list the list items under the nested ul tags.
I hope this is an acceptable solution. If for some reason it doesn't work, please comment as to what additional limitations you have, and perhaps share the link of the page that is giving you the required template or format specifications.

Javascript/Jquery: Number nested list

I have a nested list:
<ul>
<li id="1">first</li>
<li id="2">second</li>
<ul>
<li id="2-1">second nested first element</li>
<li id="2-2">second nested secondelement</li>
<li id="2-3">second nested thirdelement</li>
<ul>
<li id="2-3-1">Other</li>
</ul>
</ul>
<li id="3"i>third</li>
<li id="4">fourth</li>
</ul>
Each element has an id that indicates the position within the list. How do I generate it automatically?
Thank you.
UPDATE:
html is generated by Apache velocity without ID. I'm trying to create a method for updating the id if you move elements with jquery sortable. The structure of the id must be "1" for the first item "1-1" for the first element of the first "li". I tried using index () but I can't generate the id in the form that I need
It's not clear what you exactly want to do here, but here's an example of generating dynamic li's with dynamic id's:
HTML:
<ul id="autoGenerated">
</ul>
JS:
for(var i = 1; i < 3 ;i++){
$("#autoGenerated").append("<li id=2-" + i + ">Testing " + i + "</li>")
}
$('#autoGenerated li').click(function(){
alert($(this).attr("id"));
})
Fiddle.

Prototype - Show one element, hide siblings

I've got this html below.
I need all div's inside div#ProductImagesContainer to be hidden at startup, all but div#productImageA.
When you click a.productImageB, the corresponding div#productImageB inside div#ProductImagesContainer should be shown and it's siblings should hide.
I need to use Prototype for this project, but I'm not a javascript genious. Would know what to do with jQuery but can't do it with Prototype.
<ul>
<li>
A
</li>
<li>
B
</li>
<li>
C
</li>
<li>
D
</li>
</ul>
<div id="ProductImagesContainer">
<div id="productImageA">maybe flash video</div>
<div id="productImageB">imageB</div>
<div id="productImageC">imageC</div>
<div id="productImageD">imageD</div>
</div>
My JavaScript is a bit rusty, but I believe you want the following:
Hide everything:
$$('#ProductImagesContainer div').invoke('hide');
Show the one you want:
$('ProductImageA').show();
Edit: documentation on prototype's api can be found here
Here is the jsfiddle to achieve what you are looking for in prototype:
Given HTML:
<ul>
<li>
A
</li>
<li>
B
</li>
<li>
C
</li>
<li>
D
</li>
</ul>
<div id="ProductImagesContainer">
<div id="productImageA">maybe flash video</div>
<div id="productImageB">imageB</div>
<div id="productImageC">imageC</div>
<div id="productImageD">imageD</div>
</div>
Prototype JavaScript:
//declare global variables to access within functions and etc...
var myLi = $$('li'); //get all the li a links
var myDiv = $('ProductImagesContainer').children; //get all the children of div#ProductImagesContainer
hideAllBut(null); //first hide all the divs
//function to hideAllBut the child div element of #ProductImagesContainer w/ the following classname as id
function hideAllBut(el) {
var toShow = el;
for (var index = 0; index < myDiv.length; index++) {
if (myDiv[index].identify() == toShow)
myDiv[index].show();
else
myDiv[index].hide();
};
}
//oops through each li
myLi.each(function(myLiEl) {
//attached on click event for each of the hyperlinks and use the hyperlink's class name to call hideAllBut(theclassname)
Event.observe(myLiEl, 'click', function() {
hideAllBut(myLiEl.firstDescendant().className); //gets the className of first decendant based on your example
});
});
First we declare two global variables to hold all the li's a links and children of div#ProductImagesContainer. Then we create a function called hideAllBut(el); where it hides all but the child div element of #ProductImagesContainer w/ the classname as id. A parameter, which is the classname of link that is associated w/ the div element's id name that we need to hide. Then we proceed to oop through each li and add an onclick event so whenever the li is clicked it'll call hideAllBut(); and pass its classname as the param.
Based on kjy112's detailed answer, here is a shorter version.
HTML:
<ul id="ProductImagesLinks">
<li>
A
</li>
<li>
B
</li>
<li>
C
</li>
<li>
D
</li>
</ul>
<div id="ProductImagesContainer">
<div id="productImageA">maybe flash video</div>
<div id="productImageB">imageB</div>
<div id="productImageC">imageC</div>
<div id="productImageD">imageD</div>
</div>
Javascript:
$('ProductImagesLinks').on('click', 'a', function(event, element){
var target = $(element.readAttribute('data-target'));
if (target) {
target.show();
$$('#ProductImagesContainer > div[id!='+target.identify()+']').invoke('hide');
}
});
$('ProductImagesContainer').down().siblings().invoke('hide');
The advantage here is it adapts if the list changes by utilising event bubbling.

Categories

Resources