Create only content of accordion in for loop - javascript

I'm trying to create the content part of an accordion in a for loop, with the title printed beforehand. This is what I tried:
$("#right").append(
"Team Leaders"
+ "<h4>Goals</h4>"
+ "<div><p>"
);
for (var i = 0; i < 5; i++) {
$("#right").append(
topGoals[i].name
+ ": "
+ topGoals[i].goals
+ "<br>"
);
}
$("#right").append("</p></div>");
$("#right").accordion();
However, that didn't work. The "Goals" part did appear as the accordion header, but the content inside of it was empty, and the content generated from the for loop appeared underneath the accordion.
I've created accordions in for loops before and had no trouble, but I've never tried to make the title outside of the loop. Am i doing something wrong here?
Edit:
The topGoals array in screen.js:
var topGoals = getTopFiveGoals(myTeam);
The function is in functions.js:
function getTopFiveGoals(team) {
var tempTeam = team.players.slice();
tempTeam.sort(function(a, b) {
return b.goals-a.goals;
});
tempTeam.splice(5, 15);
return tempTeam;
}

You're modifying the DOM tree many times, instead create a dom element in memory and append all child elements. At the end append it to the live DOM tree. In your code, the tags are not closed properly so it won't be generated properly.
jQuery will automatically close the tags such as <div><p> which are not closed properly.
$("#right").append(
"Team Leaders"
+ "<h4>Goals</h4>"
);
var $div = $("<div></div>");
for (var i = 0; i < 5; i++) {
$div.append("<p>"+
topGoals[i].name
+ ": "
+ topGoals[i].goals
+ "</p><br>"
);
}
$("#right").append($div);
$("#right").accordion();

Related

Adding clickable buttons or links for side bar

I'm having trouble adding links or buttons to my side bar dynamically. I'm trying to use JavaScript to add the appropriate amount of elements or buttons(I don't know what is better). In essence this is used to make a JS quiz website where each of the buttons in the sidebar will jump you to the question(to make it more clear: Question 4 takes you to 4th question and so on)
This is my side bar:
<div id="mySidenav" class="sidenav">
×
Question
</div>
My JS trying to make the elements but failing to do so:
//add question numbers to the side bar
function questionNav(){
for(var i = 0; i < numberOfQuestions; i++){
document.getElementById("mySidenav").innerHTML = "Question " + (i+1) + "<br/>";
//var newSideBarElm = "Question " + (i+1) + "<br/>";
//document.getElementById("mySidenav").insertAdjacentHTML = ('beforeend',newSideBarElm);
}
}
I've been trying numerous different methods but I can't get it to work and would greatly appreciate if someone was able to help me.
Here is the full code of the site in case you would like to see how I'm doing everything else: https://pastebin.com/hrSADLQy
So assuming that I understand your question correctly, what you are currently doing is targeting the div with the id 'mySideNav' and overwriting its content by assigning a new value to its innerHTML attribute. What you should be doing instead is
Create a new anchor element
Use the innerHTML attribute to insert your desired value (i.e "Question N")
Append your newly created element to your 'mySideNav' div element.
I wrote a small demo for you to see my answer in action, but will post my code below this answer for you to see as well.
// Grab and Store Element to append questions to
var mySideNav = document.getElementById('mySidenav');
// Designate number of questions
var numberOfQuestions = 10;
// Loop as many times as there are questions
for (let i = 0; i < numberOfQuestions; i++) {
// Step 1: Create a new anchor element
let newQuestion = document.createElement('a');
// Assign href to whatever you want
newQuestion.href = '#';
// Step 2: Use the innerHTML attribute to insert your desired value
newQuestion.innerHTML = 'Question ' + i + '<br>';
// Step 3: Append your newly created element to your 'mySideNav' div element.
mySideNav.appendChild(newQuestion);
}
I hope this helps!
According to your question and the code you provided i think you need to define a div with an onclick() property to make the corresponding question visible. That could be something like this (assuming you can access the number of questions inside this function):
function questionNav(){
for(var i = 0; i < numberOfQuestions; i++){
document.getElementById("mySidenav").innerHTML += "<div style='cursor:pointer' onclick=navigateToQuestion(" + (i+1) + ")/> Question " + (i+1) + "</div>";
}
}
And then define a the onclick function "navigateToQuestion" to show the question that is passed as parameter, maybe could be somethink like this:
function navigateToQuestion(question){
document.getElementById("question_" + currentQuestionInView).style.display = "none";
currentQuestionInView = question;
document.getElementById("question_" + question).style.display = "block";
}
Haven't tested the code but i think it should work.
Hope you get your problem solved :)

