I’ve build a simple Expense Tracker that contains 3 inputs
Name input
Date input
Amount input
After the user fills these 3 inputs, they can click a button to add the expense into a table and store it there. If they want to remove an expense from the table, they can click the “REMOVE ENTRY” button.
If the table is empty, the “No expenses added yet!” tr
element is shown. Once an expense gets added, the tr
element with the message disappears. However, if I add an expense to the table and then remove it, the tr
element with the message no longer appears. Is there any way how I can make it re-appear again?
let nameInput = document.querySelector(".name");
let dateInput = document.querySelector(".date");
let amountInput = document.querySelector(".amount");
let button = document.querySelector(".add-btn");
let ifEmpty = document.querySelector(".if-empty");
let table = document.querySelector("table");
button.addEventListener("click", function() {
ifEmpty.remove();
// CREATE THE EXPENSE
let holder = document.createElement("tr");
let row = document.createElement("td");
let btnRow = document.createElement("td");
let removeButton = document.createElement("button");
table.appendChild(holder);
holder.appendChild(row).textContent = nameInput.value;
holder.appendChild(row.cloneNode(true)).textContent = dateInput.value;
holder.appendChild(row.cloneNode(true)).textContent = amountInput.value;
holder.appendChild(btnRow);
btnRow.appendChild(removeButton).textContent = "REMOVE ENTRY";
// REMOVE THE EXPENSE
removeButton.addEventListener("click", function() {
holder.remove();
});
/* TRIED THIS TO MAKE THE ELEMENT RE-APPEAR IF THE TABLE IS EMPTY BUT
IT DIDN'T WORK */
if (!table.contains(holder)) {
table.appendChild(ifEmpty);
}
});
.container {
text-align: center;
}
h1 {
font-size: 3.5em;
}
h2 {
font-size: 2em;
margin-bottom: 0.5em;
color: green;
}
span {
font-size: 1.4em;
}
.date-amount-input {
margin-top: 0.5em;
}
input {
height: 28px;
}
.name {
padding-right: 5em;
}
.amount {
padding-right: 15.35em;
}
.amount-text {
margin-left: 0.4em;
}
.date {
padding-right: 18.8em;
}
.add-btn {
margin-top: 0.9em;
padding: 0.6em;
font-size: 1.1em;
background: green;
color: white;
border: none;
border-radius: 5px;
}
.add-btn:hover, .add-btn:focus {
cursor: pointer;
background: rgb(3, 177, 3);
}
table {
margin: 0 auto;
margin-top: 2em;
width: 50%;
height: 80px;
}
tr {
height: 40px;
}
table, th, td{
border: 1px solid rgba(0, 0, 0, 0.103);
border-collapse: collapse;
}
.empty-text {
font-size: 0.93em;
}
.if-empty {
background: rgba(0, 0, 0, 0.055);
}
<body>
<div class="container">
<h1>Expense Tracker</h1>
<h2>Add A New Item</h2>
<div class="name-input">
<span class="name-text">Name: </span>
<input type="text" class="name" placeholder="Where was the expense made" size="117">
</div>
<div class="date-amount-input">
<span>Date: </span>
<input class="date" type="date">
<span class="amount-text">Amount: </span>
<input class="amount" type="text">
</div>
<button class="add-btn">Add Expense</button>
<table>
<tr>
<th>Name</th>
<th>Date</th>
<th>Amount</th>
</tr>
<tr class="if-empty">
<td colspan = "4">
<span class="empty-text">No expenses added yet!</span>
</td>
</tr>
</table>
</div>
<script src="main.js"></script>
</body>
I am still a beginner in JS, so any tips will be aprecitated.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You do an ifEmpty.remove();
, that actually removes the element. Once it is removed it is gone and you can’t make it reappear without creating it again.
The easier solution may be to hide it instead of removing it.
You can use ifEmpty.style.display = "none"
to hide it and ifEmpty.style.display = "table-row"
to show it again
Method 2
Show/hide can be done with pure CSS, display as table-row
if it is the last <tr>
. Make sure new rows are added inside the same <tbody>
.
tr.if-empty { background: rgba(0, 0, 0, 0.055); display: none; } tr:last-child.if-empty { display: table-row; }
let nameInput = document.querySelector(".name");
let dateInput = document.querySelector(".date");
let amountInput = document.querySelector(".amount");
let button = document.querySelector(".add-btn");
let ifEmpty = document.querySelector(".if-empty");
let table = document.querySelector("table > tbody");
button.addEventListener("click", function() {
// CREATE THE EXPENSE
let holder = document.createElement("tr");
let row = document.createElement("td");
let btnRow = document.createElement("td");
let removeButton = document.createElement("button");
table.appendChild(holder);
holder.appendChild(row).textContent = nameInput.value;
holder.appendChild(row.cloneNode(true)).textContent = dateInput.value;
holder.appendChild(row.cloneNode(true)).textContent = amountInput.value;
holder.appendChild(btnRow);
btnRow.appendChild(removeButton).textContent = "REMOVE ENTRY";
// REMOVE THE EXPENSE
removeButton.addEventListener("click", function() {
holder.remove();
});
});
.container {
text-align: center;
}
h1 {
font-size: 3.5em;
}
h2 {
font-size: 2em;
margin-bottom: 0.5em;
color: green;
}
span {
font-size: 1.4em;
}
.date-amount-input {
margin-top: 0.5em;
}
input {
height: 28px;
}
.name {
padding-right: 5em;
}
.amount {
padding-right: 15.35em;
}
.amount-text {
margin-left: 0.4em;
}
.date {
padding-right: 18.8em;
}
.add-btn {
margin-top: 0.9em;
padding: 0.6em;
font-size: 1.1em;
background: green;
color: white;
border: none;
border-radius: 5px;
}
.add-btn:hover, .add-btn:focus {
cursor: pointer;
background: rgb(3, 177, 3);
}
table {
margin: 0 auto;
margin-top: 2em;
width: 50%;
height: 80px;
}
tr {
height: 40px;
}
table, th, td{
border: 1px solid rgba(0, 0, 0, 0.103);
border-collapse: collapse;
}
.empty-text {
font-size: 0.93em;
}
tr.if-empty {
background: rgba(0, 0, 0, 0.055);
display: none;
}
tr:last-child.if-empty {
display: table-row;
}
<body>
<div class="container">
<h1>Expense Tracker</h1>
<h2>Add A New Item</h2>
<div class="name-input">
<span class="name-text">Name: </span>
<input type="text" class="name" placeholder="Where was the expense made" size="117">
</div>
<div class="date-amount-input">
<span>Date: </span>
<input class="date" type="date">
<span class="amount-text">Amount: </span>
<input class="amount" type="text">
</div>
<button class="add-btn">Add Expense</button>
<table>
<tbody>
<tr>
<th>Name</th>
<th>Date</th>
<th>Amount</th>
</tr>
<tr class="if-empty">
<td colspan = "4">
<span class="empty-text">No expenses added yet!</span>
</td>
</tr>
</tbody>
</table>
</div>
<script src="main.js"></script>
</body>
Method 3
Instead of deleting the element from page, you can simply hide it with CSS.
Add following class in CSS:
.hide{ display: none; }
Now, create a function in JavaScript that checks if the table if Empty excluding header row and ifEmpty row:
let toggleIfEmpty = () => { if(table.getElementsByTagName('tr').length <= 2){ ifEmpty.classList.remove("hide"); } else { ifEmpty.classList.add("hide"); } };
Call this function on eventListener:
removeButton.addEventListener("click", function() { holder.remove(); toggleIfEmpty(); });
Then call the function again instead of appending the child element:
Do this: toggleIfEmpty();
Instead of:
if (!table.contains(holder)) { table.appendChild(ifEmpty); }
It will work.
Full updated JS for your reference:
let nameInput = document.querySelector(".name"); let dateInput = document.querySelector(".date"); let amountInput = document.querySelector(".amount"); let button = document.querySelector(".add-btn"); let ifEmpty = document.querySelector(".if-empty"); let table = document.querySelector("table"); let toggleIfEmpty = () => { if(table.getElementsByTagName('tr').length <= 2){ ifEmpty.classList.remove("hide"); } else { ifEmpty.classList.add("hide"); } }; button.addEventListener("click", function() { // CREATE THE EXPENSE let holder = document.createElement("tr"); let row = document.createElement("td"); let btnRow = document.createElement("td"); let removeButton = document.createElement("button"); table.appendChild(holder); holder.appendChild(row).textContent = nameInput.value; holder.appendChild(row.cloneNode(true)).textContent = dateInput.value; holder.appendChild(row.cloneNode(true)).textContent = amountInput.value; holder.appendChild(btnRow); btnRow.appendChild(removeButton).textContent = "REMOVE ENTRY"; // REMOVE THE EXPENSE removeButton.addEventListener("click", function() { holder.remove(); toggleIfEmpty(); }); /* TRIED THIS TO MAKE THE ELEMENT RE-APPEAR IF THE TABLE IS EMPTY BUT IT DIDN'T WORK */ /* if (!table.contains(holder)) { table.appendChild(ifEmpty); } */ toggleIfEmpty(); });
Method 4
You can do something like this, inside of the eventListener for the remove entry
button you can check if the number of children elements inside the table is less than or equal to 1 (including the name date and amount element) in that case there will be no entries, and you can append the message.
In this solution, im creating a placeholder for the “no entries” message, and creating that everytime the message has to be appended, you could use the display property of an element to hide or show it accordingly instead of creating a new element for each session
let nameInput = document.querySelector(".name");
let dateInput = document.querySelector(".date");
let amountInput = document.querySelector(".amount");
let button = document.querySelector(".add-btn");
let ifEmpty = document.querySelector(".if-empty");
let table = document.querySelector("table");
const emptyMessage = ifEmpty;
button.addEventListener("click", function() {
ifEmpty.remove();
// CREATE THE EXPENSE
let holder = document.createElement("tr");
let row = document.createElement("td");
let btnRow = document.createElement("td");
let removeButton = document.createElement("button");
// REMOVE THE EXPENSE
removeButton.addEventListener("click", function() {
holder.remove();
if (table.children.length <= 1) table.appendChild(emptyMessage)
});
table.appendChild(holder);
holder.appendChild(row).textContent = nameInput.value;
holder.appendChild(row.cloneNode(true)).textContent = dateInput.value;
holder.appendChild(row.cloneNode(true)).textContent = amountInput.value;
holder.appendChild(btnRow);
btnRow.appendChild(removeButton).textContent = "REMOVE ENTRY";
// TRIED THIS BUT IT DIDN'T WORK
});
.container {
text-align: center;
}
h1 {
font-size: 3.5em;
}
h2 {
font-size: 2em;
margin-bottom: 0.5em;
color: green;
}
span {
font-size: 1.4em;
}
.date-amount-input {
margin-top: 0.5em;
}
input {
height: 28px;
}
.name {
padding-right: 5em;
}
.amount {
padding-right: 15.35em;
}
.amount-text {
margin-left: 0.4em;
}
.date {
padding-right: 18.8em;
}
.add-btn {
margin-top: 0.9em;
padding: 0.6em;
font-size: 1.1em;
background: green;
color: white;
border: none;
border-radius: 5px;
}
.add-btn:hover, .add-btn:focus {
cursor: pointer;
background: rgb(3, 177, 3);
}
table {
margin: 0 auto;
margin-top: 2em;
width: 50%;
height: 80px;
}
tr {
height: 40px;
}
table, th, td{
border: 1px solid rgba(0, 0, 0, 0.103);
border-collapse: collapse;
}
.empty-text {
font-size: 0.93em;
}
.if-empty {
background: rgba(0, 0, 0, 0.055);
}
<body>
<div class="container">
<h1>Expense Tracker</h1>
<h2>Add A New Item</h2>
<div class="name-input">
<span class="name-text">Name: </span>
<input type="text" class="name" placeholder="Where was the expense made" size="117">
</div>
<div class="date-amount-input">
<span>Date: </span>
<input class="date" type="date">
<span class="amount-text">Amount: </span>
<input class="amount" type="text">
</div>
<button class="add-btn">Add Expense</button>
<table>
<tr>
<th>Name</th>
<th>Date</th>
<th>Amount</th>
</tr>
<tr class="if-empty">
<td colspan = "4">
<span class="empty-text">No expenses added yet!</span>
</td>
</tr>
</table>
</div>
<script src="main.js"></script>
</body>
Using display property method
replace ifEmpty.remove()
with ifEmpty.style.display = 'none
to hide it and replace table.appendChild(emptyMessage)
with ifEmpty.style.display = 'table-row
to show it again
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0