Rataiczak24 Rataiczak24 - 1 month ago 5
HTML Question

Buttons Not Working When Adding Table Rows

I have a table with a column that has 2 buttons, edit and deactivate. Both function perfectly. However, I also have a button outside of the table that adds a row to the table. On all added rows, neither my edit nor deactivate button work at all. How do I fix this?

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

Answer

The dynamically added buttons are not binded to anything.

The solution is to make your onload bindings a function that you can call anytime...

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

Bind the button on load.

$(document).ready(function() {
    // Bind the deactivate button click to the function
    bindDeactivate();
});

At the end of your add row function, bind the button.

function addRow(tableID) {
    // Skipped a couple lines...

    cell7.appendChild(element7);
    cell7.appendChild(element8);

    // Bind this new deactivate button click to the function
    bindDeactivate();
}

You will be able to do the same for the edit button...
;)

EDIT

You had another problem.
Your dynamically added button do NOT have the associated classes.

Add this to your function addRow(tableID) to add a class to the Deactivate button.

var setClass = document.createAttribute("class");
setClass.value = "deactivate";
element8.setAttributeNode(setClass);

Do the same for the edit button.

See my CodePen here.

EDIT

Okay... Another issue you had:
In your initial HTML, the buttons are <button> tags.
While the dynamically added ones are <input type="button">

This causes $this.text(function(i, t) { to be not working on the <input type="button">.

I changed them for <input type="button"> in your HTML.
And changed $this.text(function(i, t) { for $this.val(function(i, t) {

I also improved the "double click effect" by unbinding before re-bind... At the end of the addRow(tableID) function.

// Bind this new deactivate button click to the function
$('#html_master').off("click",'.deactivate');
bindDeactivate();

Please, re-check my codePen again
It is now working (only for Deactivate/Activate button)
You can apply the same logic for the Edit button...
;)

Comments