How to create nested elements in JavaScript? - javascript

Here's my HTML. I target to create elements in Javascript and insert it into div with the class "wrap" but didn't succeed.
<div class="wrap">
<div class="shelf">
<div class="shelf-background">
<div class="base">
</div>
</div>
</div>
</div>
var base = document.createElement('div');
var shelfBackground = document.createElement('div');
var wrap = document.querySelector(".wrap");
var shelf = document.createElement('div');
shelfBackground.className = "shelf-background";
base.className = "base";
shelf.className = "shelf";
shelfBackground.appendChild(base);
wrap.append(shelf, shelfBackground, shelfBackground.appendChild(base));
I get
<div class="wrap">
<div class="shelf"></div>
<div class="shelf-background"></div>
<div class="base"></div>
</div>

Right now, you are appending base to the background, and then appending all of the elements to the wrap element at the top level. Also note, when you call shelfBackground.appendChild(base), it returns the appended child base which is why it is the last element in your output structure.
What you need to do is instead append the elements based to their respective parents, i.e.:
...
// Build the structure from the bottom up
shelfBackground.appendChild(base); // shelf-background > base
shelf.appendChild(shelfBackground); // shelf > shelf-background > base
wrap.appendChild(shelf); // wrap > shelf > shelf-background > base

Try this:
var wrap = document.querySelector(".wrap");
var base = document.createElement('div');
var shelfBackground = document.createElement('div');
var shelf = document.createElement('div');
base.className = "base";
shelfBackground.className = "shelf-background";
shelf.className = "shelf";
shelfBackground.appendChild(base);
shelf.appendChild(shelfBackground);
wrap.appendChild(shelf);
document.appendChild(wrap);

Related

How I can create multiple DIVs with ’append’ in jQuery?

