Как сделать кнопку удаления для удаления элемента, к которому он принадлежит, из списка?

Извините за мой английский. У меня есть множество элементов, которые отображаются на моей веб-странице. У каждого элемента есть кнопка удаления, но как я могу привязать нажатие кнопки к элементу, которому он (кнопка) принадлежит? Я имею в виду: как мне удалить именно тот элемент, какую кнопку я нажал? Нужно ли мне добавлять идентификаторы к моим предметам, и если да, то как я могу это сделать? Желательно без сервера и React, только JS. Ждем вашей помощи!

Из моего CodePen

HTML

<section class = "main">
  <div class = "container">
    <h1 class = "mb-3">Details storage</h2>
    <form class = "mb-3" action = "" id = "add-detail">
      <div class = "mb-3">
        <input required class='form-control' type = "number" placeholder = "Detail Code" id = "input-key">
        </div>
      <div class = "mb-3">
        <input required class='form-control' type = "text" placeholder = "Category" id = "input-category">
        </div>
      <div class = "mb-3">
        <input required class='form-control' type = "number" placeholder = "Amount" id = "input-amount">
      </div>
      <div class = "mb-3">
        <input required class='form-control' type = "number" placeholder = "Price per piece" id = "input-price">
        </div>
      <button class='btn btn-primary'>Add</button>
    </form>
    <table class = "table table-striped detailsTable">
      <thead>
      <th data-column = "key">Detail Code</th>
      <th data-column = "category">Category</th>
      <th data-column = "amount">Amount</th>
      <th data-column = "price">Price per piece</th>
      <th data-column = "totalPrice">Total amount</th> 
      <th></th>
      </thead>
      <tbody id = "details-list">
      </tbody>
    </table>
  </div> 
</section>

JS

class Detail {
  constructor(key, category, amount, price) {
    this.key=key
    this.category=category
    this.amount=amount
    this.price=price
  }
  get totalPrice() {
    return (this.amount * this.price);
}
}

const details=[
  new Detail(0,'Nails',300,4),
  new Detail(1,'Screws',400,6),
  new Detail(2,'Bolts',600,5),
  new Detail(3,'Self-tapping screw',700,3),
  new Detail(4,'Nails', 400, 2)
]

const $detailsList = document.getElementById('details-list'),
      $detailsListTHALL = document.querySelectorAll('.detailsTable th')

let column = 'key',
    columnDir = true

function newDetailTR(detail){
  const $detailTR= document.createElement('tr'),
        $keyTD= document.createElement('td'),
        $categoryTD= document.createElement('td'),
        $amountTD= document.createElement('td'),
        $priceTD= document.createElement('td'),
        $totalPriceTD=document.createElement('td'),
        $deleteTD=document.createElement('button')
  
  $keyTD.textContent=detail.key
  $categoryTD.textContent=detail.category
  $amountTD.textContent=detail.amount
  $priceTD.textContent=detail.price
  $totalPriceTD.textContent = detail.totalPrice
  $deleteTD.textContent = "Delete"
  
  $detailTR.append($keyTD)
  $detailTR.append($categoryTD)
  $detailTR.append($amountTD)
  $detailTR.append($priceTD)
  $detailTR.append($totalPriceTD)
  $detailTR.append($deleteTD)
  
  return $detailTR;
}


function getSortDetails(prop, dir) {
  const detailsCopy=[...details]
  return detailsCopy.sort(function(detailA, detailB){
    if ((!dir==false? detailA[prop] <detailB[prop] : detailA[prop] > detailB[prop])) return -1;
  })
}

function render(){
  let detailsCopy=[...details];
  
  detailsCopy=getSortDetails(column, columnDir);
  
  $detailsList.innerHTML = '';
  for(const detail of detailsCopy){
    $detailsList.append(newDetailTR(detail))
  }
}


$detailsListTHALL.forEach(elment => {
  elment.addEventListener('click', function() {
    column = this.dataset.column;
    columnDir = !columnDir;
    render()
  })
})


document.getElementById('add-detail').addEventListener('submit', function(event){
  event.preventDefault()
  details.push(new Detail(
    Number(document.getElementById('input-key').value),
    document.getElementById('input-category').value,
    Number(document.getElementById('input-amount').value),
    Number(document.getElementById('input-price').value)
  ))
  
  render()
  alert('Item has been added!')
  event.preventDefault();
  event.target.reset(); 
})

render()

попробуйте добавить обработчик событий click к $deleteTD, который вы создали динамически для каждой строки. Затем внутри обратного вызова события, учитывая его подпись как (event)=>{...}, вы можете определить родителя нажатой кнопки удаления, выполнив event.target.closest('tr')

