functions don't no longer work after rewriting code into javascript - javascript

I have a list with people's data inside it has a li element with 3 p tags inside, one for name, one for address and one for email.
I filled this list manually but due to some changes to my code I had to rewrite this so the html would be made with javascript.
My code looked like this
<p class="adres">#logopedist.Adres</p>
<p class="email">#logopedist.Email</p>
<p class="mobiel">#logopedist.Mobiel</p>
I rewrote this to build the html using javascript. This looks something like this.
var li = document.createElement('li');
li.className = "lijst";
li.id = "lijst";
li.onclick = "ficheVullen(this)";
p.className = "naam";
p.innerHTML = objLogos.Naam[i];
li.appendChild(p);
p.className = "adres";
p.innerHTML = objLogos.Adres[i];
li.appendChild(p);
var p = document.createElement('p');
p.className = "mobiel";
p.innerHTML = objLogos.Mobiel[i];
li.appendChild(p);
My list generates properly. But in my old code I had this at the start of the list.
<li class="lijst" onclick="ficheVullen(this)">
Whenever you would click an li element it would fill a div with the info from the p tags inside that li, so it would fill the div with name, address, mobile,etc
I cannot seem to get this function to work anymore. It only works on the very first LI element and only works for the name. Even though my code is the same and I append classes to the tags like it had in my old code.
The function looks like this:
function ficheVullen() {
FicheNaam = document.getElementById("FicheNaam");
FicheAdres = document.getElementById("FicheAdres");
FicheGSM = document.getElementById("FicheGSM");
FicheNaam.innerHTML = this.querySelector('.naam').textContent;
FicheGSM.innerHTML = this.querySelector('.mobiel').textContent;
FicheAdres.innerHTML = this.querySelector('.adres').textContent;
I get this error now. Cannot read property 'textContent' of null
I call this function here:
window.onload = function() {
changePage(1);
document.getElementById("lijst").addEventListener("click", ficheVullen);
};
The changepage function is part of my pagination where I use javascript to build the list.
When I move the eventlistener out of this I get this error: Cannot read property 'addEventListener' of null.
I hope this gives enough context

You have to use setAttribute to set id.
elm.setAttribute("id", "uniqueId");
Your case : li.setAttribute("id", "lijst")
li.id = "lijst"; will add "id" to object not as attribute
const parent = document.getElementById("container")
let elm = document.createElement("p")
elm.setAttribute("id", "pElm")
elm.innerText = "p tag"
parent.append(elm)
document.getElementById("pElm").style.background = "red"
<div id="container"></div>

Related

How do I nest multiple HTML elements under one element using Javascript?

I am using Javascript/socket.io to display a chat message. I am trying to mirror the structure/classes that already exist in my HTML file:
<li>
<span id="messageUsername">{{message.user}}</span>
<p id="messageViewContent">{{message.content}}</p>
</li>
My javascript is as follows:
const li = document.createElement('li');
const spanUser = document.createElement('span');
const p = document.createElement('p');
spanUser.innerHTML = `${data.messageUser}`
spanUser.classList.add("messageUsername")
p.innerHTML = `${data.messageContent}`;
p.classList.add("messageViewContent");
li.innerHTML = p + spanUser;
document.querySelector('#messageLoop').append(li);
I also tried the following: li.innerHTML = p, spanUser; and li.append(p), neither worked. With my current code, instead of display a message it is displaying: [object HTMLParagraphElement]
What am I doing wrong here? It seems so simple but I just can't seem to get the right syntax. Thanks in advance.
You're trying to concatenate DOM elements, what you really want is append them to the previously created li element.
Remove this li.innerHTML = p + spanUser;
And append the elements to li element.
li.append(spanUser);
li.append(p);

Having Trouble Displaying Input Value in Ordered List

I'm having trouble making a button that will put text inputted from a box to a list element that is inside an ordered list. My professor asked that I only use createElement, textContent and appendChild (also can't use jQuery), so my options to move the text from the input to li are extremely limited. Here's what I have so far:
let main = function() {
if (this.id == "btn1") {
let listDiv = document.getElementById('div');
let olCreator = document.createElement('OL');
div.appendChild(olCreator).setAttribute("id", "ol");
}
if (this.id == "btn2") {
let olGrab = document.getElementById('OL');
let liCreator = document.createElement('LI');
ol.appendChild(liCreator);
let inputText = document.getElementById("inputBox").textContent;
let liDone = document.getElementById('li').appendChild(inputText);
}
};
I'm pretty sure I don't want to give the li element an id, because if I do, the inputted text will go into every li element, and that'd be bad. As of now, the console tells me this when I press the button in my HTML document:
Uncaught TypeError: Cannot read property 'appendChild' of null
at HTMLButtonElement.main
You are calling appendChild on elements that do not exist or have value null.
Instead of
div.appendChild(olCreator).setAttribute("id", "ol");
try
lastDiv.appendChild(olCreator).setAttribute("id", "ol");
Same in the second condition, change ol.appendChild to olGrab.appendChild

