How to append child of child in javascript? - javascript

I have a div with a class called post, and I am iterating through a list of posts from the backend that I want to display on the front end.
My requirement is that I first want to create an empty div and append all the created elements in that div, and then finally push that div in the <div class = 'post'. But for some reason, it's giving me an error saying appendChild is not a function.
It would be great if I could convert this empty div element to look like below just through javascript. Since I want to style each of my posts and so I am wrapping them in a div.
EDIT: Below is my javascript code that I tried
for (let i = 0; i < paginatedItems.length; i++) {
let post_wrapper = document.createElement('div');
let post_element = document.querySelector('.post');
let hr = document.createElement('hr');
// Title of the blog
let title_element = document.createElement('h2')
title_element.classList.add('mt-4');
title_element.innerHTML = paginatedItems[i].title;
post_element.appendChild(title_element);
// Image of the Blog
let image_element = document.createElement('img');
image_element.classList.add('img-fluid');
image_element.classList.add('rounded');
image_element.style.width = '672'
image_element.style.height = '372'
image_element.src = paginatedItems[i].featured_image;
post_element.appendChild(image_element);
// Author Element
let author_element = document.createElement('p');
author_element.classList.add('lead');
author_element.innerHTML = 'By ';
let author_link = document.createElement('a')
author_link.innerHTML = paginatedItems[i].author.name;
author_link.href = 'google.com'
author_element.appendChild(author_link);
author_link.appendChild(hr);
post_element.appendChild(author_element);
// // Date Element
let date_element = document.createElement('p');
date_element.classList.add('item');
date_element.innerHTML = `Posted ${timeSince(paginatedItems[i].date)} ago`;
post_element.appendChild(date_element);
date_element.appendChild(hr);
// Description Element
let description_element = document.createElement('p');
description_element.classList.add('item');
description_element.innerHTML = paginatedItems[i].content.substr(0, 300) + '....';
post_element.appendChild(description_element);
// Show more button
let input_button = document.createElement('a')
input_button.classList.add('btn-primary');
input_button.classList.add('btn');
input_button.textContent = "Show more..";
input_button.addEventListener('click',
function () {
RenderPost(paginatedItems[i].ID);
}
)
console.log(post_element);
post_wrapper.appendChild(post_element);
post_element.appendChild(input_button);
}

you have to use forEach method.
here is an example:
const postsArray = [{title: 'miaw', id: 123324}, {title: 'hello', id: 983745}];
// the dom div you want to append to.
const myDiv = document.getElementById('[yourDivId]');
postsArray.forEach(post=>{
// creating the post
var div = document.createElement('div');
var title = document.createElement('h1');
var id = document.createElement('h4');
title.textContent = post.title;
id.textContent = post.id;
// appending the elements to a div
div.append(title, id);
// then appending the post to your div
myDiv.appendChild(div);
});

Getting element by id fixed it for me
here is the final working code snippet
let post_element = document.querySelector('#posts');
for (let i = 0; i < paginatedItems.length; i++) {
let post_wrapper = document.createElement('div');
let hr = document.createElement('hr');
// Title of the blog
let title_element = document.createElement('h2')
title_element.classList.add('mt-4');
title_element.innerHTML = paginatedItems[i].title;
post_wrapper.appendChild(title_element);
// Image of the Blog
let image_element = document.createElement('img');
image_element.classList.add('img-fluid');
image_element.classList.add('rounded');
image_element.style.width = '672'
image_element.style.height = '372'
image_element.src = paginatedItems[i].featured_image;
post_wrapper.appendChild(image_element);
post_element.appendChild(post_wrapper);
}

Related

Why are the answer options for all questions appearing in this single question?

