I have been trying to get my renderUserList to work when I submit a new Person to the array and display it in a table row. To test that it does render from the start I added a first person to the array from the get-go. When I console log the array and the renderfunction themselves, they seem to work. The array increases and the site renders anew when I "submit" something. However, my page remains empty regardless of what I do and only the array seems to actually work as intended, but my html dom does not change in the slightest.
class Person {
public Firstname: string;
public Lastname: string;
constructor(Firstname: string, Lastname: string) {
this.Firstname = Firstname;
this.Lastname = Lastname;
}
}
let people: Person[] = [
new Person("Peter", "Parker")]
document.addEventListener("DOMContentLoaded", () => {
renderUserList(people);
document.getElementById("add-user").addEventListener("submit", (event) => {
event.preventDefault();
const FormField: HTMLFormElement = document.getElementById("add-person") as
HTMLFormElement
const FirstNameInput: HTMLInputElement = document.getElementById("Firstname") as
HTMLInputElement;
const LastNameInput: HTMLInputElement = document.getElementById("Lastname") as
HTMLInputElement;
const FName: string = FirstNameInput.value;
const LName: string = LastNameInput.value;
if (FName && LName) {
people.push(new Person(FName, LName));
renderUserList(people);
FormField.reset();
}
})
function renderUserList(userlist: Person[]): void {
const peoplelist: HTMLElement = document.getElementById("peoplelist")
for (let i: number = 0; i < userlist.length; i++) {
peoplelist.innerHTML = "";
`<tr>
<td class="p-3 table-font">${people[i].Firstname}</td>
<td class="p-3 table-font">${people[i].Lastname}</td>
<td>
<button class="btn tablebutton delete-button list-button" data-idx="${i}"><i class="fas fa-trash-alt"></i></button>]
<button type="button" class="btn tablebutton edit-button list-button" data-bs-toggle="modal" data-bs-target="#ModalWindow" data-idx="${i}"><i class="fas fa-user-edit"></i></button>
</td>
</tr>`;
}
}
})
Might this be a typo? There's a line peoplelist.innerHTML = "";
right above the template string containing the <tr>
markup. I would wager that something like the following was intended.
function renderUserList(userlist: Person[]): void {
const peoplelist: HTMLElement = document.getElementById("peoplelist");
for (let i: number = 0; i < userlist.length; i++) {
peoplelist.innerHTML = `<tr>
<td class="p-3 table-font">${people[i].Firstname}</td>
<td class="p-3 table-font">${people[i].Lastname}</td>
<td>
<button class="btn tablebutton delete-button list-button" data-idx="${i}"><i class="fas fa-trash-alt"></i></button>]
<button type="button" class="btn tablebutton edit-button list-button" data-bs-toggle="modal" data-bs-target="#ModalWindow" data-idx="${i}"><i class="fas fa-user-edit"></i></button>
</td>
</tr>`;
}
}
There's still a bit of a problem, though, because the innerHTML
assignment within a loop will replace the previous contents, ending up with just the last person rendered. You might build up the markup in the for
loop before assigning all rows to peoplelist.innerHTML
at once — or perhaps even look into other ways of DOM manipulation, like insertAdjacentHTML
.
Also, as an aside, it's good to keep the possible security problems in mind when rendering user inputs as markup. What if someone enters code as their name? Could you render the parts you don't trust as plain text (with textContent
, for example)?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With