【问题标题】:Buttons Not Working When Adding Table Rows添加表格行时按钮不起作用
【发布时间】:2017-02-12 18:39:20
【问题描述】:

我有一个表格,其中有一列有 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);
        }
    }
});
});

【问题讨论】:

标签: javascript php jquery html button


【解决方案1】:

动态添加的按钮没有绑定到任何东西。

解决方案是让您的 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);

对编辑按钮执行相同操作。

见我的CodePen here

编辑

好的...您遇到的另一个问题:
在您的初始 HTML 中,按钮是 &lt;button&gt; 标签。
而动态添加的是&lt;input type="button"&gt;

这会导致$this.text(function(i, t) { 无法在&lt;input type="button"&gt; 上工作。

我在您的 HTML 中将它们更改为 &lt;input type="button"&gt;
并将$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();

请再次检查我的codePen
它现在正在工作(仅适用于停用/激活按钮)
您可以对“编辑”按钮应用相同的逻辑...
;)

【讨论】:

  • 那么在加载时绑定按钮的代码......它到底在哪里?并在添加行函数的末尾添加代码....我把它放在函数中,但最后正确吗?
  • 更正«在函数内部但在最后»。对于onload...它在准备好的文档中...所以任何地方都很好。
  • 如果还是不行...(突然有点疑惑)试试$(document).find('.deactivate').click(function() {
  • 等一下...我这边会试试的。
  • 好吧...当我添加一行并单击按钮时,它就可以工作了!但是,现在遇到了一些额外的问题...当我单击按钮时,即使在单击它应该说激活时,文本仍保持停用状态...此外...单击原始行时,它会询问我是否我想停用该行,然后背靠背询问我是否要激活它...
【解决方案2】:

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

【讨论】:

  • 我将两组代码都放入我的脚本中,但它似乎不起作用。添加行功能现在甚至无法使用。
  • 检查右括号。因为我只是复制你的代码。我错过了编辑代码中的右括号。
【解决方案3】:

使用代码

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

【讨论】:

  • 添加这两行 element7.setAttribute("class","edit"); element8.setAttribute("class","deactivate"); bcoz 在您的代码中,您没有将类添加到新按钮。我测试了它对我的工作。
【解决方案4】:

新添加的行不响应editdeactivate 方法的主要原因是因为它们是动态创建的,因此不会像其他事件那样绑定到最初声明的onclick 事件。您可能必须在创建行后简单地附加这些事件。下面的代码 sn-p 试图说明如何。

注意:
下面的 sn-p 结合了 JQuery ready 方法下的所有 Javascript 代码,因为无需在一个脚本中使用单独的 ready 方法。其次,要创建新行,使用 Jquery(而不是使用 Raw 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>

【讨论】:

    【解决方案5】:

    尝试使用 id 而不是 class,例如:

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

    在 jQuery 中,将“.edit”替换为“#edit”,将“.deactivate”替换为“#deactivate”。

    【讨论】:

    • 这不起作用...ID 特定于一个元素....我有多行,所以我很确定这里必须使用 CLASS
    • 也许你可以尝试使用 html 按钮上的 onclick 并使用它来调用 jQuery 中的函数?只是猜测
    • 在一页上所有元素都必须有唯一的ID。那么只有 jquery 了解 eleent 的选择,否则它将始终选择一个(第一个)ID 元素。
    猜你喜欢
    • 2020-09-16
    • 1970-01-01
    • 2019-02-13
    • 1970-01-01
    • 2022-11-05
    • 2021-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多