Combining textContent into one header when rendering Javascript - javascript

Very new to javascript here, just two days in, but I have decided to start a pretty ambitious project using Javascript and Firebase.
Below I am trying to render the Javascript from Firestore to HTML, but as you can probably see, it's creating 4 H5's. Ideally, I have all the text inside of one H5, but formatted nicely.
Here is my javascript (again I just started learning this two days ago so I am very new)
const resultList = document.querySelector('#horseList')
function renderResult(doc){
let li = document.createElement('li');
var resultDiv = document.createElement('div');
resultDiv.className = ('result');
var resultImage = document.createElement('div');
resultImage.className = ('data-image');
var resultFooter = document.createElement('div');
resultFooter.className = ('result-footer');
var resultText = document.createElement('div');
resultText.className = ('results-text');
var resultButton = document.createElement('button');
resultButton.className = ('button tiny w-button');
resultButton.innerHTML = "View";
let name = document.createElement ('h5');
name.className = ('data-text');
let age = document.createElement ('h5');
age.className = ('data-text');
let type = document.createElement ('h5');
type.className = ('data-text');
let price = document.createElement ('h5');
price.className = ('data-text');
li.setAttribute('data-id', doc.id);
name.textContent = doc.data().name;
age.textContent = doc.data().age;
type.textContent = doc.data().type;
price.textContent = doc.data().price;
resultList.appendChild(li);
li.appendChild(resultDiv);
resultDiv.appendChild(resultImage);
resultDiv.appendChild(resultFooter);
resultFooter.appendChild(resultText);
resultFooter.appendChild(resultButton);
resultText.appendChild(name);
resultText.appendChild(type);
resultText.appendChild(age);
resultText.appendChild(price);
}
//connect to database & get data
const db = firebase.firestore();
db.collection("Horses").get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
// doc.data() is never undefined for query doc snapshots
renderResult(doc);
});
})
.catch(function(error) {
console.log("Error getting documents: ", error);
});
And here is what I am hoping to achieve in HTML
<ul id="horseList" role="list" class="result-list">
<li>
<div class="result">
<div class="data-image"></div>
<div class="result-footer">
<div class="results-text">
<h5 class="data-text">Taffy, 8 | Arabian</h5>
<h5 class="data-text">$12,000</h5>
</div>View</div>
Updated code:
let lineone = document.createElement ('h5');
lineone.className = ('data-text');
let linetwo = document.createElement ('h5');
linetwo.className = ('data-text');
li.setAttribute('data-id', doc.id);
lineone.textContent = ${doc.data().name}, ${doc.data().age}, ${doc.data().type};
linetwo.textContent = ${doc.data().price};
Any help would be great! Thanks!

You can combine all the data calls into a single string variable using template literals, and then set that variable to the text content of your h5 element:
const string = `${doc.data().name}, ${doc.data().age} | ${doc.data().type}`;
let h5 = document.createElement('h5');
h5.textContent = string;

how are you? you can try to use the template literals, creating just one h5 for the 3 attributes name, age, type:
phrase.textContent = ${doc.data().name}, ${doc.data().age} ${doc.data().type}

Related

forEach loop keeps appending to first child element only