This is a quiz in which each question has 4 answer options. I'm looping through the question one by one and trying to make it appear with its corresponding answer options, but the question is appearing with the answer options of other questions as well. What could I be missing here?
var questionOne = function () {
// create container to hold questions and answer options & give it a class name
var questionsDiv = document.createElement("div");
questionsDiv.className = "questions-div";
// create question stem, give it a class name, add its content, & append to questionsDiv
var questionStem = document.createElement("h2");
questionStem.className = "question-stem";
questionStem.innerText = quizQuestions[currentQuestion].question;
questionsDiv.append(questionStem);
// create container to hold answer option buttons
var answerOptionsDiv = document.createElement("div");
// create footer container, give it a class name, & append to the questionsContainer
var footerDiv = document.createElement("div");
footerDiv.className = "footer-div";
questionsContainer.append(footerDiv);
// create footer text (correct/wrong), give it a class name, & append to footerDiv
var footerTextCorrect = document.createElement("h2");
footerTextCorrect.className = "footer-text-correct";
footerTextCorrect.innerText = "Correct!";
footerDiv.append(footerTextCorrect);
var footerTextWrong = document.createElement("h2");
footerTextWrong.className = "footer-text-wrong";
footerTextWrong.innerText = "Wrong!";
footerDiv.append(footerTextWrong);
// append questionsDiv to main questions container
questionsContainer.append(questionsDiv);
// append answerOptionsDiv to questions container
questionsDiv.append(answerOptionsDiv);
// loop through the questions
for (let i = 0; i < quizQuestions.length; i++) {
console.log(quizQuestions[currentQuestion].question);
for (let j = 1; j <= 4; j++) {
console.log(`${j}. ${quizQuestions[currentQuestion].options[`${j}`]}`);
// create buttons for answer options and add their content
var optionBtnOne = document.createElement("button");
optionBtnOne.innerText = `${j}. ${
quizQuestions[currentQuestion].options[`${j}`]
}`;
// append button to answerOptionsDiv
answerOptionsDiv.append(optionBtnOne);
optionBtnOne.addEventListener("click", selectAnswer);
optionBtnOne.setAttribute(
"id",
`${quizQuestions[currentQuestion].options[`${j}`]}`
);
}
currentQuestion++;
}
};
You shouldn't have the loop that iterates through the quizQuestions array. This function should just process quizQuestions[currentQuestion]. The currentQuestion index should be incremented when the user goes to the next question, not in this function.
var questionOne = function() {
// create container to hold questions and answer options & give it a class name
var questionsDiv = document.createElement("div");
questionsDiv.className = "questions-div";
// create question stem, give it a class name, add its content, & append to questionsDiv
var questionStem = document.createElement("h2");
questionStem.className = "question-stem";
questionStem.innerText = quizQuestions[currentQuestion].question;
questionsDiv.append(questionStem);
// create container to hold answer option buttons
var answerOptionsDiv = document.createElement("div");
// create footer container, give it a class name, & append to the questionsContainer
var footerDiv = document.createElement("div");
footerDiv.className = "footer-div";
questionsContainer.append(footerDiv);
// create footer text (correct/wrong), give it a class name, & append to footerDiv
var footerTextCorrect = document.createElement("h2");
footerTextCorrect.className = "footer-text-correct";
footerTextCorrect.innerText = "Correct!";
footerDiv.append(footerTextCorrect);
var footerTextWrong = document.createElement("h2");
footerTextWrong.className = "footer-text-wrong";
footerTextWrong.innerText = "Wrong!";
footerDiv.append(footerTextWrong);
// append questionsDiv to main questions container
questionsContainer.append(questionsDiv);
// append answerOptionsDiv to questions container
questionsDiv.append(answerOptionsDiv);
console.log(quizQuestions[currentQuestion].question);
for (let j = 1; j <= 4; j++) {
console.log(`${j}. ${quizQuestions[currentQuestion].options[`${j}`]}`);
// create buttons for answer options and add their content
var optionBtnOne = document.createElement("button");
optionBtnOne.innerText = `${j}. ${
quizQuestions[currentQuestion].options[`${j}`]
}`;
// append button to answerOptionsDiv
answerOptionsDiv.append(optionBtnOne);
optionBtnOne.addEventListener("click", selectAnswer);
optionBtnOne.setAttribute(
"id",
`${quizQuestions[currentQuestion].options[`${j}`]}`
);
}
};