Using jQuery to replace tags within an array?

I am new to Javascript and JQuery and I am trying to replace all my tags with upon first click, and then replace with on the second click, and so forth.
Basically just cycling through them so on each click I have a 3d rendered box or sphere. I tried to run it with this code however it does not work.
When I checked the console, only the lines were getting logged, so it doesn't seem to be replacing them correctly. I need to keep the tags within each preserved as I work.
var counter = 0;
var myArr = ["a-sphere", "a-box"];
$("#targeted").click(function() {
if(counter == myArr.length) counter = 0;
$(myArr[counter]).replaceWith(function() {
var myString = "<" + myArr[counter] + ">" + $(this).html() + "</" + myArr[counter] + ">";
console.log(myString + counter);
return myString;
});
counter++;
});

change events stop working when a new change event is added to a different element in JS

I am programmatically generating some HTML, and trying to add a listener for a change event the elements.
This works fine for the first object, but as soon as I add the second object the first one stops firing the event.
In the code example below you'll see the updateLabel function only fires for the last object created. I need it to fire for all of the objects.
I have tried with .onchange, and with an event listener, but get the same results.
Any help much appreciated.
<html>
<body>
<div id="main">
<!--this is where all the generated HTML goes -->
</div>
</body>
<script>
mainDomElement = document.querySelector("#main");
for (var count = 0; count < 4; count++)
{
var labelId = 'Label' + count;
newHTML = '<input class="accordionLabel" type="text" id="' + labelId + '" value="' + labelId + '"/>'
currentHTML = mainDomElement.innerHTML
mainDomElement.innerHTML = newHTML + currentHTML
labelDomObj = document.querySelector('#' + labelId);
//labelDomObj.addEventListener("change", updateLabel);
labelDomObj.onchange = function(event){updateLabel(event)}
}
function updateLabel(event)
{
alert(event.target.value);
}
</script>
</html>
It may be best to take a different approach when creating and adding DOM elements. Try this.
for (var count = 0; count < 4; count++)
{
var labelId = 'Label' + count,
newHTML = document.createElement('input');
newHTML.type = 'text';
newHTML.value = labelId;
newHTML.id = labelId;
newHTML.addEventListener('onchange', updateLabel, false);
mainDomElement.appendChild(newHTML);
}
your code explanation
// this takes the main DOM element and stores a copy of it in the variable.
currentHTML = mainDomElement.innerHTML
/*
This is taking the innerHTML property of the main DOM element. It is then
trying to concatenate the newly created DOM to that stored in the mainDomElement
variable. I don’t think this is what you want.
*/
mainDomElement.innerHTML = newHTML + currentHTML
// this is trying to select an element from the DOM that does not exist yet.
labelDomObj = document.querySelector('#' + labelId);
// This is trying to add an event listener to an element that does not exist.
labelDomObj.onchange = function(event){updateLabel(event)}
You are also missing sim icons from your variable declarations.
This looks like an issue with closures, where initializing var count = 0 within the for loop ultimately results in only the last value getting bound to the event handler.
I believe moving the initialization outside of the loop will fix your issue. Also, ES6 introduced the let keyword that scopes the variable in the way you are expecting:
for (let count = 0; count < 4; count++) { }
See this excellent introduction to javascript closures for more information.

Edit HTML list entry with javascript

