Home > Mobile >  How can I make an element re-appear?
How can I make an element re-appear?

Time:11-03

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.

enter image description here

enter image description here

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?

enter image description here

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>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

I am still a beginner in JS, so any tips will be aprecitated.

CodePudding user response:

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

CodePudding user response:

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();
    });

CodePudding user response:

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>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

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>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

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

  • Related