1

I am currently building and invoice creator app as to practice javascript.

My goal is that when the user presses the "remove" button, only the clicked item will be removed from the list.

const theForm = document.getElementById('the-form');
const taskInput = document.getElementById('task-input');
const renderItem = document.querySelector('.render');
const selectOption = document.getElementById('amount');
const totalSum = document.getElementById('total-sum');

let totalAmount = 0;

theForm.addEventListener('submit', function(e) {
  e.preventDefault();
  totalAmount += parseInt(selectOption.value);
  renderItem.innerHTML += `
  <div class="render-item">
    <div class="left-side">
        <h2>${taskInput.value}</h2>
        <button class='remove'>Remove</button>
    </div>
    <h2><span>$</span>${selectOption.value}</h2>
  </div>
  `;

  totalSum.textContent = `$${totalAmount}`;

  taskInput.value = '';
  selectOption.value = '10';

  const removeItem = document.querySelectorAll('.render-item');

  removeItem.forEach((item) => {
    item.addEventListener('click', function() {
      renderItem.innerHTML = '';
      totalAmount = 0;
      totalSum.textContent = '';
    });
  });
});
<div class="outer-container">
  <header>
    <h1>Invoice creator</h1>
    <p>Thanks for choosing RazCorp, LLC!</p>
  </header>

  <main class="inner-container">
    <section class="form-enter">
      <form id="the-form">
        <input type="text" id="task-input" name="task-input" placeholder="Enter task" required />
        <div class="amount-container">
          <label for="amount">$</label>
          <select name="amount" id="amount">
            <option value="10">10</option>
            <option value="20">20</option>
            <option value="30">30</option>
            <option value="40">40</option>
            <option value="50">50</option>
          </select>
        </div>
        <button id="submit-btn" class="submit" type="submit">+</button>
      </form>
    </section>

    <section class="display">
      <div class="task-total">
        <h3>TASK</h3>
        <h3>TOTAL</h3>
      </div>
      <div class="render"></div>
    </section>

    <section class="final-amount">
      <div class="final-left">
        <h3>NOTES</h3>
        <p>We accept cash, credit card, or PayPal</p>
      </div>
      <div class="final-right">
        <h3>TOTAL AMOUNT</h3>
        <h1 id="total-sum"></h1>
      </div>
    </section>
    <button id="send-invoice" class="send-invoice">
          <span><i class="fa-solid fa-envelope"></i></span>Send invoice
        </button>
  </main>
</div>

First I am creating the Html through javascript and then I would like to remove it.

Right now when I press remove, every new created redenerItem is deleted and not just the one being clicked.

Any help appreciated :)

Barmar
  • 741,623
  • 53
  • 500
  • 612
Biobrolly
  • 113
  • 2
  • 12
  • 1
    `renderItem.innerHTML = '';` should be `item.innerHTML = '';` – Barmar Feb 07 '23 at 17:36
  • Every time you add a new task, you're adding another event listener to all the old tasks. You should use event delegation for dynamically-added elements. See https://stackoverflow.com/questions/23508221/vanilla-javascript-event-delegation – Barmar Feb 07 '23 at 17:37

2 Answers2

2

Because you have a single element that you're adding all of the entries to, when you press the remove button and it clears that single element, it clears all of the entries. What you probably want is a system that stores an array of all the items in the list, then selectively removing them. You might be able to use this:

const theForm = document.getElementById('the-form');
const taskInput = document.getElementById('task-input');
const selectOption = document.getElementById('amount');
const totalSum = document.getElementById('total-sum');
const renderItems = document.querySelector('.render');
const listItems = [];

let totalAmount = 0;

theForm.addEventListener('submit', function (e) {
  e.preventDefault();
  totalAmount += parseInt(selectOption.value);
  //The Array.push method returns the new length of the array that we can use to get the item position
  let itemPos = listItems.push(document.createElement('div')) - 1;
  listItems[itemPos].innerHTML = `
  <div class="left-side">
      <h2>${taskInput.value}</h2>
      <button class='remove' onclick='removeItem(${itemPos}, ${selectOption.value})'>Remove</button>
  </div>
  <h2><span>$</span>${selectOption.value}</h2>
  `;
  renderItems.appendChild(listItems[itemPos]);

  totalSum.textContent = `$${totalAmount}`;

  taskInput.value = '';
  selectOption.value = '10';
});