add link to .textcontent in Javascript

When I received help on adding a link to symbolSpan, I am now getting a link but the symbols are showing at the bottom of the page and not in the table with the rest of the data... How do I fix that?
const renderBalances = balances => {
//
binanceBalances.innerHTML = "";
//
//console.log(balances);
balances.forEach(balance => {
let balanceLi = document.createElement("li");
balanceLi.className = "list-group-item list-group-item-justify-content-center";
let balanceDiv = document.createElement("div");
balanceDiv.className = "d-flex w-100 justify-content-between";
let symbolSpan = document.createElement("span");
symbolSpan.textContent = balance.symbol;
// balanceDiv.appendChild(symbolSpan);
function createLink(linkExtension) {
const balanceDiv = document.createElement("div");
const symbolSpan = document.createElement("span");
const link = document.createElement("a");
link.setAttribute('href', `www.binance.com/en/trade/${linkExtension}`);
link.textContent = balance.symbol;
symbolSpan.appendChild(link);
balanceDiv.appendChild(symbolSpan);
document.body.appendChild(balanceDiv);
}
createLink('myparam')
this is the rest of the code for this table
let price = document.createElement("span");
price.textContent = balance.startPrice;
balanceDiv.appendChild(price);
let available = document.createElement("span");
available.textContent = balance.holdings;
balanceDiv.appendChild(available);
let onOrder = document.createElement("span");
onOrder.textContent = balance.used;
balanceDiv.appendChild(onOrder);
balanceLi.appendChild(balanceDiv);
binanceBalances.appendChild(balanceLi);
});
};
Create a span and a link html element. For the link element append the text and the href attribute.
Attach the link element to span and span to div. At last append to DOM.
Pass the additional parameter that needs to be appended to the link.
function createLink(linkExtension) {
const balanceDiv = document.createElement("div");
const symbolSpan = document.createElement("span");
const link = document.createElement("a");
link.setAttribute('href', `www.binance.com/en/trade/${linkExtension}`);
link.textContent = 'binance link';
symbolSpan.appendChild(link);
balanceDiv.appendChild(symbolSpan);
document.body.appendChild(balanceDiv);
}
createLink('myparam')

Access parent object property of image element