Diego D 02.05.2024 10:25
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
67
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Когда вы создаете элемент TR, назначьте ему щелчок; в основном так (с использованием многократно используемой функции elNew для создания новых элементов DOM):

const $detailTR = elNew('tr')
const $deleteButton = elNew('button', {
  textContent: "Delete",
  onclick() {
    removeDetail(detail); // Remove from array
    $detailTR.remove();   // Remove from HTML
  }
});

также не забудьте:

  • создайте оболочку TD для вашей кнопки удаления
  • не клонируйте свои массивы, иначе вы не сможете отслеживать индекс элемента, который нужно удалить (после сортировки массива).

Пример:

// DOM utility functions:
const el = (sel, par = document) => par.querySelector(sel);
const els = (sel, par = document) => par.querySelectorAll(sel);
const elNew = (tag, prop) => Object.assign(document.createElement(tag), prop);

class Detail {
  constructor(key, category, amount, price) {
    this.key = key;
    this.category = category;
    this.amount = amount;
    this.price = price;
  }
  get totalPrice() {
    return (this.amount * this.price);
  }
}

const details = [
  new Detail(0, 'Nails', 300, 4),
  new Detail(1, 'Screws', 400, 6),
  new Detail(2, 'Bolts', 600, 5),
  new Detail(3, 'Self-tapping screw', 700, 3),
  new Detail(4, 'Wheels', 400, 2),
];

const $detailsList = el('#details-list');
const $detailsListTHALL = els('.detailsTable th');

let column = 'key';
let columnDir = true;

function removeDetail(detail) {
  const index = details.indexOf(detail);
  if (index > -1) details.splice(index, 1);
}

function newDetailTR(detail) {
  const $detailTR = elNew('tr'),
        $keyTD = elNew('td', { textContent: detail.key }),
        $categoryTD = elNew('td', { textContent: detail.category }),
        $amountTD = elNew('td', { textContent: detail.amount }),
        $priceTD = elNew('td', { textContent: detail.price }),
        $totalPriceTD = elNew('td', { textContent: detail.totalPrice }),
        $deleteTD = elNew('td'),
        $deleteButton = elNew('button', {
          textContent: "Delete",
          onclick() {
            removeDetail(detail); // Remove from array
            $detailTR.remove();   // Remove from HTML
          }
        });
  $deleteTD.append($deleteButton);
  $detailTR.append($keyTD, $categoryTD, $amountTD, $priceTD, $totalPriceTD, $deleteTD);
  return $detailTR;
}

function getSortDetails(prop, dir) {
  return details.sort(function(a, b) {
    if ((!dir==false? a[prop] < b[prop] : a[prop] > b[prop])) return -1;
  });
}

function render() {
  const detailsCopy = getSortDetails(column, columnDir);
  $detailsList.innerHTML = "";
  details.forEach(detail => $detailsList.append(newDetailTR(detail)));
}

el('#add-detail').addEventListener('submit', function(event){
  event.preventDefault();

  details.push(new Detail(
    el('#input-key').valueAsNumber,
    el('#input-category').value,
    el('#input-amount').valueAsNumber,
    el('#input-price').valueAsNumber
  ));

  render();
  event.target.reset(); 
})

render();
  <section class = "main">
  <div class = "container">
    <h1 class = "mb-3">Details storage</h2>
    <form class = "mb-3" action = "" id = "add-detail">
      <div class = "mb-3">
        <input required class='form-control' type = "number" placeholder = "Detail Code" id = "input-key">
        </div>
      <div class = "mb-3">
        <input required class='form-control' type = "text" placeholder = "Category" id = "input-category">
        </div>
      <div class = "mb-3">
        <input required class='form-control' type = "number" placeholder = "Amount" id = "input-amount">
      </div>
      <div class = "mb-3">
        <input required class='form-control' type = "number" placeholder = "Price per piece" id = "input-price">
        </div>
      <button class='btn btn-primary'>Add</button>
    </form>
    <table class = "table table-striped detailsTable">
      <thead>
        <th data-column = "key">Detail Code</th>
        <th data-column = "category">Category</th>
        <th data-column = "amount">Amount</th>
        <th data-column = "price">Price per piece</th>
        <th data-column = "totalPrice">Total amount</th> 
        <th></th>
      </thead>
      <tbody id = "details-list"></tbody>
    </table>
  </div> 
</section>

Роко К. Бульян, спасибо за помощь!!!

lanamak 02.05.2024 11:38

Другие вопросы по теме