Note: i searched a half hour. I need a special solution for this:
I have the folowing code already (node some Variables have german Names i hope that's ok)
function generateList () {
document.getElementById("liste").innerHTML =""
var listEasy = vorNameListe[i] + " " + nachNameListe[i] + " " + alterListe[i]
for (var i=0; i < vorNameListe.length; i++) {
document.getElementById("liste").innerHTML += "<li>" + listEasy + "</li>"
};
Now i need a javascript (pls no jquery) solution so the user can change every List entry by himself. How do i do that?
further explanation: The code i have is one to bring a "li" in a existing "ul" with every loop.
But then i want to give every "li entry" the ability to be changed by the user.
Are you trying to change text of every li of #liste ul?
function generateList() {
var liItems = document.querySelectorAll('#liste > li');
for (i = 0; i === liItems, i++) {
liItems[i].innerHTML = 'content';
}
}
i refined my edit function with jquery fdurther and further i will edit this entry for every step:
I have a Special Idea about an Edit function
https://stackoverflow.com/questions/28695711/edit-and-delete-selected-list-entrys

Removing elements from a document in Javascript [duplicate]

This question already has answers here:
JavaScript DOM remove element
(4 answers)
Closed 8 years ago.
Working on building this to-do list app to learn JS better.
I am able to insert text into box and have it add a new div element to the page with the relevant text residing within the div. The code that adds the div to the page automatically applies the class .newItem then adds an incrementing id i0, i1, i2, etc each time it's clicked. Everything works without an issue. Now, I have been fiddling around with the code to be able to click a single div element and have it remove itself from the page, but can't seem to get it to work.
var iDN = 0;
//Function that adds a new div with a custom incrementing id number
document.getElementById('add_button').onclick = function () {
var taskName = document.getElementById('add_task').value; // Store the value in the textbox into a variable
document.querySelector('.shit_to_do').innerHTML += '<div class = "newItem" id = "i' + iDN + '"' + 'onclick = removeEl()' + '>' + taskName + '</div>';
iDN += 1;
};
document.getElementById('testing').onclick = function () {
var parentNode = document.querySelector('.shit_to_do');
parentNode.removeChild(parentNode.children[0]);
}
function removeEl() {
for (i = 0; i < iDN; i++) {
if (document.getElementById('i' + i).onclick) {
document.getElementById('i' + i).display.style = 'none';
}
alert(i);
}
}
The for loop was really some random option I was trying to figure out how things were working onclick for each div, but didn't get to far with that one.
tl;dr:
I want to add click events to the new divs added onto the page in a single, universal function.
The value of document.getElementById('i' + i).onclick will be null if you've not set a handler to this attribute/property, otherwise it will be a function. null is always falsy, a function is always truthy.
To remove your element, you'll either have to look at this or e.target where e is the click event, and then call the DOM method node.removeChild(child).
The "quick and dirty" solution is to pass this into removeEl and remove it that way,
// ...
document.querySelector('.shit_to_do').innerHTML += '<div class="newItem" id="i' + iDN + '" onclick="removeEl(this)">' + taskName + '</div>';
// ...
function removeEl(elm) {
elm.parentNode.removeChild(elm);
}
I also removed the strange spacing between attribute names and values in your HTML
A perhaps "cleaner" solution is to create your nodes and attach listeners all by using DOM methods
function createDiv(index, taskname) {
var d = document.createElement('div');
d.setAttribute('id', 'i' + index);
d.textContent = taskname;
return d;
}
function removeElm() {
this.parentNode.removeChild(this);
}
var iDN = 0;
document.getElementById('add_button').addEventListener('click', function () {
var taskName = document.getElementById('add_task').value,
list = querySelector('.shit_to_do'),
div = createDiv(iDN, taskName);
div.addEventListener('click', removeElm);
list.appendChild(div);
iDN += 1;
});
This way means the browser does not re-parse any HTML as it not use element.innerHTML, which is a dangerous property may destroy references etc (along with usually being a bit slower)
Helpful links
node.addEventListener
document.createElement
node.appendChild

Categories

Resources