I have a list of cats. Each cat object has a property cat.clicks that record the number of times the cat image has been clicked. The cat image's onclick calls the method cat.clickCat.
But of course 'this' in the clickCat method refers to the image element and not the cat object which contains the property 'clicks'.
How do I display and update the number of clicks on the image?
function Cat(src, name) {
this.src = src;
this.name = name;
this.clicks = 0; //property recording no. of clicks
}
Cat.prototype.createCatItem = function() {
let catDisplay = document.createElement("div");
catDisplay.id = "catDisplay"
let catName = document.createElement("h2");
let catImg = document.createElement("img");
let catCounter = document.createElement("div");
catCounter.id = "clicker";
catName.innerHTML = this.name;
catImg.src = this.src;
catImg.onclick = this.clickCat; //call the clickCat method
catDisplay.appendChild(catName);
catDisplay.appendChild(catImg);
catDisplay.appendChild(catCounter);
return catDisplay;
}
Cat.prototype.clickCat = function() {
this.clicks += 1; //how to access the object property clicks from this method?
let clickerDiv = document.getElementById("clicker")
clickerDiv.innerHTML = ''
clickerDiv.innerHTML = 'clicks = ' + this.clicks;
}
function App() {
this.cats = [];
}
App.prototype.add = function(cat) {
this.cats.push(cat)
}
App.prototype.listCats = function() {
let container = document.getElementById("container");
let ul = document.createElement("ul");
for (let i=0; i<this.cats.length; i++){
let li = document.createElement("li");
li.innerHTML = this.cats[i].name;
li.onclick = this.displayCat;
ul.appendChild(li);
}
container.appendChild(ul);
}
App.prototype.displayCat = function() {
let container = document.getElementById("container");
let catDisplay = document.getElementById("catDisplay")
let cats = app.cats;
let chosenCat = cats.filter(cat => cat.name === this.innerHTML);
let chosenCatItem = chosenCat[0].createCatItem();
container.removeChild(catDisplay);
container.appendChild(chosenCatItem);
console.log(chosenCat);
}
App.prototype.showFirstCat = function() {
let container = document.getElementById("container");
let catDisplay = document.getElementById("catDisplay")
let firstCat = app.cats[0].createCatItem();
container.appendChild(firstCat);
}
let app = new App;
let tea = new Cat("http://placehold.it/350x150", "tea");
let snowball = new Cat("http://placehold.it/350x200", "snowball");
let triksy = new Cat("http://placehold.it/350x300", "triksy");
let vera = new Cat("http://placehold.it/350x350", "vera");
let jon = new Cat("http://placehold.it/350x400", "jon");
app.add(tea)
app.add(snowball)
app.add(triksy)
app.add(vera)
app.add(jon)
app.listCats();
app.showFirstCat();
<div id="container">
<h1>My Cat Clicker</h1>
</div>
First of all .. beware of using this ... this always refer the object currently responsible to execute the scripts in browser ... so in your case the image is responsible for executing the click event and it has no property called clicks .. and that's why clicks is NaN
A good practice is preserve this into a variable to avoid the system replacement when executing (that=this)
Cat.prototype.createCatItem = function() {
let that=this; //preserving this value
let catDisplay = document.createElement("div");
catDisplay.id = "catDisplay"
let catName = document.createElement("h2");
let catImg = document.createElement("img");
let catCounter = document.createElement("div");
catCounter.id = "clicker";
catName.innerHTML = this.name;
catImg.src = this.src;
catImg.onclick = function() {
//alert(this);
that.clicks += 1; //how to access the object property clicks from this method?
let clickerDiv = document.getElementById("clicker")
clickerDiv.innerHTML = ''
clickerDiv.innerHTML = 'clicks = ' + that.clicks;
}
catDisplay.appendChild(catName);
catDisplay.appendChild(catImg);
catDisplay.appendChild(catCounter);
return catDisplay;
}
//Cat.prototype.clickCat = function() {
// this.clicks += 1; //how to access the object property clicks from this method?
// let clickerDiv = document.getElementById("clicker")
// clickerDiv.innerHTML = ''
// clickerDiv.innerHTML = 'clicks = ' + this.clicks;
//}

Inserting text after a certain image using javascript