Include a name attribute while adding to an <ol>

I'm working on a website that has a dynamic list in it and I want to be able to access individual elements in the list.
Is there a way to add a name to each element when using appendChild()?
This is my function:
function addOrder(theName, thePrice) {
var li = document.createElement("li");
var t = document.createTextNode(theName);
li.appendChild(t);
document.getElementById("cart").appendChild(li);
}
Do you mean adding a name or data to each element so you can access it at some later time in JS? If so you would want a data-attribute, which you set by using the dataset property.
function addOrder(theName, thePrice) {
var li = document.createElement("li");
// Add a data attribute with name of data-name and value of theName:
li.dataset.name = theName;
var t = document.createTextNode(theName);
li.appendChild(t);
document.getElementById("cart").appendChild(li);
}
In future code you can now look for a list item with a specific name by using something like this: document.querySelectorAll("[data-name='some name']"); or you could get all list items and filter them:
const listItems = document.querySelectorAll("#cart li");
const nameIWantToFind = 'some name';
const foundName = Array.from(listItems).filter(item => item.dataset.name === nameIWantToFind);
Also, as others have said, you don't need to use createTextNode. You can use textContent instead. Others have suggested innerHTML which will work, but isn't needed if you only plan to insert text, and textContent should have slightly better performance. Here is how you would rewrite the function:
function addOrder(theName, thePrice) {
// It's neater to put your DOM elements in variables at the top of the function
var cart = document.getElementById("cart");
var li = document.createElement("li");
// Add the text inside the `li` element:
li.textContent = theName;
// Add a data attribute with name of data-name and value of theName:
li.dataset.name = theName;
// Append the `li` element to the `#cart` using the variable we defined at the top of the function:
cart.appendChild(li);
}
Definitely!
Here you go:
== UPDATED with ES6 ==
function addOrder(theName, thePrice) {
// Select your `ul` element
const list = document.querySelector("#cart");
// Create `li` element
const li = document.createElement("li");
// Add your dynamic HTML to the `li`
li.innerHTML = theName;
// Append your `li` to your `ul`
list.appendChild(li);
}
Have any concerns? Feel free to comment!

Explaining parentNode

This isn't a help me solve something kind of question rather a explain what this does type question.
I understand what parentNode does but I can't wrap my head around the context of how it works with my code. The reason I was able to write the code was through a YouTube tutorial.
I was learning how to create a todo list app where you were able to add stuff and remove it. I made the remove button but the code I don't understand is how the remove function works in the code.
By my understanding, I'm thinking that it deletes the child which is the LI from the parent which is the UL?
If someone could explain the removeItem() function and what the code does I would very much appreciate it.
var input = document.getElementById('input'),
button = document.getElementById('add')
function removeItem() {
var item = this.parentNode
var parent = item.parentNode
parent.removeChild(item)
}
button.addEventListener('click', function(e) {
var p = document.querySelector('p')
if (input.value.trim() === '') {
p.style.display = 'block'
return false
}
p.style.display = ''
var userInput = document.createTextNode(input.value)
var li = document.createElement('li')
var ul = document.getElementById('todo')
var remove = document.createElement('button')
remove.innerHTML = 'Remove'
remove.addEventListener('click', removeItem);
ul.insertBefore(li, ul.childNodes[0])
li.appendChild(userInput)
li.appendChild(remove)
})
<input type="text" id="input"/>
<button id="add">Add</button>
<p>plz add</p>
<ul id="todo"></ul>
You are correct. The best way to remove a node in Javascript is from its parent, using the removeChild() function.
You could use the remove() function like item.remove(), but this will not work with IE because in IE this function does another thing, it removes an option from a drop-down list (select).
So, to achieve cross-browser behavior, it is used the removeChild approach.

Is possible to insert HTML.Actionlink inside LI?

I'm trying to insert a #HTML.ActionLink element inside a li element using the following code:
var ul = document.getElementById('container');
var enlace = '#Html.ActionLink("Details", "Details", "Elements", new { id = "5" }, null)';
var li = document.createElement('li');
li.appendChild(document.createTextNode('My title'));
li.appendChild(document.createElement('br'));
///////////////////////////////////////////////
li.appendChild(document.createElement(enlace));
///////////////////////////////////////////////
ul.appendChild(li);
Is it possible?
You're passing an entire HTML element to document.createElement(), which expects only a tag name. Essentially, you're doing this:
document.createElement('some text')
whereas the function works like this:
document.createElement('a');
You can probably fix this by separating the creation of the element from the setting of the element's HTML to your custom server-generated HTML. Replacing just the code surrounded by the comments, it might look like this:
///////////////////////////////////////////////
var enlaceElement = document.createElement('a');
enlaceElement.innerHTML = enlace;
li.appendChild(enlaceElement);
///////////////////////////////////////////////
I have a full demo here.

Categories