I want to loop multiple DIV elements.
There are 5 books. I want to loop 5 books in ID: BootLoop.
What I tried?
my_orders.append(data[i].order.bname).appendTo("#bookLoop > div > div > div > h3");
my_orders.append(data[i].order.blink).appendTo("#bookLoop > div > div > div > a");
It didn't work. Where am I making a mistake?
JS:
var my_orders = $("#bookLoop");
$.each(data, function(i, order) {
$("#bookName").append(data[i].order.bname);,
$("#bookURL").append(data[i].order.blink);
});
HTML (Code structure that should be loop):
<div id="bookLoop">
<div class="col-3">
<div class="block-content">
<div class="d-md-flex">
<h3 id="bookName" class="h4 font-w700"></h3>
<div>
<div class="d-md-flex link">
Details
<div>
<div>
<div>
<div>
JSON:
[
{"order":{"id":"61","bname":"Book 1","blink":984}},
{"order":{"id":"42","bname":"Book 2","blink":5414}},
{"order":{"id":"185","bname":"Book 3","blink":4521}},
{"order":{"id":"62","bname":"Book 4","blink":41254}},
{"order":{"id":"15","bname":"Book 5","blink":7464}}
]
I think that what you want is to append each book and link inside #bookLoop, beign each book and link with it's own content.
Below I'm creating elements (nodes) to each book you have then appending it to my_orders.
Take a look if it is what you want, if not, please edit your question showing an example of the desired rendered HTML
var my_orders = $("#bookLoop");
var books = ''
var links = ''
let data = [
{"order":{"id":"61","bname":"Book 1","blink":984}},
{"order":{"id":"42","bname":"Book 2","blink":5414}},
{"order":{"id":"185","bname":"Book 3","blink":4521}},
{"order":{"id":"62","bname":"Book 4","blink":41254}},
{"order":{"id":"15","bname":"Book 5","blink":7464}}
]
$.each(data, function(i, order) {
let col = document.createElement('div')
col.className = 'col-3'
let content = document.createElement('div')
content.className = 'block-content'
let flexC = document.createElement('div')
flexC.className = 'd-md-flex'
let title = document.createElement('h3')
title.className = 'h4 font-w700'
title.textContent = data[i].order.bname;
flexC.append(title)
let flexL = document.createElement('div')
flexL.className = 'd-md-flex link'
let details = document.createElement('a')
details.className = 'bookURL'
details.href = "#"
details.textContent = "Details: " + data[i].order.blink
flexL.append(details)
my_orders.append(col)
col.append(content)
content.append(flexC)
content.append(flexL)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="bookLoop">
<div>

Create multiple div using data from array using for loop

I want to assign array elements to multiple divs which also have image tag in them using for loop.
Array consists of image paths.
var img_list = ["one.png", "two.png", "three.png", "four.png"];
By using above array I have to create below HTML Structure. All divs should be inside "outer" div with a data-slide attribute which is without ".png".
<div id="outer">
<div class="slide" data-slide="one"><img src="Images/one.png" /></div>
<div class="slide" data-slide="two"><img src="Images/two.png" /></div>
<div class="slide" data-slide="three"><img src="Images/three.png" /></div>
<div class="slide" data-slide="four"><img src="Images/four.png" /></div>
</div>
This is what I wrote:
for (var i=0; i < img_list.length; i++){
var container = document.getElementById("outer").innerHTML;
var new_card = "<div class=\"slide\" data-slide=\'" + img_list[i] + "\'><img src=\'Images/" + img_list[i] + "\' /></div>";
document.getElementById("outer").innerHTML = new_card;
}
But it is only showing the last image.
Please help.
Each time your for loop runs, it is replacing the html element within the "outer" div with the current img html.
In order to have it append you can simply change
document.getElementById("outer").innerHTML = new_card;
to
document.getElementById("outer").innerHTML += new_card; so that the element is appended rather than overwritten.
The code at the question overwrites the .innerHTML within the for loop by setting .innerHTML to new_card at every iteration of the array. You can substitute .insertAdjacentHTML() for setting .innerHTML. Also, substitute const for var to prevent new_card from being defined globally. Include alt attribute at <img> element. You can .split() img_list[0] at dot character ., .shift() the resulting array to get word before . in the string img_list[i] to set data-* attribute value.
const img_list = ["one.png", "two.png", "three.png", "four.png"];
for (let i = 0, container = document.getElementById("outer"); i < img_list.length; i++) {
const src = img_list[i];
const data = src.split(".").shift();
const new_card = `<div class="slide" data-slide="${data}"><img src="Images/${src}" alt="${data}"/></div>`;
container.insertAdjacentHTML("beforeend", new_card);
}
<div id="outer"></div>
You are changing the innerHTML you need to add to it. And use Template literals for creating html strings
var img_list = ["one.png", "two.png", "three.png", "four.png"];
const outer = document.getElementById('outer')
img_list.forEach(img => {
outer.innerHTML += `<div class="slider" data-slide="${img.split('.')[0]}"><img src="Images/${img}" /></div>`
})
console.log(outer.innerHTML)
<div id="outer">
</div>
#Tony7931, please replace the last line of for loop with below code:
document.getElementById("outer").innerHTML += new_card;
You are almost there but, every time you are overriding the slider div.
You just have to add + at assignments section. like below.
document.getElementById("outer").innerHTML += new_card;
Here is the full example:
var img_list = ["one.png", "two.png", "three.png", "four.png"];
for (var i=0; i < img_list.length; i++){
var container = document.getElementById("outer").innerHTML;
var new_card = "<div class=\"slide\" data-slide=\'" + img_list[i].split('.')[0] + "\'><img src=\'Images/" + img_list[i] + "\' /></div>";
document.getElementById("outer").innerHTML += new_card;
}
<div id="outer"></div>
You could also use map method of array and Element.innerHTML to get the required result.
The map() method creates a new array with the results of calling a provided function on every element in the calling array.
Demo
const img_list = ["one.png", "two.png", "three.png", "four.png"];
let result = img_list.map((v, i) => `<div class="slide" data-slide="${v.split(".")[0]}"><img src="Images/${v}"/>${i+1}</div>`).join('');
document.getElementById('outer').innerHTML = result;
<div id="outer"></div>
You can declare your variables outside of the loop and reuse them. This is more efficient.
const and let are preferable to var. You only need to set container once so it can be const. new_card should be let since you need to assign it more than once.
You can also use template string so you don't need all the back slashes.
using forEach will make the code cleaner:
const img_list = ["one.png", "two.png", "three.png", "four.png"];
const container = document.getElementById("outer")
let new_card;
img_list.forEach(i => {
new_card = `<div class=slide data-slide='${i.split(".")[0]}'><img src='Images/${i}'></div>`
container.innerHTML += new_card;
})
<div id="outer">
</div>
Alternately, using reduce:
const img_list = ["one.png", "two.png", "three.png", "four.png"];
const container = document.getElementById("outer")
const reducer = (a, i) => a + `<div class=slide data-slide='${i.split(".")[0]}'><img src='Images/${i}'></div>`
container.innerHTML = img_list.reduce(reducer, '')
<div id="outer">
</div>

How to put a link in a div?

Suppose I have this HTML:
<article id="1919">
<div class="entry-content clearfix">
<div></div>
<div></div>
</div>
</article>
<article id="1910">
<div class="entry-content clearfix">
<div></div>
<div></div>
</div>
</article>
I need to put a link in div with class "entry-content clearfix" for all articles
So can I do it JavaScript:
//take all div with these class value
var eventi_programma=document.getElementsByClassName('entry-content');
//for to read these elements
for(var i=0;i<eventi_programma.length;i++){
var link="http://www.google.it";//(LINK EXAMPLE);
eventi_programma[i].parentElement.innerHTML=''+eventi_programma[i].outerHTML+'</div>';
}
But my code doesn't work.
(function (){
var eventi_programma=document.getElementsByClassName('entry-content');
//for to read these elements
for(var i=0;i<eventi_programma.length;i++){
var link="http://www.google.it";//(LINK EXAMPLE);
eventi_programma[i].parentElement.innerHTML=' THIS IS A LINK </div>';
}
})();
It didn't work because you are putting eventi_programma[i].outerHTML as text of the link. As your for loop is based on .entry-content class it basicly creates a never ending for loop since you keep creating new divs with that classname. So instead of putting outerHTML put some other text.
I assume your entry-content class has only one in every article tag ! So I retrieve all article and added then replace it.
var eventi_programma = document.getElementsByTagName("article");
//for to read these elements
for(var i=0;i<eventi_programma.length;i++){
var link="http://www.google.it";//(LINK EXAMPLE);
org_html = eventi_programma[i].innerHTML;
new_html = "<a href='"+link+"'>" + org_html + "</a>";
eventi_programma[i].innerHTML = new_html;
}
//take all div with these class value
var eventi_programma = $('div.entry-content');
//for to read these elements
for (var i = 0; i < eventi_programma.length; i++) {
var link = "http://www.google.it";//(LINK EXAMPLE);
var temp = eventi_programma[i];
$(temp).parent('article').html('</div>')
}
try it...

How to get innerHTML of DIV without few inside DIV's?

I have some DIV, what contains HTML with images, styles e.t.c. I want to remove exact div's that contains id = 'quot' or className = 'quote', but i don't understand how i can get not only innerHTML of each tag. For example, < p > and < /p > which don't have innerHTML also should be included in final parsed HTML.
var bodytext = document.getElementById("div_text");
var NewText = "";
if (bodytext.hasChildNodes){
var children = bodytext.childNodes;
for (var i = 0; i < children.length; i++){
if (children[i].id != "quot" && children[i].className != "quote" && children[i].innerText != ""){
NewText = NewText + children[i].innerHTML;
}
}
HTML of source need to be parsed:
<div id="div_text">
<p>
Some Text</p>
<p>
Some Text</p>
<p>
<img alt="" src="localhost/i/1.png" /></p>
<div id="quot" class="quote" />
any text <div>text of inside div</div>
<table><tr><td>there can be table</td></tr></table>
</div>
<p>
</p>
</div>
Desired output:
<p>
Some Text</p>
<p>
Some Text</p>
<p>
<img alt="" src="localhost/i/1.png" /></p>
<p>
</p>
Just grab a reference to the targeted divs and remove them from their respective parents.
Perhaps something a little like this?
EDIT: Added code to perform operation on a clone, rather than the document itself.
div elements don't have .getElementById method, so we search for an element manually.
window.addEventListener('load', myInit, false);
function removeFromDocument()
{
// 1. take car of the element with id='quot'
var tgt = document.getElementById('quot');
var parentNode = tgt.parentNode;
parentNode.removeChild(tgt);
// 2. take care of elements whose class == 'quote'
var tgtList = document.getElementsByClassName('quote');
var i, n = tgtList.length;
for (i=0; i<n; i++)
{
// we really should be checking to ensure that there aren't nested instances of matching divs
// The following would present a problem - <div class='quote'>outer<div class='quote'>inner</div></div>
// since the first iteration of the loop would also remove the second element in the target list,
parentNode = tgtList[i].parentNode;
parentNode.removeChild(tgtList[i]);
}
// 3. remove the containing div
var container = document.getElementById('div_text');
container.outerHTML = container.innerHTML;
}
function cloneAndProcess()
{
var clonedCopy = document.getElementById('div_text').cloneNode(true);
var tgt;// = clonedCopy.getElementById('quot');
var i, n = clonedCopy.childNodes.length;
for (i=0; i<n; i++)
{
if (clonedCopy.childNodes[i].id == 'quot')
{
tgt = clonedCopy.childNodes[i];
var parentNode = tgt.parentNode;
parentNode.removeChild(tgt);
break; // done with for loop - can only have 1 element with any given id
}
}
// 2. take care of elements whose class == 'quote'
var tgtList = clonedCopy.getElementsByClassName('quote');
var i, n = tgtList.length;
for (i=0; i<n; i++)
{
// we really should be checking to ensure that there aren't nested instances of matching divs
// The following would present a problem - <div class='quote'>outer<div class='quote'>inner</div></div>
// since the first iteration of the loop would also remove the second element in the target list,
parentNode = tgtList[i].parentNode;
parentNode.removeChild(tgtList[i]);
}
// 3. remove the containing div
//var container = clonedCopy; //.getElementById('div_text');
//container.outerHTML = container.innerHTML;
console.log(clonedCopy.innerHTML);
}
function myInit()
{
cloneAndProcess();
//removeFromDocument();
}

How to create a clickable list of divs with sub items using JavaScript

I want to create a list of clickable divs from arrays using Javascript, where the list structure has to be something like this:-
<div id="outerContainer">
<div id="listContainer">
<div id="listElement">
<div id="itemId"> </div>
<div id="itemTitle"> </div>
<div id="itemStatus"> </div>
</div>
<div id="listElement">
<div id="itemId"> </div>
<div id="itemTitle"> </div>
<div id="itemStatus"> </div>
</div>
</div>
</div>
I want to extract the values of itemId, itemTitle and itemStatus from three arrays itemIdData[ ], itemTitleData[ ] and itemStatusData[ ] respectively, to create the whole list.
Also, when I click on any of the listElements, I want an alert showing the itemId. Can anyone help me with this problem.
If you're using jQuery, then try something like this:
$("#listContainer").on("click", "div", function () {
console.log("jQuery Event Delegation");
alert($(this).find(">:first-child").attr("id"));
});
It's possible to write the same thing without jQuery, but will take further lines of code - I'm conveying the idea of delegation here (there are extensive existing docs and examples on the JQuery site, and here on this site).
NB: the code you're submitted in the question can't(shouldn't) have multiple DOM elements with same IDs (that's what classes are for - for semantically similar elements). Also, trying to emulate a list using divs instead of li elements is perhaps not best practice.
After a bit of experimentation, understood what I was doing wrong and how to get it done.
Here's the code:-
var listContainer = document.createElement("div");
document.getElementById("outerContainer").appendChild(listContainer);
for (var i = 0; i < json.length; i++) {
//create the element container and attach it to listContainer.
var listElement = document.createElement("div");
listElement.id = i;
listElement.className = "listItemContainer";
listElement.addEventListener("click", function(e){
var itemId = e.target.children[1].innerHTML;
alert(itemId);
});
listContainer.appendChild(listElement);
//create and attach the subchilds for listElement.
var itemTitle = document.createElement("span");
itemTitle.innerHTML = postTitleData[i];
itemTitle.id = 'title'+i;
itemTitle.className = "itemTitle";
listElement.appendChild(itemTitle);
var itemId = document.createElement("div");
itemId.innerHTML = postIdData[i];
itemId.id = 'id'+i;
itemId.className = "itemId";
listElement.appendChild(itemId);
var itemStatus = document.createElement("span");
itemStatus.innerHTML = postStatusData[i];
itemStatus.id = 'status'+i;
itemStatus.className = "itemStatus";
listElement.appendChild(itemStatus);
}
Tried something like this which isn't quite working!
var listContainer = document.createElement("div");
document.getElementById("outerContainer").appendChild(listContainer);
var listElement = document.createElement("div");
listContainer.appendChild(listElement);
listElement.className = "listItemContainer";
for (var i = 0; i < json.length; i++) {
var itemId = document.createElement("div");
itemId.innerHTML = idData[i];
listElement.appendChild(itemId);
itemId.className = "itemId";
var itemTitle = document.createElement("div");
itemTitle.innerHTML = titleData[i];
listElement.appendChild(itemTitle);
itemTitle.className = "itemTitle";
var itemStatus = document.createElement("div");
itemStatus.innerHTML = statusData[i];
listElement.appendChild(itemStatus);
itemStatus.className = "itemStatus";
listElement.appendChild(document.createElement("hr"));
var elementId = 'ListElement'+i;
listElement.id = elementId;
listElement.addEventListener("click", function(){
alert(document.getElementById(elementId).innerHTML);
});
}

Categories

Resources