Кнопки Не Работают При Добавлении Строк Таблицы


У меня есть таблица со столбцом, в котором есть 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);
        }
    }
});
});
Author: Rataiczak24, 2016-10-04

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

Пожалуйста, еще раз проверьте мой кодовый код
Теперь он работает (только для кнопки Деактивировать/Активировать)
Вы можете применить ту же логику для кнопки Редактирования...
;)

 2
Author: Louys Patrice Bessette, 2016-10-04 16:49:03

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;
});
});
 0
Author: Veer, 2016-10-04 15:21:56

Использовать код

 $(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);
    }
}
});
 0
Author: Veer, 2016-10-04 15:30:38

Основная причина, по которой вновь добавленные строки не отвечают методам edit и deactivate, заключается в том, что они были созданы динамически и, следовательно, не были привязаны к первоначально объявленным событиям onclick, как и другие. Возможно, вам придется просто прикрепить эти события после создания строк. Приведенный ниже фрагмент кода пытается проиллюстрировать, как это сделать.

Примечание:
Приведенный ниже фрагмент кода объединяет весь ваш код Javascript с помощью метода jQuery ready, так как в этом не было бы необходимости иметь отдельные методы 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>
 0
Author: Poiz, 2016-10-04 16:43:52

Попробуйте использовать идентификатор вместо класса , например:

<td><button class="edit" id="edit" name="edit">Edit</button>
        <button class="deactivate" id="deactivate" name="deactivate">Deactivate</button></td>

И в jQuery замените ".редактировать" на "#редактировать" и ".деактивировать" на "#деактивировать".

 -1
Author: KatharaDarko, 2016-10-04 15:05:01