In one function I have a loop that creates 10 images using the createElement();. In the other function I have another loop that contains info that I need to add text after each picture but my code adds it at the end of all 10 pictures I need them to be after every corresponding picture.
This is the function that displays the text:
function displayAlbum(json){
for (var x = 0; x<json.length;x++){
var span1 = document.createElement("span");
span1.innerText = json[x].album;
console.log(json[x].album);
var display = document.getElementById("results");
display.appendChild(span1);
}
}
I cant individually set the id of each image because i created them in js. Thanks for the help in advance and no jquery please
for (var x = 0; x<json.length;x++){
var image = document.createElement("img");
image.id = "picture";
image.width = 100;
image.height = 100;
image.src = json[x].cover;
var display = document.getElementById("results");
display.appendChild(image);
var a = document.getElementById("artist");
var y = document.getElementById("year");
var artist = document.getElementById("artist").selectedIndex;//index of value of the switch statement
var year = document.getElementById("year").selectedIndex;//index of value of the switch statement
var realYear = y[year].text;//Value of the selected text
var realArtist = a[artist].text;//Value of the selected text
var display = document.getElementById("Results");
}
This is my second loop. I want displayalbum to appear after every picture. I cannot combine them because of other complications in the code
Try to do something like that: plunker
function displayAlbum(){
for (var x = 0; x < 10 ; x++){ // change to json.length
var span1 = document.createElement("span");
span1.innerText = 'json[x].album';
span1.id = 'span'+x;
var display = document.getElementById("results");
display.appendChild(span1);
}
}
The loop where you are creating images, give a unique id to image like image.id = "picture" + x;
Then change displayAlbum() function to use corresponding image to place the span tag.
function displayAlbum(json){
for (var x = 0; x<json.length;x++){
var span1 = document.createElement("span");
span1.innerText = json[x].album;
console.log(json[x].album);
var display = document.getElementById("results");
var img = document.getElementById("picture" + x); // use unique id of img to access it
if(img.nextSibling) { // if img is not the last node in 'results'
display.insertBefore(span1, img.nextSibling);
} else { // if img is the last node in 'results'
display.appendChild(span1);
}
}
}
You can achieve your goal with single loop and using Figure and FigCaption element , specifically created for this kind of display image with its description
var json = [{cover:"https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/Internet2.jpg/440px-Internet2.jpg", album:"test1"},{cover:"https://upload.wikimedia.org/wikipedia/commons/thumb/d/da/Internet2.jpg/440px-Internet2.jpg", album:"test2"}];
for (var x = 0; x<json.length;x++){
var fig = document.createElement("figure");
var figCap = document.createElement("figcaption");
figCap.innerText = json[x].album;
var image = document.createElement("img");
image.id = "picture";
image.width = 100;
image.height = 100;
image.src = json[x].cover;
var display = document.getElementById("results");
fig.appendChild(image);
fig.appendChild(figCap);
display.appendChild(fig);
}
<div id="results">
</div>

Bootstrap panels not displaying body text

For some reason my bootstrap panels won't show the body text. I have set up all my elements via DOM Manipulation.
My panel header text displays properly, however my body text doesn't show up.
I also noticed that the bootstrap panel body content does not have any elements, just lines of text.
I have tried to add text elements to it but so far nothing has been working. Here is my code:
JS
var searchButton = document.getElementById('search-button');
searchButton.addEventListener('click', function() {
var term = document.getElementById('term').value;
var matched = [];
for (var i = 0; i < hotelRooms.length; i++) {
if (hotelRooms[i].hotel.indexOf(term) !== -1) {
matched.push(hotelRooms[i]);
}
}
for (var i = 0; i < matched.length; i++) {
var roomResults = document.createElement('div');
roomResults.setAttribute('id', 'results');
roomResults.setAttribute('class', 'result-style');
var resultsArea = document.getElementById('results-area');
console.log(matched[i]);
var panelDefault = document.createElement('div');
panelDefault.setAttribute('class', 'panel-default');
var panelHeading = document.createElement('div');
panelHeading.setAttribute('class', 'panel-heading');
var panelBody = document.createElement('div');
panelBody.setAttribute('class', 'panel-body');
var name = document.createElement('h3'); // Hotel Name
name.setAttribute('class', 'hotel-name');
name.textContent = matched[i].hotel;
var price = document.createElement('div'); // Room Price
price.setAttribute('class', 'room-price');
price.textContent = matched[i].price;
roomResults.appendChild(panelDefault);
panelDefault.appendChild(panelHeading);
panelHeading.appendChild(name);
panelBody.appendChild(price);
resultsArea.appendChild(roomResults);
}
});
You are never appending panelBody to panelDefault.
....
roomResults.appendChild(panelDefault);
panelDefault.appendChild(panelHeading);
panelHeading.appendChild(name);
panelBody.appendChild(price);
panelDefault.appendChild(panelBody);
....
You have just created a div, you need to append it to the body tag document.body.appendChild(size)
var size = document.createElement('div');
size.setAttribute('class', 'room-size');
size.textContent ="hello"
document.body.appendChild(size)

Categories

Resources