I'm in a bit of a pickle. I'm running a forEach loop for an API that will create a new div for each result with some html appended inside it. While the data is being retrieved, it appends only to the first div created. I'm trying to ensure each set of text ends up in each individual div. Can anyone enlighten me on what I'm doing wrong? Thanks
app.displayResults = (arrayOfObjects) => {
arrayOfObjects.forEach((Object) =>{
const number = Object.house_number;
const address = Object.street_name;
const zipCode = Object.zip_code;
const borough = Object.borough;
const date = Object.inspection_date;
const initial = Object.inspection_type;
const iResult = Object.result;
const resultContainer = document.createElement("div");
resultContainer.classList.add('resultContainer');
document.querySelector('.inspectionResults').append(resultContainer);
const innerHTML = `
<p class = "recordDetails"> ADDRESS: ${number}${address}</p>
<p class = "recordDetails"> DATE: ${date}</p>
<p class = "recordDetails"> BOROUGH: ${borough}</p>`
const record = document.createElement("div");
record.classList.add('record');
record.innerHTML = `${innerHTML}`
document.querySelector(".resultContainer").append(record)
})
}
In the last line of your forEach callback, you're querying the first .resultContainer element instead of the one you've created before. Instead of immediately appending that div to the DOM, append your record to resultContainer, then append only resultContainer to the DOM, like this (I've changed Object to obj because Object is already defined):
app.displayResults = (arrayOfObjects) => {
arrayOfObjects.forEach((obj) =>{
const number = obj.house_number;
const address = obj.street_name;
const zipCode = obj.zip_code;
const borough = obj.borough;
const date = obj.inspection_date;
const initial = obj.inspection_type;
const iResult = obj.result;
const resultContainer = document.createElement("div");
resultContainer.classList.add('resultContainer');
const innerHTML = `
<p class = "recordDetails"> ADDRESS: ${number}${address}</p>
<p class = "recordDetails"> DATE: ${date}</p>
<p class = "recordDetails"> BOROUGH: ${borough}</p>`
const record = document.createElement("div");
record.classList.add('record');
record.innerHTML = `${innerHTML}`
resultContainer.appendChild(record); // instead of directly appending record to document append it to the container, then append the container to the document
document.querySelector('.inspectionResults').append(resultContainer);
})
}
app.displayResults = (arrayOfObjects) => {
arrayOfObjects.forEach((obj) =>{
/*
const number = Object.house_number;
const address = Object.street_name;
const zipCode = Object.zip_code;
const borough = Object.borough;
const date = Object.inspection_date;
const initial = Object.inspection_type;
const iResult = Object.result;
*/
// Destructuring Assignment maybe better here
const { house_number : number,
street_name : address,
zip_code : zipCode,
borough,
inspection_date : date,
inspection_type : initial,
result : iResult } = obj
const resultContainer = document.createElement("div");
resultContainer.classList.add('resultContainer');
// below is the problem, you appended several divs with the class name 'resultContainer', every time you query, there were a array of it, and you always got the first.
// document.querySelector('.inspectionResults').append(resultContainer);
const innerHTML = `
<p class = "recordDetails"> ADDRESS: ${number}${address}</p>
<p class = "recordDetails"> DATE: ${date}</p>
<p class = "recordDetails"> BOROUGH: ${borough}</p>`
const record = document.createElement("div");
record.classList.add('record');
record.innerHTML = innerHTML
// here just append to the exact div you created above
resultContainer.append(record)
// then append the container which contains the content you expected to the documment
document.querySelector('.inspectionResults').append(resultContainer);
})
}
How about adding an identifier?
terms.setAttribute(‘id’,‘para-1’);

My generated link in the unordered list is not navigable

let x=[];
let array = []
const json1 = '{"https://www.w3schools.com/html/":"check w3 schools"}';
const obj1 = JSON.parse(json1);
array=Object.getOwnPropertyNames(obj1);
ul = document.createElement('ul');
ser.appendChild(ul);
x= document.createElement('li');
x.innerText=""+"";//hyper link not clickable
ul.appendChild(x);
<div id="ser"></div>
the javascript code renders the unordered list but the link in the list() is not navigable.Please advice on solving this issue.
There are multiple fixes so take a look at this
let array = []
const json1 = '{"https://www.w3schools.com/html/":"check w3 schools"}';
const obj1 = JSON.parse(json1);
array = Object.getOwnPropertyNames(obj1);
const ul = document.querySelector('#ser').appendChild(document.createElement('ul'));
const x = document.createElement('li');
const a = document.createElement('a');
a.setAttribute("href", array[0]);
a.innerHTML = array[0];
x.appendChild(a);
ul.appendChild(x);
You must use .innerHTML instead of .innerText.
Also, make sure to put text inside the and tags, or else the link won't be visible.

cant append text node to element using javascript

im trying to get some data from another html page and create an element in javascript and then added it to the dom
so far im trying to append a text node inside an h1 and p element from a variable
the console shows this error
script.js:32 Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
at script.js:32:7
this is the code i will add some comments to clarify :
window.addEventListener("load",() =>{
const data = (new URL (document.location)).searchParams;
// all of these are strings
const title = data.get('title');
const desc = data.get('desc');
const date = data.get("date");
const PDF = data.get("pdf");
// elmenet creation
const columns = document.createElement("div");
const worksheetCon=document.createElement("div");
const card = document.createElement("div");
const imageDiv = document.createElement("div");
const image = document.createElement("img");
const h1 = document.createElement("h1");
// creating h1 elment text node to append it later to h1 element
const h1Text = document.createTextNode(title);
const contain = document.createElement("div");
const p =document.createElement("p");
// creating p elment text node to append it later to append it later to p element
const Ptext = document.createTextNode(desc);
// trying to figure out type of text node it says its object
alert(typeof Ptext);
worksheetCon.className = "container-worksheets";
columns.className = "columns";
card.className = "carde";
imageDiv.className = "img";
contain.className = "contain";
worksheetCon.appendChild(columns);
columns.appendChild(card);
card.appendChild(imageDiv);
imageDiv.appendChild(image);
card.appendChild(h1);
h1.appendChild(h1Text)
card.appendChild(contain);
contain.appendChild(p);
p.appendChild(Ptext );
const worksheets = document.querySelector("worksheets");
worksheets.appendChild(card);
})
As I said, you never use Ptext, but you try to use desc as a Node
const desc = data.get('desc');
p.appendChild(desc);

create variable from string given in array

Is there any way to create variable from String inside the array with the name of the String?
something like this:
const array = ["type","name","hours","photos","place","price"];
array.forEach(item =>{
let item = document.crea.....
//but it should work like let array[index] = docu.......
})
The reason for this is that I wanted to make this code look a bit nicer and its obvious, that there are quite a lot things repeating.
const type = document.createElement("td");
const name = document.createElement("td");
const hours = document.createElement("td");
const photos = document.createElement("td");
const place = document.createElement("td");
const price = document.createElement("td");
type.innerHTML = element.type;
name.innerHTML = element.name;
hours.innerHTML = element.hours;
photos.innerHTML = element.photos;
place.innerHTML = element.place;
price.innerHTML = element.price;
tr.appendChild(type);
tr.appendChild(name);
tr.appendChild(hours);
tr.appendChild(photos);
tr.appendChild(place);
tr.appendChild(price);
Try use var or let instead const,works for me always.
And remember foreach is a kind of loop means
var mytd = document.createElement("td");mytd.innerHTML = element.{item};tr.appendChild(mytd);
I know this doesn't directly answer your question about variable names, but this should be the code you need to get your result.
array.forEach(item => {
const elem = tr.appendChild(document.createElement("td"));
elem.innerHTML = item;
})
You don't really need to use your array to generate the variable name as the forEach handles each item in the array separately.

Vanilla JavaScript - Appending Elements and Txt to an Element without using .innerHTML

element.append() not working in MS Edge
I was wondering how is the best way to create a new element and then append a string into it made up of other elements ang text variables? The .append method doesn’t seem to work in MS Edge
The error I’m getting is: SCRIPT438: SCRIPT438: Object doesn't support property or method 'append'
Isn’t this the correct way to do this without creating a string and then append to the parent.inner HTML??
parent = document.createElement("h4");
txtNode = document.createTextNode("");
txtNode.append(“WHATEVER”);
parent.appendChild(txtNode):
Thanks in advance
// Const
const numCopyrightTxtYear = 2018;
// Copyright Var
var elmCopyright = document.createElement("h4");
var elmCopyrightTxt = document.createTextNode("");
// Elements to append to elmCopyrightTxt
var elmTime = document.createElement("time");
var elmTimeTxt = document.createTextNode(numCopyrightTxtYear);
var elmCopyrightHolder = document.createElement("em");
var elmCopyrightHolderTxt = document.createTextNode("")
// Copyright
elmTime.dateTime = numCopyrightTxtYear;
elmTime.setAttribute("itemprop", "copyrightYear");
elmCopyrightHolder.setAttribute("itemprop", "creator copyrightHolder");
elmCopyrightHolder.appendChild(elmCopyrightHolderTxt);
elmCopyright.append("© ");
elmTime.appendChild(elmTimeTxt);
elmCopyright.append(elmTime);
elmCopyright.append(elmCopyrightHolder);
// This is the compleat code if I left somthing out??
function createHeaderFragment() {
// Main Fragment
var elmHeaderFragment = document.createDocumentFragment();
// Other Containers
var elmHeader = document.createElement("header");
// Values to Set
const strTitle = "Title";
const strCaption = "Caption";
const strSubjectOf = "SubjectOf";
const strLocation = "Location";
const strHashtags = "Hashtags";
const strKeywords = "Keywords";
const numCopyrightTxtYear = 2018;
// New Elements
// Title
var elmTitle = document.createElement("h2");
var elmTitleTxt = document.createTextNode(strTitle);
// Caption
var elmCaption = document.createElement("h3");
var elmCaptionTxt = document.createTextNode(strCaption);
// SubjectOf
var elmSubjectOf = document.createElement("h3");
var elmSubjectOfTxt = document.createTextNode(strSubjectOf);
// Location
var elmLocation = document.createElement("h3");
var elmLocationTxt = document.createTextNode(strLocation);
// Hashtags
var elmHashtags = document.createElement("h3");
var elmHashtagsTxt = document.createTextNode(strHashtags);
// Keywords
var elmKeywords = document.createElement("h3");
var elmKeywordsTxt = document.createTextNode(strKeywords);
// Copyright
var elmCopyright = document.createElement("h4");
var elmCopyrightTxt = document.createTextNode("");
var elmTime = document.createElement("time");
var elmTimeTxt = document.createTextNode(numCopyrightTxtYear);
var elmCopyrightHolder = document.createElement("em");
var elmCopyrightHolderTxt = document.createTextNode(" Evan Santé Photography")
// <img src= "/images/nav/grid1.jpg" alt= "Thumbnail Image" itemprop= "hasPart image thumbnail" />
//var objHeaderImage = document.createElement("img");
// Set Element Nodes
elmTitle.setAttribute("itemprop", "headline");
elmTitle.appendChild(elmTitleTxt);
elmCaption.setAttribute("itemprop", "caption");
elmCaption.appendChild(elmCaptionTxt);
elmSubjectOf.setAttribute("itemprop", "subjectOf");
elmSubjectOf.appendChild(elmSubjectOfTxt);
elmLocation.setAttribute("itemprop", "contentLocation");
elmLocation.appendChild(elmLocationTxt);
elmHashtags.setAttribute("itemprop", "keywords");
elmHashtags.appendChild(elmHashtagsTxt);
elmKeywords.setAttribute("itemprop", "keywords");
elmKeywords.appendChild(elmKeywordsTxt);
// Copyright
elmTime.dateTime = numCopyrightTxtYear;
elmTime.setAttribute("itemprop", "copyrightYear");
elmCopyrightHolder.setAttribute("itemprop", "creator copyrightHolder");
elmCopyrightHolder.appendChild(elmCopyrightHolderTxt);
elmCopyright.append("© ");
elmTime.appendChild(elmTimeTxt);
elmCopyright.append(elmTime);
elmCopyright.append(elmCopyrightHolder);
// Append To Header
elmHeader.appendChild(elmTitle);
elmHeader.appendChild(elmCaption);
elmHeader.appendChild(elmSubjectOf);
elmHeader.appendChild(elmLocation);
elmHeader.appendChild(elmHashtags);
elmHeader.appendChild(elmKeywords);
elmHeader.appendChild(elmCopyright);
return elmHeaderFragment.appendChild(elmHeader);
}
append is fairly new and not supported in all browsers. However, the MDN page has a polyfill for it you can use on IE9-IE11 and, presumably, Edge.
If you don't use a polyfill, what you're looking for are appendChild (spec | MDN) or insertBefore (spec | MDN), which you call on the parent, passing in the node to append.
var parent = document.createElement("h4");
parent.appendChild(
document.createTextNode("WHATEVER")
);
// ...presumably you `.appendChild(parent)` at some point...
Live Example:
var parent = document.createElement("h4");
parent.appendChild(
document.createTextNode("WHATEVER")
);
document.body.appendChild(parent);
appendChild always adds at the end of the parent. insertBefore adds before another node you specify (or at the end if you give null for the other node).
Having said that, innerHTML is universally supported and browsers are very fast at reading markup and turning it into DOM nodes. There's no reason not to use innerHTML when you have something complex you want to use as the content of an element. Naturally, though, you need appendChild, insertBefore, and other DOM methods in other situations.
In a comment you've said you want to append text to an existing text node: If so, just add to nodeValue:
setTimeout(function() {
var d = document.getElementById("target");
var txt = d.firstChild;
txt.nodeValue += " more text";
}, 800);
<div id="target">existing text</div>

Categories

Resources