//Move the remove item functionality to a new function
function removeItem(index, value) {
  listItems[index].remove(); //Remove the element from the DOM
  listItems.splice(index, 1); //Remove the element from the array
  totalAmount -= value;
  totalSum.textContent = `$${totalAmount}`;
}
<div class="outer-container">
  <header>
    <h1>Invoice creator</h1>
    <p>Thanks for choosing RazCorp, LLC!</p>
  </header>

  <main class="inner-container">
    <section class="form-enter">
      <form id="the-form">
        <input type="text" id="task-input" name="task-input" placeholder="Enter task" required />
        <div class="amount-container">
          <label for="amount">$</label>
          <select name="amount" id="amount">
            <option value="10">10</option>
            <option value="20">20</option>
            <option value="30">30</option>
            <option value="40">40</option>
            <option value="50">50</option>
          </select>
        </div>
        <button id="submit-btn" class="submit" type="submit">+</button>
      </form>
    </section>

    <section class="display">
      <div class="task-total">
        <h3>TASK</h3>
        <h3>TOTAL</h3>
      </div>
      <div class="render"></div>
    </section>

    <section class="final-amount">
      <div class="final-left">
        <h3>NOTES</h3>
        <p>We accept cash, credit card, or PayPal</p>
      </div>
      <div class="final-right">
        <h3>TOTAL AMOUNT</h3>
        <h1 id="total-sum"></h1>
      </div>
    </section>
    <button id="send-invoice" class="send-invoice">
          <span><i class="fa-solid fa-envelope"></i></span>Send invoice
        </button>
  </main>
</div>
EpicPuppy613
  • 301
  • 1
  • 13
  • Thank you so much! This makes perfect sense. I will have to have a good look on that. So much to learn yet. – Biobrolly Feb 07 '23 at 17:40
-2

const theForm = document.getElementById('the-form');
const taskInput = document.getElementById('task-input');
const renderItem = document.querySelector('.render');
const selectOption = document.getElementById('amount');
const totalSum = document.getElementById('total-sum');

let totalAmount = 0;

theForm.addEventListener('submit', function(e) {
  e.preventDefault();
  totalAmount += parseInt(selectOption.value);
  renderItem.innerHTML += `
  <div class="render-item">
    <div class="left-side">
        <h2>${taskInput.value}</h2>
        <button class='remove'>Remove</button>
    </div>
    <h2><span>$</span>${selectOption.value}</h2>
  </div>
  `;

  totalSum.textContent = `$${totalAmount}`;

  taskInput.value = '';
  selectOption.value = '10';

  const removeItem = document.querySelectorAll('.render-item');

  removeItem.forEach((item) => {
    item.addEventListener('click', function() {
      this.remove();

      /*totalAmount = 0;
      totalSum.textContent = '';*/
    });
  });
});
<div class="outer-container">
  <header>
    <h1>Invoice creator</h1>
    <p>Thanks for choosing RazCorp, LLC!</p>
  </header>

  <main class="inner-container">
    <section class="form-enter">
      <form id="the-form">
        <input type="text" id="task-input" name="task-input" placeholder="Enter task" required />
        <div class="amount-container">
          <label for="amount">$</label>
          <select name="amount" id="amount">
            <option value="10">10</option>
            <option value="20">20</option>
            <option value="30">30</option>
            <option value="40">40</option>
            <option value="50">50</option>
          </select>
        </div>
        <button id="submit-btn" class="submit" type="submit">+</button>
      </form>
    </section>

    <section class="display">
      <div class="task-total">
        <h3>TASK</h3>
        <h3>TOTAL</h3>
      </div>
      <div class="render"></div>
    </section>

    <section class="final-amount">
      <div class="final-left">
        <h3>NOTES</h3>
        <p>We accept cash, credit card, or PayPal</p>
      </div>
      <div class="final-right">
        <h3>TOTAL AMOUNT</h3>
        <h1 id="total-sum"></h1>
      </div>
    </section>
    <button id="send-invoice" class="send-invoice">
          <span><i class="fa-solid fa-envelope"></i></span>Send invoice
        </button>
  </main>
</div>

your event listener is already on the render-item, so just remove the element clicked.

now you will have the problem to update the amount and the text of 0.

you should add a class for the amount of each render-item, actually the amount is after the span that's it. If you have a class "render-item-amount" it would be easier at each update to modify the total

pier farrugia
  • 1,520
  • 2
  • 2
  • 9