this is my first post here. Please excuse my poor code, I will try my best to describe my issue.
I'm building a Library app from Odin Project. Currently I'm able to create an object with values I'm inputting in a popup form. Created object is being displayed on the screen with correct values as intended.
My goal is to update Read status in a myLibrary array when I click on a button. I was able to update the text content on the button with a click, unfortunately I have no idea how to update a read value in an array for the created object.
I would really appreciate any suggestions.
Thank you for your time
let myLibrary = [];
const registerBook = document.getElementById("registerBook");
const title = document.getElementById("title");
const author = document.getElementById("author");
const pages = document.getElementById("pages");
let read = document.getElementById("read-btn");
let form = document.getElementById("bookForm");
let optionYes = document.getElementById("option-yes");
let optionNo = document.getElementById("option-no");
function openForm() {
document.getElementById("bookForm").style.display = "block";
}
function closeForm() {
document.getElementById("bookForm").style.display = "none";
}
registerBook.addEventListener("click", function() {
myLibrary.push({
title: title.value,
author: author.value,
pages: pages.value,
read: read.value,
})
renderBooks();
console.log(myLibrary);
})
function renderBooks() {
let bookShelf = document.querySelector('#bookShelf');
let bookCover = document.createElement('div');
bookCover.classList.add('bookCover');
bookShelf.appendChild(bookCover);
let deleteCard = document.createElement('div');
deleteCard.classList.add('delete-card');
deleteCard.id = "deleteCard";
bookCover.append(deleteCard);
let bookTitleTag = document.createElement('div');
bookTitleTag.classList.add('book-title-tag');
bookCover.append(bookTitleTag);
bookTitleTag.textContent = 'Book title:';
let bookTitle = document.createElement('div');
bookTitle.classList.add('book-title');
bookCover.append(bookTitle);
let bookAuthorTag = document.createElement('div');
bookAuthorTag.classList.add('book-author-tag');
bookCover.append(bookAuthorTag);
bookAuthorTag.textContent = 'Book author:';
let bookAuthor = document.createElement('div');
bookAuthor.classList.add('book-author');
bookCover.append(bookAuthor);
let bookPagesTag = document.createElement('div');
bookPagesTag.classList.add('book-pages-tag');
bookCover.append(bookPagesTag);
bookPagesTag.textContent = 'No of pages:';
let bookPages = document.createElement('div');
bookPages.classList.add('book-pages');
bookCover.append(bookPages);
let bookStatusTag = document.createElement('div');
bookStatusTag.classList.add('book-pages-tag');
bookCover.append(bookStatusTag);
bookStatusTag.textContent = 'Have you read the book?:';
let bookStatus = document.createElement('button');
bookStatus.classList.add('book-status-btn');
bookStatus.id = 'book-status-btn';
bookCover.append(bookStatus);
bookTitle.textContent = title.value;
bookAuthor.textContent = author.value;
bookPages.textContent = pages.value;
bookStatus.textContent = read.value;
/*Book status in card is updated */
bookStatus.addEventListener("click", () => {
if (bookStatus.textContent === 'Yes') {
bookStatus.textContent = 'No'
} else {
if (bookStatus.textContent === 'No') {
bookStatus.textContent = 'Yes'
}
}
});
/* Trying to update array */
bookStatus.addEventListener("click", () => {
if (bookCover.read === 'Yes') {
bookCover.read = 'No'
} else {
if (bookCover.read === 'No') {
bookCover.read = 'Yes'
}
}
console.log(myLibrary);
});
deleteCard.addEventListener("click", () => {
bookShelf.removeChild(bookCover);
myLibrary.splice(bookCover, 1);
});
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<script defer src="index.js"></script>
<title>Library</title>
</head>
<body>
<div class="wrapper">
<div class="header">
<div class="logo">Library</div>
<div class="buttons">
<div class="add-book-btn" id="addBookBtn" onclick="openForm()">Add Book</div>
<!--<div class="login-btn">Log in</div> -->
</div>
</div>
<div class="main">
<div class="form-popup" id="bookForm">
<form action="/action_page.php" onsubmit="event.preventDefault()" class="form-container">
<div class="form-popup-close" onclick="closeForm()"></div>
<h1>Add Book</h1>
<label for="title"><b>Book title</b></label>
<input type="text" id="title" placeholder="Enter book title" name="title" required>
<label for="author"><b>Author</b></label>
<input type="text" id="author" placeholder="Enter author name" name="author">
<label for="pages"><b>No. of pages</b></label>
<input type="number" id="pages" placeholder="Number of pages" name="pages">
<div class="form-bot">
<p>Have you read it?</p>
<select name="read" id="read-btn">
<option id="option-yes" value="Yes">Yes</option>
<option id="option-no" value="No">No</option>
</select>
</div>
<button type="button" class="btn" id="registerBook" onclick="closeForm()">Register Book</button>
</form>
</div>
<div id="bookShelf"></div>
</div>
</div>
</body>
</html>
You can get the title from the bbookTitle DIV, and search the array for that title. Then you can toggle the read property.
let myLibrary = [];
const registerBook = document.getElementById("registerBook");
const title = document.getElementById("title");
const author = document.getElementById("author");
const pages = document.getElementById("pages");
let read = document.getElementById("read-btn");
let form = document.getElementById("bookForm");
let optionYes = document.getElementById("option-yes");
let optionNo = document.getElementById("option-no");
function openForm() {
document.getElementById("bookForm").style.display = "block";
}
function closeForm() {
document.getElementById("bookForm").style.display = "none";
}
registerBook.addEventListener("click", function() {
myLibrary.push({
title: title.value,
author: author.value,
pages: pages.value,
read: read.value,
})
renderBooks();
console.log(myLibrary);
})
function renderBooks() {
let bookShelf = document.querySelector('#bookShelf');
let bookCover = document.createElement('div');
bookCover.classList.add('bookCover');
bookShelf.appendChild(bookCover);
let deleteCard = document.createElement('div');
deleteCard.classList.add('delete-card');
deleteCard.id = "deleteCard";
bookCover.append(deleteCard);
let bookTitleTag = document.createElement('div');
bookTitleTag.classList.add('book-title-tag');
bookCover.append(bookTitleTag);
bookTitleTag.textContent = 'Book title:';
let bookTitle = document.createElement('div');
bookTitle.classList.add('book-title');
bookCover.append(bookTitle);
let bookAuthorTag = document.createElement('div');
bookAuthorTag.classList.add('book-author-tag');
bookCover.append(bookAuthorTag);
bookAuthorTag.textContent = 'Book author:';
let bookAuthor = document.createElement('div');
bookAuthor.classList.add('book-author');
bookCover.append(bookAuthor);
let bookPagesTag = document.createElement('div');
bookPagesTag.classList.add('book-pages-tag');
bookCover.append(bookPagesTag);
bookPagesTag.textContent = 'No of pages:';
let bookPages = document.createElement('div');
bookPages.classList.add('book-pages');
bookCover.append(bookPages);
let bookStatusTag = document.createElement('div');
bookStatusTag.classList.add('book-pages-tag');
bookCover.append(bookStatusTag);
bookStatusTag.textContent = 'Have you read the book?:';
let bookStatus = document.createElement('button');
bookStatus.classList.add('book-status-btn');
bookStatus.id = 'book-status-btn';
bookCover.append(bookStatus);
bookTitle.textContent = title.value;
bookAuthor.textContent = author.value;
bookPages.textContent = pages.value;
bookStatus.textContent = read.value;
/*Book status in card is updated */
bookStatus.addEventListener("click", () => {
if (bookStatus.textContent === 'Yes') {
bookStatus.textContent = 'No'
} else {
if (bookStatus.textContent === 'No') {
bookStatus.textContent = 'Yes'
}
}
});
/* Trying to update array */
bookStatus.addEventListener("click", () => {
let title = bookTitle.textContent;
let book = myLibrary.find(book => book.title === title);
if (book) {
book.read = book.read === 'Yes' ? 'No' : 'Yes';
bookStatus.textContent = book.read;
}
console.log(myLibrary);
});
deleteCard.addEventListener("click", () => {
bookShelf.removeChild(bookCover);
myLibrary.splice(bookCover, 1);
});
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<script defer src="index.js"></script>
<title>Library</title>
</head>
<body>
<div class="wrapper">
<div class="header">
<div class="logo">Library</div>
<div class="buttons">
<div class="add-book-btn" id="addBookBtn" onclick="openForm()">Add Book</div>
<!--<div class="login-btn">Log in</div> -->
</div>
</div>
<div class="main">
<div class="form-popup" id="bookForm">
<form action="/action_page.php" onsubmit="event.preventDefault()" class="form-container">
<div class="form-popup-close" onclick="closeForm()"></div>
<h1>Add Book</h1>
<label for="title"><b>Book title</b></label>
<input type="text" id="title" placeholder="Enter book title" name="title" required>
<label for="author"><b>Author</b></label>
<input type="text" id="author" placeholder="Enter author name" name="author">
<label for="pages"><b>No. of pages</b></label>
<input type="number" id="pages" placeholder="Number of pages" name="pages">
<div class="form-bot">
<p>Have you read it?</p>
<select name="read" id="read-btn">
<option id="option-yes" value="Yes">Yes</option>
<option id="option-no" value="No">No</option>
</select>
</div>
<button type="button" class="btn" id="registerBook" onclick="closeForm()">Register Book</button>
</form>
</div>
<div id="bookShelf"></div>
</div>
</div>
</body>
</html>
Related
My buttons for edit delete and save are not working and that is because the event listener is passing an element that has nothing in it, but I want to target the class <div class="task" date-id = "${id}"> for the event listener.
This is what is wrong:
elements.list.addEventListener('click',event => the elements.list is wrong as it is not holding anything. But I would like to target the <div class="task" date-id = "${id}"> for the eventEventListener.
Please see the full code so you have a better idea:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>To-do App</title>
<script src="js/main.js" defer></script>
<script src="js/dateTime.js" defer></script>
<link rel="stylesheet" href="css/main.css" />
</head>
<body>
<div class="header">
<h1>To-Do List</h1>
<div class="time">
<div class="dateTime"></div>
<div class="day"></div>
</div>
</div>
<form id="new-task-form">
<div class="add-task">
<input type="text" name="new-task-input" id="new-task-input" placeholder="What do you have planned?" />
<input type="date" id="calendar">
</div>
<input type="submit" id="new-task-submit" value="Add task" />
</form>
</header>
<main>
<section class="task-list">
<h2>Tasks</h2>
<div id="tasks">
<!--<button class = "sort">Sort</button>
<div class="task">
<div class="content">
<input
type="text"
class="text"
value="A new task"
readonly>
</div>
<div class="actions">
<button class="edit">Edit</button>
<button class="delete">Delete</button>
</div>
</div>-->
</div>
</section>
</main>
</body>
</html>
JS
/************************************
* creates objct of elements needed *
************************************/
const elements = {
form: document.querySelector("#new-task-form"),
input: document.querySelector("#new-task-input"),
list: document.querySelector("#tasks"),
cal: document.querySelector("#calendar")
}
/****************************
* Generates an ID for task *
****************************/
const createId = () => `${Math.floor(Math.random() * 10000)}-${new Date().getTime()}`
/**********************************************
* function that creates the HTML elements *
**********************************************/
const createTask = () => {
const id = createId()
const task = elements.input.value;
const date = elements.cal.value;
if(!task && !date) return alert("Please fill in task and select date");
if(!task) return alert("Please fill in task");
if(!date) return alert("Please select date");
const tasks = document.createElement("div");
tasks.innerHTML = `
<button class = "sort">Sort</button>
<div class="task" data-id = "${id}">
<div class="content">
<input type ="checkbox" class="tick">
<input type ="text" class = "text" id = "text" readonly>${task}
<label class = "due-date" for ="text">${date}</label>
<input type ="date" class = "date" id = "date">
</div>
<div class = "actions">
<button class="edit" data-id="${id}">Edit</button>
<button class="delete" data-id="${id}">Delete</button>
</div>
</div>
`
elements.list.appendChild(tasks)
return tasks
}
/**************************************************************
* Event that listens for the edit,save and delete buttons *
**************************************************************/
elements.list.addEventListener('click',event => {
const {target} = event
const {id} = target.dataset
const task = id ? document.querySelector('[data-id="${id}"]'):null;
const type = {
edit: event.target.classList.contains('edit'),
delete: event.target.classList.contains('delete')
}
const isFromSaveLabel = target.innerText.toLowerCase() === 'save'
if(task && type.edit && isFromSaveLabel){
const text = task.querySelector('.text')
target.innerText = 'Edit'
text.addAttribute('readonly')
return
};
if(task && type.edit){
const text = task.querySelector('.text')
target.innerText = 'save'
text.removeAttribute('readonly')
text.focus()
return
};
if(task && type.delete){
return
}
});
/*******************************************************************
* Submits the HTML elements to have the lists submitted and created*
*******************************************************************/
const submitHandler = (event) =>{
event.preventDefault();
createTask();
}
elements.form.addEventListener("submit", submitHandler);
I have been asking a lot about this on the platform, but I realized I have been asking the wrong question. As mentioned above I need the event listener to target the <div class="task" date-id = "${id}"> that has been created with const tasks = document.createElement("div");
The reason is when you click on add task it creates a new <div class="task" date-id = "${id}"> for example ```````
with the contents class and everything in there.
PS: Apologies for the long-winded code, it's necessary so that you get the full picture of the issue and question
Could it be beacause you used "date-id" on tasks.innerHTML, but use "data-id" on
const task = id ? document.querySelector('[data-id="${id}"]'):null;
Okay, I found some issues in the event listener:
the queryselector is not a template literal, so ${id} doesn't work.
"addAttribute" is wrong. "setAttribute" is the correct one.
Edit and save works after these are fixed.
/**************************************************************
* Event that listens for the edit,save and delete buttons *
**************************************************************/
elements.list.addEventListener('click',event => {
const {target} = event
const {id} = target.dataset
const task = id ? document.querySelector(`[data-id="${id}"]`):null;
const type = {
edit: event.target.classList.contains('edit'),
delete: event.target.classList.contains('delete')
}
const isFromSaveLabel = target.innerText.toLowerCase() === 'save'
if(task && type.edit && isFromSaveLabel){
const text = task.querySelector('.text')
target.innerText = 'Edit'
text.setAttribute('readonly', 'true')
return
};
if(task && type.edit){
const text = task.querySelector('.text')
target.innerText = 'save'
text.removeAttribute('readonly')
text.focus()
return
};
if(task && type.delete){
return
}
});
And for the error, it is probably a bug in the extension.
I am trying to add a style [text-decoration: line-through] to a value of an object property. How to add the style at javascript code line no 28 closeIssue?
I want to add style to the currentIssue.description.
Here is my code:
document.getElementById('issueInputForm').addEventListener('submit', submitIssue);
function submitIssue(e) {
const getInputValue = id => document.getElementById(id).value;
const description = getInputValue('issueDescription');
const severity = getInputValue('issueSeverity');
const assignedTo = getInputValue('issueAssignedTo');
const id = Math.floor(Math.random() * 100000000) + '';
const status = 'Open';
const issue = { id, description, severity, assignedTo, status }; // issue = object
let issues = [];
if (localStorage.getItem('issues')) {
issues = JSON.parse(localStorage.getItem('issues'));
}
issues.push(issue);
localStorage.setItem('issues', JSON.stringify(issues));
document.getElementById('issueInputForm').reset();
fetchIssues();
e.preventDefault();
}
const closeIssue = id => {
const issues = JSON.parse(localStorage.getItem('issues'));
const currentIssue = issues.find(issue => issue.id == id);
currentIssue.status = 'Closed';
// How to add a style on "currentIssue.description"
localStorage.setItem('issues', JSON.stringify(issues));
fetchIssues();
}
const deleteIssue = id => {
const issues = JSON.parse(localStorage.getItem('issues'));
const remainingIssues = issues.filter(issue => issue.id != id)
localStorage.setItem('issues', JSON.stringify(remainingIssues));
fetchIssues();
}
const fetchIssues = () => {
const issues = JSON.parse(localStorage.getItem('issues'));
const issuesList = document.getElementById('issuesList');
issuesList.innerHTML = '';
for (var i = 0; i < issues.length; i++) {
const { id, description, severity, assignedTo, status } = issues[i];
issuesList.innerHTML += `<div class="well">
<h6>Issue ID: ${id} </h6>
<p><span class="label label-info"> ${status} </span></p>
<h3 id="xxx"> ${description} </h3>
<p><span class="glyphicon glyphicon-time"></span> ${severity}</p>
<p><span class="glyphicon glyphicon-user"></span> ${assignedTo}</p>
Close
Delete
</div>`;
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Issue Tracker: </title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<style>
.lt {
text-decoration: line-through;
}
</style>
</head>
<body onload="fetchIssues()">
<div class="container">
<h1>Issue Tracker: <span id="issue-counter"></span></h1>
<div class="jumbotron">
<h3>Add New Issue:</h3>
<form id="issueInputForm">
<div class="form-group">
<label for="issueDescription">Description</label>
<input type="text" class="form-control" id="issueDescription" placeholder="Describe the issue ...">
</div>
<div class="form-group">
<label for="issueSeverity">Severity</label>
<select id="issueSeverity" class="form-control">
<option value="Low">Low</option>
<option value="Medium">Medium</option>
<option value="High">High</option>
</select>
</div>
<div class="form-group">
<label for="issueAssignedTo">Assigned To</label>
<input type="text" class="form-control" id="issueAssignedTo" placeholder="Enter responsible ...">
</div>
<button type="submit" class="btn btn-primary">Add</button>
</form>
</div>
<div class="col-lg-12">
<div id="issuesList"></div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"
integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
<script src="main.js"></script>
</body>
</html>
How can I do that?
man u can try this :
value.style.textDecoration = 'line-through'
I have a simple to do application with local storage. In my app user can create unordered list with new tasks. Last element in this app is local storage. I have a problem with this functionality.
Before I save the items in localstorage I can delete them using the button. I don't know why but it doesn't works after saving elements.
Any idea how can I fix it?
My code:
const first= document.getElementById("first");
const second= document.getElementById("second");
function addList(e) {
const newElement = document.createElement("li");
newElement.innerHTML = first.value + second.value;
}
newElement.innerHTML += "<button> X </button>";
ul.appendChild(newElement);
store();
newElement.querySelector("button").addEventListener("click", removeElement);
}
function removeElement(e) {
e.target.parentNode.remove();
}
function store() {
window.localStorage.myitems = ul.innerHTML;
}
function getValues() {
let storedValues = window.localStorage.myitems;
if(storedValues) {
ul.innerHTML = storedValues;
ul.querySelector("button").addEventListener("click", removeElement);
}
}
getValues();
<div class="container">
<form>
<input type="text" id="first" name="artist" placeholder="Artist" />
<input type="text" id="second" name="title" placeholder="Song title" />
<button type="button" onclick="addList(event)">Add task</button>
</form>
</div>
<div class="li-elements">
<ul class="list"></ul>
</div>
Looks like you were just missing a few small things in ur code. You were not properly adding the removeElement event listener when loading from localStorage, and you were not properly updating localStorage. I have updated ur code so it works.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div class="container">
<form>
<input type="text" id="first" name="artist" placeholder="Artist" />
<input type="text" id="second" name="title" placeholder="Song title" />
<button type="button" onclick="addList(event)">Add task</button>
</form>
</div>
<div class="li-elements">
<ul id="list" class="list"></ul>
</div>
<script>
function addList(e) {
const first = document.getElementById("first");
const second = document.getElementById("second");
const newElement = document.createElement("li");
newElement.innerHTML = first.value + second.value;
newElement.innerHTML += "<button> X </button>";
document.getElementById("list").appendChild(newElement);
store();
newElement.querySelector("button").addEventListener("click", removeElement);
}
function removeElement(e) {
e.target.parentNode.remove();
store();
}
function store() {
window.localStorage["myitems"] = document.getElementById("list").innerHTML;
}
function getValues() {
let storedValues = window.localStorage["myitems"];
if (storedValues) {
let ul = document.getElementById("list");
ul.innerHTML = storedValues;
for (i = 0; i < ul.childNodes.length; i++) {
ul.childNodes[i].querySelector("button").addEventListener("click", removeElement);
}
}
}
getValues();
</script>
</body>
</html>
hey i need help with creating a delete button for my "notes" so it will delete it from the screen and the localstorage (u will notice i tried to make a delBtn function but with no success) i would appreciate if someone could post a fix to mine and explain me where i went wrong.
My JS
const tableBody = document.getElementById("tableBody");
const taskInfo = document.getElementById("taskInfo");
const taskDate = document.getElementById("taskDate");
const taskTime = document.getElementById("taskTime");
const delBtn = document.getElementById("delBtn")
let x = new Task("this is a test", "2021-04-14", "03:19");
let y = new Task("this is a 2nd test", "2021-04-14", "03:19");
//x.add();
//y.add();
let taskList = [
x, y, (new Task("this is a 3rd test", "2021-04-14", "03:19"))
];
if (localStorage.savedTaskList)
taskList = JSON.parse(localStorage.savedTaskList);
displayTable();
function displayTable() {
tableBody.innerHTML = "";
for (let task of taskList) {
const div = document.createElement("div");
div.setAttribute("class","taskZone");
const divTaskInfo = document.createElement("div");
divTaskInfo.setAttribute("class","taskInfo");
const divTaskDate = document.createElement("div");
divTaskDate.setAttribute("class","taskDate");
const divTaskTime = document.createElement("div");
divTaskTime.setAttribute("class","taskTime");
const delBtn = document.createElement("span");
delBtn.setAttribute("class","delBtn");
divTaskInfo.innerText = task.taskInfo;
divTaskDate.innerText = task.taskDate;
divTaskTime.innerText = task.taskTime;
div.append(divTaskInfo, divTaskDate, divTaskTime);
tableBody.appendChild(div);
}
}
delBtn.onclick = function delTask() {
delBtn.parentNode.removeChild(taskZoneElmToDel)
}
function addTask() {
if (taskInfo.value == '' || taskDate.value == '' || taskTime.value == '') {
return alert(`Please fill all the fields.`);
}else{newTask = new Task(taskInfo.value, taskDate.value, taskTime.value);
taskList.push(newTask);
localStorage.savedTaskList = JSON.stringify(taskList);
displayTable();
}
}
Thats the Html part of it
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Task Board</title>
<link rel="stylesheet" href="style.css">
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
</head>
<body>
<div class="scaleable-wrapper" id="scaleable-wrapper">
<div class="very-specific-design" id="very-specific-design">
<header class="Title">
My Task Board
</header>
<div id="Input">
</br>
</br>
<form class="Form" id="formInfo">
<label for="taskInfo">Task Info:</label>
<input type="text" id="taskInfo" name="taskInfo" required autofocus></input></br>
<label for="taskDate">Task Date:</label>
<input type="date" id="taskDate" name="taskDate" required></input></br>
<label for="taskTime">Task Time:</label>
<input type="time" id="taskTime" name="taskTime" required></input></br>
<input type="submit" id="addTaskDiv" class="btn" value="Save" onclick="addTask()"></input>
<input type="reset" id="resetForm" class="btn"></input>
</form>
</br>
</br>
</div>
<div class="outNotes"></div>
<div class="tableBody">
<table>
<tbody id="tableBody">
</tbody>
</table>
</div>
</div>
</div>
<input type="button" id="delBtn">x</input>
</body>
<script src="Task.js"></script>
<script src="script2.js"></script>
</html>
I have a table that gets populated with data from Firebase. Each tr shows that data. I have dynamically created a form that gets appended to each tr, the problem is that it is not showing and I can't figure out why. I inspected each tr with the dev tools and it shows that the form with the input is indeed there but for some reason it is not visible, why? Here is my html:
const animalList = document.querySelector('#animal-list');
const form = document.querySelector('#add-animals');
function renderAnimals(doc) {
let tr = document.createElement('tr');
let deleteButton = document.createElement('button');
let name = document.createElement('div');
let species = document.createElement('div');
let age = document.createElement('div');
let last_fed = document.createElement('div');
let last_shed = document.createElement('div');
let diet = document.createElement('div');
let basking_area_temp = document.createElement('div');
let cold_part_temp = document.createElement('div');
let humidity = document.createElement('div');
let additional_info = document.createElement('div');
// The form that does not become visible
let form = document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("action", "default.aspx");
form.setAttribute("target", "_blank");
let inputField = document.createElement("input");
inputField.setAttribute("name", "firtname");
inputField.setAttribute("value","product1,product2" );
inputField.setAttribute("type", "text");
form.setAttribute("class", "f")
form.appendChild(inputField);
tr.setAttribute('data-id', doc.id);
name.textContent = `name: ${doc.data().name}`
deleteButton.textContent = 'Delete';
deleteButton.setAttribute('class','btn btn-danger');
species.textContent = `species: ${doc.data().species}`
age.textContent = `age: ${doc.data().age}`
last_fed.textContent = `last fed: ${doc.data().last_fed}`;
last_shed.textContent = `last shed: ${doc.data().last_shed}`;
diet.textContent = `diet: ${doc.data().diet}`;
basking_area_temp.textContent =`basking area temp: ${ doc.data().basking_area_temp}`;
cold_part_temp.textContent = `cold part temp: ${doc.data().cold_part_temp}`;
humidity.textContent = `humidity: ${doc.data().humidity}`;
additional_info.textContent = `additional info: ${doc.data().additional_info}`;
tr.appendChild(species);
tr.append(name);
tr.append(age);
tr.append(last_fed);
tr.append(last_shed);
tr.append(diet);
tr.append(basking_area_temp);
tr.append(cold_part_temp);
tr.append(humidity);
tr.append(additional_info);
tr.append(deleteButton);
tr.append(form);
animalList.appendChild(tr);
//deleting data
deleteButton.addEventListener('click', (event) => {
event.stopPropagation();
let id = event.target.parentElement.getAttribute('data-id');
db.collection('animals').doc(id).delete();
})
}
// getting data from the back end
db.collection('animals').onSnapshot(snapshot => {
let changes = snapshot.docChanges();
changes.forEach(change => {
if(change.type == 'added') {
renderAnimals(change.doc);
} else if (change.type == 'removed') {
let li = animalList.querySelector('[data-id=' + change.doc.id + ']');
animalList.removeChild(li);
}
})
})
// adding data
form.addEventListener('submit', (event) => {
event.preventDefault();
db.collection('animals').add({
species: form.species.value,
name: form.name.value,
age: form.age.value,
last_fed: document.querySelector('#last-fed').value,
last_shed: document.querySelector('#last-shed').value,
diet: form.diet.value,
basking_area_temp: document.querySelector('#basking-area-temperature').value,
cold_part_temp: document.querySelector('#cold-temperature').value,
humidity: form.humidity.value,
additional_info: document.querySelector('#additional-info').value
})
})
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Repti Care</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://www.gstatic.com/firebasejs/5.5.7/firebase.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.5.5/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.5.5/firebase-firestore.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css"
integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<link rel="stylesheet" href="./css/main.css">
</head>
<body>
<div class="jumbotron">
<div class="placeholder"></div>
</div>
<div class="container">
<h2>Add a new Animal</h2>
<form class="form-group" id="add-animals">
Species: <input type="text" id="species" class="form-control">
Name: <input type="text" id="name" class="form-control" >
Age: <input type="text" id="age" class="form-control">
Last Fed: <input type="date" id="last-fed" class="form-control">
Last Shed: <input type="date" id="last-shed" class="form-control">
Diet: <input type="text" id="diet" class="form-control">
Basking area temperature: <input type="text" id="basking-area-temperature" class="form-control">
Cold part temperature: <input type="text" id="cold-temperature" class="form-control">
Humidity: <input type="text" id="humidity" class="form-control">
Addition Info: <textarea class="form-control" id="additional-info"></textarea>
<button id="btnCreate" class="btn btn-primary">Create</button>
</form>
<h3>View Current Animals</h3>
<table id="animal-list">
<th>Animals</th>
</table>
</div>
</div>
<script>
// Initialize Firebase
var config = {
apiKey: "AIzaSyBSuC8nqJzLe7d5jKS-_nE15kaI9Y6NIfI",
authDomain: "repti-care-32176.firebaseapp.com",
databaseURL: "https://repti-care-32176.firebaseio.com",
projectId: "repti-care-32176",
storageBucket: "repti-care-32176.appspot.com",
messagingSenderId: "632910932105"
};
firebase.initializeApp(config);
const db = firebase.firestore();
db.settings({ timestampsInSnapshots: true });
</script>
<script
src="https://code.jquery.com/jquery-3.3.1.js"
integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
crossorigin="anonymous"></script>
<script src="./scripts/main.js"></script>
</body>
</html>
The problem here is that you're appending elements (name, age, etc.) to a tr element. You need to add a td element inside your tr then append to the td.
Solution:
After let tr = document.createElement("tr"); add let td = document.createElement("td");.
Change tr to td in all 12 lines from tr.appendChild(species); to tr.append(form);.
After td.append(form); add tr.appendChild(td);
https://codepen.io/rockysims/pen/VVQmYB