By iterating, dynamically set variables using strings from array - javascript

I got stuck. I need to create 4 new elements which will have the same class and different ID. The point is that I do not want to repeat a code... but my loop does not work.
I was trying to overcome this challenge for like 2 hours already (doing also a lot of research in Google), trying to find out what is going on using console.log and printing elements inside the iteration. Then, I needed to print console.dir to see attributes of created [object HTMLDivElement].
The code looks like this:
columnsArray = ["first", "second", "third", "fourth"]
for (var i = 0; i < columnsArray.length; i++ ) {
let name = columnsArray[i]
name = document.createElement("div");
name.className = "container"
name.setAttribute("id", name.name)
document.querySelector("#board" + boardId).appendChild(name);
}
I wonder if there is any relatively simple way (worth of trying) to achieve my aim? Except for this:
let first = document.createElement("div");
let second = document.createElement("div");
let third = document.createElement("div");
let fourth = document.createElement("div");
first.className = "container"
second.className = "container"
third.className = "container"
fourth.className = "container"
first.setAttribute = "first"
second.setAttribute = "second"
third.setAttribute = "third"
fourth.setAttribute = "fourth"
document.querySelector("#board" + boardId).appendChild(first);
document.querySelector("#board" + boardId).appendChild(second);
document.querySelector("#board" + boardId).appendChild(third);
document.querySelector("#board" + boardId).appendChild(fourth);
Thanks in advance for help;)

You're overriding the ID value from columnsArray in your loop by creating it as an element.
Create your element within a new variable:
columnsArray = ["first", "second", "third", "fourth"]
for (var i = 0; i < columnsArray.length; i++ ) {
// get the ID value from the array
let name = columnsArray[i];
// create a new element
let element = document.createElement("div");
// set its name
element.className = "container"
// set the ID value to columnsArray[i] (name)
element.setAttribute("id", name)
// append to board
document.querySelector("#board" + boardId).appendChild(element);
}

Your loop works fine, you just can't access the name in the way you think.
You have to set the id like this:
name.setAttribute("id", columnsArray[i])
name.name doesn't exist.
columnsArray = ["first", "second", "third", "fourth"];
boardId = 1;
for (var i = 0; i < columnsArray.length; i++ ) {
let name = document.createElement("div");
name.className = "container"
name.setAttribute("id", columnsArray[i]) // set name.id to columnsArray[i]
name.innerHTML = "DIV id="+columnsArray[i]
document.querySelector("#board" + boardId).appendChild(name);
console.log(name, name.id)
}
<div id="board1"></div>

Use name.setAttribute("id", columnsArray[i]) instead of name.setAttribute("id", name.name)
After that use
name.innerHTML = columnsArray[i]; //Replace it for some info or element
document.querySelector("#board" + boardId).appendChild(name);

use this:
columnsArray = ["first", "second", "third", "fourth"]
for (i in columnsArray) {
let name = columnsArray[i]
name = document.createElement("div");
name.className = "container"
name.setAttribute("id",columnsArray[i])
document.getElementById('boardId').appendChild(name);
}

Related

Is there a way so that elements which are getting added inside javascript function on the click of array of elements should be added only once?

