Кнопки Не Работают При Добавлении Строк Таблицы
У меня есть таблица со столбцом, в котором есть 2 кнопки, редактировать и деактивировать. Оба функционируют идеально. Однако у меня также есть кнопка за пределами таблицы, которая добавляет строку в таблицу. Во всех добавленных строках ни моя кнопка редактирования, ни кнопка деактивации вообще не работают. Как мне это исправить?
HTML/PHP:
<table id="html_master">
<thead>
<tr>
<td>ID</td>
<td>Vendor</td>
<td>Buyer ID</td>
<td>POC Name</td>
<td>POC Email</td>
<td>POC Phone</td>
<td>Edit/Delete</td>
</tr>
</thead>
<tbody>
<?php
foreach ($dbh->query($sql) as $rows){
?>
<tr>
<td class="mr_id" contenteditable="false"><?php echo intval ($rows['MR_ID'])?></td>
<td class="mr_name" contenteditable="false"><?php echo $rows['MR_Name']?></td>
<td class="buyer_id" contenteditable="false"><?php echo $rows['Buyer_ID']?></td>
<td class="poc_n" contenteditable="false"><?php echo $rows['MR_POC_N']?></td>
<td class="poc_e" contenteditable="false"><?php echo $rows['MR_POC_E']?></td>
<td class="poc_p" contenteditable="false"><?php echo $rows['MR_POC_P']?></td>
<td><button class="edit" name="edit">Edit</button>
<button class="deactivate" name="deactivate">Deactivate</button></td>
</tr>
<?php
}
?>
</tbody>
<br>
<input type="button" class="add" value="Add Row" onclick="addRow('html_master')">
</table>
JavaScript:
// ----- Deactivate Row -----
$(document).ready(function() {
$('.deactivate').click(function() {
var $this = $(this);
var $tr = $this.closest('tr');
var action = $tr.hasClass('deactivated') ? 'activate' : 'deactivate';
if (confirm('Are you sure you want to ' + action + ' this entry?')) {
$tr.toggleClass('deactivated');
$this.text(function(i, t) {
return t == 'Deactivate' ? 'Activate' : 'Deactivate';
});
}
})
});
// ----- Add Row -----
function addRow(tableID) {
var table = document.getElementById(tableID);
var rowCount = table.rows.length;
var row = table.insertRow(rowCount);
var cell1 = row.insertCell(0);
cell1.innerHTML = rowCount;
var cell2 = row.insertCell(1);
var element2 = document.createElement("input");
element2.type = "text";
element2.name = "txtbox[]";
cell2.appendChild(element2);
var cell3 = row.insertCell(2);
var element3 = document.createElement("input");
element3.type = "text";
element3.name = "txtbox[]";
cell3.appendChild(element3);
var cell4 = row.insertCell(3);
var element4 = document.createElement("input");
element4.type = "text";
element4.name = "txtbox[]";
cell4.appendChild(element4);
var cell5 = row.insertCell(4);
var element5 = document.createElement("input");
element5.type = "text";
element5.name = "txtbox[]";
cell5.appendChild(element5);
var cell6 = row.insertCell(5);
var element6 = document.createElement("input");
element6.type = "text";
element6.name = "txtbox[]";
cell6.appendChild(element6);
var cell7 = row.insertCell(6);
var element7 = document.createElement("input");
var element8 = document.createElement("input");
element7.type = "button";
element8.type = "button";
element7.name="edit";
element8.name="deactivate";
element7.value="Edit";
element8.value="Deactivate";
cell7.appendChild(element7);
cell7.appendChild(element8);
}
$(document).ready(function() {
$('.edit').click(function() {
var $this = $(this);
var tds = $this.closest('tr').find('td').not('.mr_id').filter(function() {
return $(this).find('.edit').length === 0;
});
if ($this.html() === 'Edit') {
$this.html('Save');
tds.prop('contenteditable', true);
} else {
var isValid = true;
var errors = '';
$('#myDialogBox').empty();
tds.each(function(){
var type = $(this).attr('class');
var value = $(this).text();
switch(type){
case "buyer_id":
if(!$.isNumeric(value)){
isValid = false;
errors += "Please enter a valid Buyer ID\n";
}
break;
case "poc_n":
if(value == value.match(/^[a-zA-Z\s]+$/)){
break;
}
else {
isValid = false;
errors += "Please enter a valid Name\n";
}
break;
case "poc_e":
if(value == value.match(/^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/)){
break;
}
else {
isValid = false;
errors += "Please enter a valid Email\n";
}
break;
case "poc_p":
if(value == value.match('^[0-9 ()+/-]{10,}$')){
break;
}
else {
isValid = false;
errors += "Please enter a valid Phone Number\n";
}
break;
}
})
if(isValid){
$this.html('Edit');
tds.prop('contenteditable', false);
}else{
alert(errors);
}
}
});
});
5 answers
Динамически добавляемые кнопки ни к чему не привязаны.
Решение состоит в том, чтобы сделать ваши привязки onload функцией, которую вы можете вызвать в любое время...
function bindDeactivate() {
$('.deactivate').click(function() {
var $this = $(this);
var $tr = $this.closest('tr');
var action = $tr.hasClass('deactivated') ? 'activate' : 'deactivate';
if (confirm('Are you sure you want to ' + action + ' this entry?')) {
$tr.toggleClass('deactivated');
$this.text(function(i, t) {
return t == 'Deactivate' ? 'Activate' : 'Deactivate';
});
}
});
}
Привязать кнопку при загрузке.
$(document).ready(function() {
// Bind the deactivate button click to the function
bindDeactivate();
});
В конце функции добавления строки свяжите кнопку.
function addRow(tableID) {
// Skipped a couple lines...
cell7.appendChild(element7);
cell7.appendChild(element8);
// Bind this new deactivate button click to the function
bindDeactivate();
}
Вы сможете сделать то же самое для кнопки редактирования...
;)
РЕДАКТИРОВАТЬ
У вас была еще одна проблема.
Ваша динамически добавляемая кнопка не имеет связанные классы.
Добавьте это в свой function addRow(tableID)
, чтобы добавить класс к кнопке Деактивировать.
var setClass = document.createAttribute("class");
setClass.value = "deactivate";
element8.setAttributeNode(setClass);
Сделайте то же самое для кнопки редактирования.
Смотрите мой Кодовая ссылка здесь.
РЕДАКТИРОВАТЬ
Хорошо... Еще одна проблема, с которой вы столкнулись:
В вашем исходном HTML кнопки являются тегами <button>
.
В то время как динамически добавляемые <input type="button">
Это приводит к тому, что $this.text(function(i, t) {
не работает над <input type="button">
.
Я изменил их на <input type="button">
в вашем HTML.
И изменил $this.text(function(i, t) {
для $this.val(function(i, t) {
Я также улучшил "эффект двойного щелчка", сняв привязку перед повторной привязкой... В конце функции addRow(tableID)
.
// Bind this new deactivate button click to the function
$('#html_master').off("click",'.deactivate');
bindDeactivate();
Пожалуйста, еще раз проверьте мой кодовый код
Теперь он работает (только для кнопки Деактивировать/Активировать)
Вы можете применить ту же логику для кнопки Редактирования...
;)
Bocz вы привязываете событие при загрузке, чтобы оно работало для существующей строки данных, но недавно добавленная строка не имеет привязки, попробуйте ниже код для привязки события.
$(document).on('click','.deactivate',function() {
var $this = $(this);
var $tr = $this.closest('tr');
var action = $tr.hasClass('deactivated') ? 'activate' : 'deactivate';
if (confirm('Are you sure you want to ' + action + ' this entry?')) {
$tr.toggleClass('deactivated');
$this.text(function(i, t) {
return t == 'Deactivate' ? 'Activate' : 'Deactivate';
});
}
});
И для редактирования
$(document).on('click','.edit',function() {
var $this = $(this);
var tds = $this.closest('tr').find('td').not('.mr_id').filter(function() {
return $(this).find('.edit').length === 0;
});
});
Использовать код
$(document).on('click','.deactivate',function() {
var $this = $(this);
var $tr = $this.closest('tr');
var action = $tr.hasClass('deactivated') ? 'activate' : 'deactivate';
if (confirm('Are you sure you want to ' + action + ' this entry?')) {
$tr.toggleClass('deactivated');
$this.text(function(i, t) {
return t == 'Deactivate' ? 'Activate' : 'Deactivate';
});
}
});
$(document).on('click','.edit',function() {
var $this = $(this);
var tds = $this.closest('tr').find('td').not('.mr_id').filter(function() {
return $(this).find('.edit').length === 0;
});
if ($this.html() === 'Edit') {
$this.html('Save');
tds.prop('contenteditable', true);
} else {
var isValid = true;
var errors = '';
$('#myDialogBox').empty();
tds.each(function(){
var type = $(this).attr('class');
var value = $(this).text();
switch(type){
case "buyer_id":
if(!$.isNumeric(value)){
isValid = false;
errors += "Please enter a valid Buyer ID\n";
}
break;
case "poc_n":
if(value == value.match(/^[a-zA-Z\s]+$/)){
break;
}
else {
isValid = false;
errors += "Please enter a valid Name\n";
}
break;
case "poc_e":
if(value == value.match(/^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/)){
break;
}
else {
isValid = false;
errors += "Please enter a valid Email\n";
}
break;
case "poc_p":
if(value == value.match('^[0-9 ()+/-]{10,}$')){
break;
}
else {
isValid = false;
errors += "Please enter a valid Phone Number\n";
}
break;
}
})
if(isValid){
$this.html('Edit');
tds.prop('contenteditable', false);
}else{
alert(errors);
}
}
});
Основная причина, по которой вновь добавленные строки не отвечают методам
edit
иdeactivate
, заключается в том, что они были созданы динамически и, следовательно, не были привязаны к первоначально объявленным событиямonclick
, как и другие. Возможно, вам придется просто прикрепить эти события после создания строк. Приведенный ниже фрагмент кода пытается проиллюстрировать, как это сделать.
Примечание:
Приведенный ниже фрагмент кода объединяет весь ваш код Javascript с помощью метода jQueryready
, так как в этом не было бы необходимости иметь отдельные методыready
в одном скрипте. Во-вторых, для создания новой строки использовался Jquery (а не необработанный Javascript). Просто для простоты.
HTML
<table id="html_master">
<thead>
<tr>
<td>ID</td>
<td>Vendor</td>
<td>Buyer ID</td>
<td>POC Name</td>
<td>POC Email</td>
<td>POC Phone</td>
<td>Edit/Delete</td>
</tr>
</thead>
<tbody>
<?php
foreach ($dbh->query($sql) as $rows){
?>
<tr>
<td class="mr_id" contenteditable="false"><?php echo intval ($rows['MR_ID'])?></td>
<td class="mr_name" contenteditable="false"><?php echo $rows['MR_Name']?></td>
<td class="buyer_id" contenteditable="false"><?php echo $rows['Buyer_ID']?></td>
<td class="poc_n" contenteditable="false"><?php echo $rows['MR_POC_N']?></td>
<td class="poc_e" contenteditable="false"><?php echo $rows['MR_POC_E']?></td>
<td class="poc_p" contenteditable="false"><?php echo $rows['MR_POC_P']?></td>
<td><button class="edit" name="edit">Edit</button>
<button class="deactivate" name="deactivate">Deactivate</button></td>
</tr>
<?php
}
?>
</tbody>
</table>
<div class="add-button-wrapper">
<input type="button" class="add" value="Add Row" id="rowAdder">
</div>
JAVASCRIPT: JQUERY
<script type="text/javascript">
$(document).ready(function() {
var rowAdder = $("#rowAdder");
var editButton = $(".edit");
var deActivator = $('.deactivate');
/* EVENT BINDINGS & HANDLING*/
// BIND THE CLICK ACTION TO DEACTIVATION HANDLER
deActivator.click(deactivate);
// BIND THE CLICK EVENT TO THE EDITING HANDLER:
editButton.click(handleEdit);
// BIND THE CLICK ACTION TO THE NEW-ROW PROCESSING HANDLER:
rowAdder.click(addRow);
/* CALL-BACK FUNCTIONS:*/
// HANDLE THE EDITING
function handleEdit(evt) {
var $this = $(this);
var tds = $this.closest('tr').find('td').not('.mr_id').filter(function() {
return $(this).find('.edit').length === 0;
});
if ($this.html() === 'Edit') {
$this.html('Save');
tds.prop('contenteditable', true);
} else {
var isValid = true;
var errors = '';
$('#myDialogBox').empty();
tds.each(function(){
var type = $(this).attr('class');
var value = $(this).text();
switch(type){
case "buyer_id":
if(!$.isNumeric(value)){
isValid = false;
errors += "Please enter a valid Buyer ID\n";
}
break;
case "poc_n":
if(value == value.match(/^[a-zA-Z\s]+$/)){
break;
}
else {
isValid = false;
errors += "Please enter a valid Name\n";
}
break;
case "poc_e":
if(value == value.match(/^[\w\-\.\+]+\@[a-zA-Z0-9\.\-]+\.[a-zA-z0-9]{2,4}$/)){
break;
}
else {
isValid = false;
errors += "Please enter a valid Email\n";
}
break;
case "poc_p":
if(value == value.match('^[0-9 ()+/-]{10,}$')){
break;
}
else {
isValid = false;
errors += "Please enter a valid Phone Number\n";
}
break;
}
})
if(isValid){
$this.html('Edit');
tds.prop('contenteditable', false);
}else{
alert(errors);
}
}
}
// HANDLE DEACTIVATION
function deactivate(evt) {
var $this = $(this);
var $tr = $this.closest('tr');
var action = $tr.hasClass('deactivated') ? 'activate' : 'deactivate';
if (confirm('Are you sure you want to ' + action + ' this entry?')) {
$tr.toggleClass('deactivated');
$this.text(function(i, t) {
return t == 'Deactivate' ? 'Activate' : 'Deactivate';
});
}
}
// ADD NEW ROW
function addRow(evt) {
var table = $("#html_master");
var rows = table.children("tr");
var rowCount = rows.length;
var row = table.insertRow(rowCount);
// SIMPLY CREATE A NEW ROW OBJECT AND APPEND IT TO THE rows VARIABLE.
var newRow = "<tr>";
newRow += "<td class='mr_id' contenteditable='false'>" + rowCount + "</td>";
newRow += "<td class='buyer_id' contenteditable='false'><input type='text' name='txtbox[]' />" + "</td>";
newRow += "<td class='poc_n' contenteditable='false'><input type='text' name='txtbox[]' />" + "</td>";
newRow += "<td class='poc_e' contenteditable='false'><input type='text' name='txtbox[]' />" + "</td>";
newRow += "<td class='poc_p' contenteditable='false'><input type='text' name='txtbox[]' />" + "</td>";
newRow += "<td class='mr_id' contenteditable='false'><input type='text' name='txtbox[]' />" + "</td>";
newRow += "<td class='mr_id' contenteditable='false'>";
newRow += "<button class='edit' name='edit'>Edit</button>";
newRow += "<button class='deactivate' name='deactivate'>Deactivate</button>";
newRow += "</td>";
newRow += "</tr>";
// APPEND THE NEW ROW...
table.append(newRow);
// RE-BIND THE EVENTS ON THE BUTTONS SINCE THESE WERE DYNAMICALLY CREATED
// BIND THE CLICK ACTION TO DEACTIVATION HANDLER
table.find("deactivate").click(deactivate);
// BIND THE CLICK EVENT TO THE EDITING HANDLER:
table.find("edit").click(handleEdit);
}
});
</script>
Попробуйте использовать идентификатор вместо класса , например:
<td><button class="edit" id="edit" name="edit">Edit</button>
<button class="deactivate" id="deactivate" name="deactivate">Deactivate</button></td>
И в jQuery замените ".редактировать" на "#редактировать" и ".деактивировать" на "#деактивировать".