Извините за мой английский. У меня есть множество элементов, которые отображаются на моей веб-странице. У каждого элемента есть кнопка удаления, но как я могу привязать нажатие кнопки к элементу, которому он (кнопка) принадлежит? Я имею в виду: как мне удалить именно тот элемент, какую кнопку я нажал? Нужно ли мне добавлять идентификаторы к моим предметам, и если да, то как я могу это сделать? Желательно без сервера и 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()
Когда вы создаете элемент TR, назначьте ему щелчок; в основном так (с использованием многократно используемой функции elNew
для создания новых элементов DOM):
const $detailTR = elNew('tr')
const $deleteButton = elNew('button', {
textContent: "Delete",
onclick() {
removeDetail(detail); // Remove from array
$detailTR.remove(); // Remove from HTML
}
});
также не забудьте:
Пример:
// 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>
Роко К. Бульян, спасибо за помощь!!!
попробуйте добавить обработчик событий
click
к$deleteTD
, который вы создали динамически для каждой строки. Затем внутри обратного вызова события, учитывая его подпись как(event)=>{...}
, вы можете определить родителя нажатой кнопки удаления, выполнивevent.target.closest('tr')