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);
Related
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’);
This question already has answers here:
Creating a new DOM element from an HTML string using built-in DOM methods or Prototype
(29 answers)
Closed last year.
function addUserDataToDom(data) {
const li = document.createElement('li')
const userList = document.getElementById('user-list')
const userName = data.items[0].login
const id = data.items[0].id
const avatarUrl = data.items[0].avatar_url
li.innerHTML = userName
}
I have to add my id and avatarUrl to <li> and append to the page? Thank you
You can add any element to another one with .appendChild( childElement ). So if you want to add the "li" to the body of your document you can do this:
document.body.appendChild( li )
So, in order to achieve what you asked, you should make this:
function addUserDataToDom(data) {
const li = document.createElement('li')
const userList = document.getElementById('user-list')
const userName = data.items[0].login
const id = data.items[0].id
const avatarUrl = data.items[0].avatar_url
// Create p elements to add your user data
const pUserName = document.createElement("p")
const pId = document.createElement("p")
const pAvatrUrl = document.createElement("p")
pUserName.innerText = userName
pId.innerText = id
pAvatrUrl.innerText = avatarUrl
li.appendChild( pUserName )
li.appendChild( pId )
li.appendChild( pAvatrUrl )
}
As you can see, all the data was added as innerText inside the p element.
Finally you have to append those p elements we created earlier inside your li element.
I guess it will not let me because it is returning a string. The error I get is "Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'". How can I write this piece of code correctly?
getWord() {
let words = ["Movies", "Series", "DC Comics", "Batman"];
let word = words[Math.floor(Math.random() * words.length)];
let div = document.createElement("div");
div.appendChild(word);
}
Try div.innerText = word. Because you are trying to insert a String as a node.
If you want to stick with the div.appendChild() so that you could change the styling or element tag name of the text node in the future, you could create a text node and append it to the div instead, like so:
var text = document.createTextNode(word);
div.appendChild(text);
in your example you trying append string in the element, it's not correct, an argument for appendChild method should be element, for example:
const parent = document.createElement("div");
parent.appendChild(document.createElement("div"));
For your case, when you need to add content to the element, you should use textNode:
const title = document.createElement("H1");
const text = document.createTextNode("Movies");
title.appendChild(text);
Or:
const title = document.createElement("H1");
title.textContent = "Series";
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>
I am working on the scripting a ToDo list webapp, and I am trying to take the contents of 4 text boxes to create the content of the ToDo item.
Currently, when I try to connect the elements generated from the form, I get the error TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
at HTMLButtonElement.document.getElementsByClassName.onclick
I am currently using a function to create the element that I want to append to the body of the ToDo item, and I believe I am returning an element from my function. The code is posted below.
document.getElementsByClassName('modal-accept-button')[0].onclick = function () {
var formVals = {
what: document.getElementById('todo-input-what').value,
where: document.getElementById('todo-input-where').value,
when: document.getElementById('todo-input-when').value,
who: document.getElementById('todo-input-who').value,
details: document.getElementById('todo-input-details').value
};
document.getElementsByTagName('main')[0].appendChild(function () {
var fields = ["where", "when", "who", "details"];
var root = document.createElement("SECTION").className = "todo";
var title = document.createElement("H2").value = formVals.what;
var body = document.createElement("DIV").className = "todo-body"
for (var i = 0; i < fields.length; i++) {
var currentField = fields[i];
var currentVal = formVals.currentField;
body.appendChild(function () {
var p = document.createElement("P").className = "indent-wrapped";
var span = document.createElement("SPAN").class = currentField;
var text = document.createTextNode(currentVal);
span.value = currentField + ": ";
p.appendChild(span);
p.appendChild(text);
return p;
});
}
root.appendChild(title);
root.appendChild(body);
return root;
});
resetModal();
}
The variable p is not an item (HTML "Node"); it is a string.
That is, because you assigned it a string, using a sequence assignment (the last value goes all the way back) - "indent-wrapped" goes into className and then className goes into p.
Separate the item creation from the class assignment:
var p = document.createElement("P")
p.className = "indent-wrapped"
Same goes for root, title and span. They all are being assigned strings the same way.
You assign the string indent-wrapped to p, as you can see in the following snippet. So you try to call appendChild on a string instead of a node. Split the assignment, so you will first assign the node to p, and in the next statement set its classname. The same goes for the other elements (root, title, body, etc) where you try to create the element and set one of their properties in the same statement.
var p = document.createElement("P").className = "indent-wrapped";
console.log(p);