Pre-Requisite: allPanelElems1[j] has elements such as t1, t2, t3 etc. which are div elements.
I am calling the javascript function handlePanelClick1 on array of elements. Inside the function I am adding up some other element i.e apiinfo. Now this function is called for each of element inside array allPanelElems1[j]. When a user clicks on any element of allPanelElems1[j] (let's say t1), then inside function element apiinfo is added successfully but when user clicks on the same element (t1) again then the element apiinfo is added again.
Is there a way, so that when user click on any element for the first time the apiinfo element should be added. But if the user calls the element again then apiinfo should not be added. Similarly for other elements t2, t3 etc ?
var allPanelElems1 = accordionElem.querySelectorAll(".panel1");
for (var j = 0, len1 = allPanelElems1.length; j < len1; j++) {
allPanelElems1[j].addEventListener("click", handlePanelClick1);
}
function handlePanelClick1(event) {
if (event.currentTarget.getAttribute('class').indexOf('active') >= 0) {
event.currentTarget.classList.remove("active");
} else {
prod1 = {
"Testcase": [{
"apiName": " demoAPIname1",
"request": "req",
"response": " res"
},
{
"apiName": " demoAPI name2",
"request": " req",
"response": "res"
}
]
};
var projectBody1 = document.createElement("div");
for (var propt1 in prod1) {
var projectBody2 = document.createElement("div");
var project1 = prod1[propt1];
for (var i in project1) {
var temp = document.createElement("div");
var apiname = project1[i].apiName;
var request1 = project1[i].request;
var response1 = project1[i].response;
var t1 = document.createElement("div");
var r1 = document.createElement("div");
var t2 = document.createElement("div");
var r2 = document.createElement("div");
r1.innerHTML = request1;
r2.innerHTML = response1;
t1.appendChild(createPanel("request", r1, "apidata"));
t2.appendChild(createPanel("response", r2, "apidata"));
temp.appendChild(t1);
temp.appendChild(t2);
projectBody2.appendChild(createPanel(apiname, temp, "apipanel"));
}
}
projectBody1.appendChild(createPanel("apiinfo", projectBody2, "apititle"));
var accordion4 = event.currentTarget; //THIS LINE I AM ASSIGNING MY current element
accordion4.appendChild(projectBody1);
var allPanelElems4 = accordion4.querySelectorAll(".panel");
for (var i = 0, len = allPanelElems4.length; i < len; i++) {
allPanelElems4[i].addEventListener("click", handlePanelClick);
}
event.currentTarget.classList.add("active");
}
event.stopPropagation();
}
I mean this sounds pretty stupid but couldn't you just clear the element's child/s before adding the new one? So It would only ever exist once?
element.innerHTML = "";
...
...
element.appendChild(child);
In case speed matters: Children removal ... sounds bad xD
Or you could check if the child count is more than 1
if(div.childNodes.length > 1) return
Check a specific ID
let children = Array.from(div.childNodes);
for(let i = 0; i < children.length; i++) {
if(children[i].id == "onlyOnce") return;
}
// Append child then as following:
let childElement = document.createElement("div");
childElement.id = "onlyOnce";
div.appendChild(childElement);
EDIT:
Greeting Elias :D

use elements ID to find value in object JavaScript

I'm looping through some elements by class name, and adding event listeners to them. I then grab the id of the selected element (in this case "tom"), and want to use it to find the value of "role" in the "tom" object. I'm getting undefined? can anyone help?
var highlightArea = document.getElementsByClassName('highlightArea');
for (var i = 0; i < highlightArea.length; i++) {
highlightArea[i].addEventListener("mouseover", showPopup);
highlightArea[i].addEventListener("mouseover", hidePopup);
}
function showPopup(evt) {
var tom = { title:'tom', role:'full stack man' };
var id = this.id;
var role = id.role;
console.log(role)
}
You are not selecting the elements correctly, the class is hightlightArea and you are querying highlightArea (missing a 't'), so, no elements are found (you can easily discover that by debugging or using console.log(highlightArea) that is the variable that holds the elements found.
Just because the id of an element is the same name as a var, it doesn't mean that it have the properties or attributes of the variable... So when you get the Id, you need to check which one is and then get the variable that have the same name.
Also, you are adding the same listener two times mouseover that way, just the last would work, it means just hidePopup. I changed to mouseenter and mouseleave, this way will work correctly.
After that, you will be able to achieve your needs. Below is an working example.
var highlightArea = document.getElementsByClassName('hightlightArea');
var mypopup = document.getElementById("mypopup");
var tom = { title:'tom', role:'marketing'};
var jim = { title:'jim', role:'another role'};
for (var i = 0; i < highlightArea.length; i++) {
highlightArea[i].addEventListener("mouseenter", showPopup);
highlightArea[i].addEventListener("mouseleave", hidePopup);
}
function showPopup(evt) {
let ElemId = this.id;
let role;
let title;
if (ElemId == 'tom'){
role = tom.role;
title = tom.title;
}else if (ElemId == 'jim'){
role = jim.role;
title = jim.title;
}
let iconPos = this.getBoundingClientRect();
mypopup.innerHTML = role;
mypopup.style.left = (iconPos.right + 20) + "px";
mypopup.style.top = (window.scrollY + iconPos.top - 60) + "px";
mypopup.style.display = "block";
}
function hidePopup(evt) {
mypopup.style.display = "none";
}
<div class="hightlightArea" id="jim">Div Jim</div>
<div class="hightlightArea" id="tom">Div Tom</div>
<div id="mypopup"></div>
in your function 'showPopup' you have this:
var id = this.id
but this.id is not defined. You probably meant to write this:
var title = dom.title;

HierarchyRequestError: Node cannot be inserted at the specified point in the hierarchy

var fieldArray = [];
var fields = {{ json_encode(Config::get('planner.'.$viewType.'_view_jobs')) }};
for(var i in fields) {
fieldArray.push([i, fields [i]]);
}
var outDiv = document.createElement('div');
for (var x = 0; x < fieldArray.length; x++) {
container[x] = document.createElement('div');
label[x] = document.createElement('div');
label[x].className = "label-job control-label";
$(label[x]).text(fieldArray[x][0]);
value[x] = document.createElement('div');
value[x].className = "label-value numeric";
eval("$(value[x]).text(event." + fieldArray[x][1] + ");");
container[x].appendChild(label[x]);
container[x].appendChild(value[x]);
}
outDiv.appendChild(container);
element.attr("data-toggle", "popover");
element.attr("data-content", $(outDiv).text());
element.append("<br />");
Hi All, this is my code. I am trying to append multiple 'label', 'value' into 'container'. Then append multiple 'container' into 'OutDiv'. However I got this error.
fieldArray = [["Ttl Job", "ttl_job"], ["Ctr Job", "ctr_job"]];
label, value, container is the var that store my createElementDiv
I really need your help. Thanks.

Appending htmlfragment to an element

I am loading json data and displaying them on site inside div.
I decided to store the data inside an htmlfragment using
var docFragment = new DocumentFragment();
function createFullList(){
var aside = document.getElementsByClassName("one")[0];
for( x in obj ){
createInfoElement( docFragment , obj[x].general , obj[x].job );
}
var div = document.createElement("div");
div.appendChild(docFragment);
aside.innerHTML += div;
}
crateInfoElement just creates div and append it to docFragment.
What is troublling me is when i want to append an documentFragment into its supposed holder ( aside variable ).
It does not display all divs inside it instead of it just
[object HTMLDivElement]
I do not have much experience with fragments , but using example from MDN
var ul = document.getElementsByTagName("ul")[0]; // assuming it exists
var docfrag = document.createDocumentFragment();
var browserList = ["Internet Explorer", "Mozilla Firefox", "Safari", "Chrome", "Opera"];
browserList.forEach(function(e) {
var li = document.createElement("li");
li.textContent = e;
docfrag.appendChild(li);
});
ul.appendChild(docfrag);
it does display ul and li elements inside it not just
[object HTMLDivElement]
as in my case. What is causing this behavior?
createInfoElement looks like this
function createInfoElement( parent , name , job ){
var div = document.createElement("div");
div.setAttribute("class","left_info");
var p = document.createElement("p");
p.setAttribute("class","name");
p.innerHTML = name.firstName + " " + name.lasName;
var p_two = document.createElement("p");
p_two.setAttribute("class","job");
p_two.innerHTML = job.title;
div.appendChild(p);
div.appendChild(p_two);
parent.appendChild(div);
}

Having trouble with createElement and appendChild

I have a reasonably simple idea that I would like to implement.
I have an array of objects with two properties: "id" and "name" I would like to list these in a series of "p" tags that would be within a "div".
So here is the HTML:
<body>
<div id="listView"></div>
</body>
And here is the JavaScript in the tag:
sessionStorage.eventid = 2;
var playerList = [];
playerList[0].id = 0;
playerList[0].name = "Add New Player";
playerList.push({
id: 5,
name: "Asako"
});
playerList.push({
id: 6,
name: "James"
});
playerList.push({
id: 7,
name: "Brian"
});
playerList.push({
id: 8,
name: "Helmut Spargle"
});
function listAll() {
var element = document.getElementById("listView");
var div;
var node;
for (var i = 0; i < playerList.length; i++) {
div = document.createElement("div");
div.setAttribute("onClick", "javascript: formOver(" + playerList[i].id + ")");
node = "<p>" + playerList[i].name + "<br />\n" +
"<small>&nbsp</small>\n" +
"</p>\n";
div.appendChild(node);
element.appendChild(div);
}
}
window.onLoad = function(){
listAll();
}
This doesn't fill the with anything. I have put this up on JSFiddle as well.
Have I misunderstood how Array.push works? Or something to do with appendChile and createElement?
Thanks in advance for your help.
Two problems - up front, trying to set the id and name on playerList[0] (which doesn't exist yet) won't work.
Second, trying to add a whole "node" full of html, jQuery-style, doesn't work in a plain-JS world. You need to build up the individual elements.
sessionStorage.eventid = 2;
var playerList = [];
playerList.push({
id: 0,
name: "Add New Player"
});
playerList.push({
id: 5,
name: "Asako"
});
playerList.push({
id: 6,
name: "James"
});
playerList.push({
id: 7,
name: "Brian"
});
playerList.push({
id: 8,
name: "Helmut Spargle"
});
function listAll() {
var element = document.getElementById("listView");
var div = document.createElement("div");
var node = "some string";
for (var i = 0; i < playerList.length; i++) {
div = document.createElement("div");
div.setAttribute("onClick", "formOver(" + playerList[i].id + ")");
var p = document.createElement('p');
p.innerHTML = playerList[i].name;
var br = document.createElement('br');
p.appendChild(br);
var small = document.createElement('small');
small.innerHTML = ' ';
p.appendChild(small);
div.appendChild(p);
element.appendChild(div);
}
}
listAll();
Example: http://jsfiddle.net/NF45y/
Initially:
var playerList = [];
playerList[0].id = 0;
You should get an error here about trying to set the id property of undefined. You can do:
var playerList = [{}];
playerList[0].id = 0;
playerList[0].name = "Add New Player";
or add the object the same way the others are. Within the function;
function listAll() {
var element = document.getElementById("listView");
var div;
var node;
for (var i = 0; i < playerList.length; i++) {
div = document.createElement("div");
div.setAttribute("onClick", "javascript: formOver(" + playerList[i].id + ")");
Don't use setAttribute to add listeners that way, it's not how it's intended to be used and doesn't work everywhere, use DOM properties for simplicity:
div.onclick = function(){...};
Since you are setting values inside a loop, you need to break the closure with the variables. An immediately invoked function expression (IIFE) can help:
div.onclick = (function(id) {
return function(){formOver(id);}
}(playerList[i].id));
Don't use XML syntax in an HTML document, and there isn't much point in the '\n' unless you are going to read the markup:
node = "<p>" + playerList[i].name + "<br><small>&nbsp</small></p>";
div.appendChild(node);
appendChild expects a DOM element, not markup. Since this is the only content of the div, you can use the markup to set its innerHTML property (you might want to change the name of node to say markup):
div.innerHTML = node;
element.appendChild(div);
}
}

Categories