0

我有一个烦人的问题,我花了很多时间试图解决,但没有成功。我有一个用于从我们的数据库中删除项目的表单。这是表格: 编辑:我已经将代码更新为更合理的东西,但是我仍然有我的问题。

    <div id="tabs-3">
            <p>Select Replenish for Books that will be for sale again.<br/>Select Remove for Books that will NOT be for sale again.</p>
            <br/>
            <table>
            <tr>
                <td><input type="radio" name="returnType" value="replenish" checked>Replenish<br></td>
                <td><input type="radio" name="returnType" value="remove">Remove<br></td>
            </tr>
            <tr>
                <td>&nbsp</th>
                <td>&nbsp</th>
            </tr>
            <tr>
                <th>SKU</th>
                <th>Order ID</th>
                <th>Quantity</th>
                <th>Location</th>
            </tr>
            <?php $numberofrow = 10;?>
<!--create the for loop-->
<?php for($counter = 1;$counter<=$numberofrow;$counter++){ ?>
<!--create 1 row for repeating-->
            <tr>
                <td><input type="text" id="sku<?php echo   $counter;?>"/></td>
                <td><input type="text" id="order<?php echo $counter;?>"/></td>
                <td><input type="text" id="reEnterQty<?php echo $counter;?>"/></td>
                <td>
                    <select id="reEnterLocation<?php echo $counter;?>" name="reEnterLocation" class="Location">
                        <option value="">--Select Location--</option>
                        <?php
                        $query = "SELECT location_id, location FROM location ORDER BY location";
                        $result = $conn->query($query);
                        while ($row = $result->fetch_assoc()) {
                            echo '<option value="' . $row['location_id'] . '" >' . $row['location'] . '</option>';
                        }
                        ?>
                    </select>
                </td>
            </tr>
            <?php }?>
            </table>
            <br/>


            <br/>
            <input type="button" id="reEnterSKU" value="Process Returns" /> <br/>

            <div id="returnsNotice"></div>
        </div>

处理这个的js是:

        $("#reEnterSKU").on('click', function() {

    if($("input[name=returnType]:checked").val() == "remove"){ //executes when Remove radio button is checked
        var arr = {};
        var counter = 0;

        for(var x=1;x<11;x++)
        {
            if($("#sku"+x).val() != "" && $("#order"+x).val() != ""){
            arr[x] ={sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: $("#reEnterQty"+x).val()};   
            }
        }   
                $.ajax({
                    type: "POST",
                    async:false,
                    url: "invReturnsRemove.php",
                    dataType: "json",
                    data: {data: JSON.stringify(arr)},//({sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: quantity}),
                    success: function(data){

                    }
                });



        $("#returnsNotice").html("<h3>" + x + " return(s) removed.</h3>");

invReturnsRemove.php 是:

    <?php
require_once ('../db.php');
$conn = db_connect();
$n=0;

$data =json_decode($_POST['data'], true); 

foreach($data as $value){

$conn->query("UPDATE order_sold SET quantity = (quantity - {$data[$n]['quantity']}) WHERE sku = {$data[$n]['sku']} AND order_id = {$data[$n]['order']}");
$n++;}


$conn->close();
?>

问题是当我尝试运行它时,即使只删除一条记录,它也会运行数百次。知道我可能做错了什么,以及如何解决吗?

4

2 回答 2

3

您发表的评论表明,至少部分问题出在客户端。

您可能已多次添加'click'事件侦听器。如果您添加事件侦听器的代码在循环中,那么您几乎可以肯定已经添加了多次。例如,如果您在页面上有多个表单并以以下方式附加侦听器,则每次按下提交按钮时都会触发多次。

// THIS IS BAD
$('form').each(function() {
    $("#reEnterSKU").on('click', function(e) {
         // details of listener for form1
    });
    $("#reEnterSKU2").on('click', function(e) {
         // details of listener for form2
    });
    $("#reEnterSKU3").on('click', function(e) {
         // details of listener for form3
    });
});

当您使用与buttonon直接关联的事件侦听器时form,您可能应该return false;从事件侦听器函数或调用e.preventDefault();(您必须将e参数添加到单击侦听器函数)以避免按钮提交form. (也许您已经在做类似的事情但没有包含代码?)我假设您不打算重定向页面,否则您不会更新元素的内容<div id="returnsNotice"></div>

可能导致问题的另一件事是,如果您用于查找和添加单击侦听器到按钮的选择器不够具体。如果是这种情况,您可能一次将事件侦听器添加到多个按钮,因此一个按钮最终可能会包含多个事件侦听器。

此外,在使用表单时,我认为通常最好避免将事件侦听器附加到特定的表单元素,例如按钮,以触发提交,因为在各种提交场景中事情可能会变得复杂,例如当用户enter按下键时而文本输入字段具有焦点。作为替代方案,您可以使用附加到元素的jQuery.submit()form方法,并且应该由任何会导致表单提交的情况触发。这将允许您执行一个函数(提交侦听器)并以更高的可靠性停止自动提交。required当您将属性应用于表单元素时,这也将允许您利用内置的浏览器表单验证功能(细节兼容性)。

$("#your-form-id").submit(function() {

    if($("input[name=returnType]:checked").val() === "remove") { //executes when Remove radio button is checked
        var arr = [];
        var counter = 0;

        for(var x = 1; x < 11; x++)
        {
            if( $("#sku"+x).val() !== "" && $("#order"+x).val() !== ""){
                arr[x] = {
                    sku: $("#sku"+x).val(), 
                    order: $("#order"+x).val(), 
                    quantity: $("#reEnterQty"+x).val()
                };   
            }
        }
        console.log('FORM SUBMIT');

        $.ajax({
            type: "POST",
            async:false,
            url: "invReturnsRemove.php",
            dataType: "json",
            data: {data: JSON.stringify(arr)},//({sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: quantity}),
            success: function(data){
                console.log('SUCCESS'); // how many times do you see this per button click?
            }
        });

        $("#returnsNotice").html("<h3>" + x + " return(s) removed.</h3>");

        // ... anything that remains in your function
        return false;

关于如何解决这个问题,我要做的第一件事是注释掉表单提交语句,以便将其排除在等式之外。然后,在其位置添加一条console.log()语句以查看 a) 如果它被多次调用,并且 b) 尝试弄清楚如果它被多次调用,如何让它只执行一次。您还可以添加在添加单击事件侦听器时console.log()执行的语句,以确保您只添加一个单击事件侦听器。我在下面包含了这些更改。

console.log('ADDING FORM SUBMISSION click listener -- you should only see this once.');

$("#reEnterSKU").on('click', function(e) {

    e.preventDefault();

    if($("input[name=returnType]:checked").val() === "remove") { //executes when Remove radio button is checked
        var arr = [];
        var counter = 0;

        for(var x = 1; x < 11; x++)
        {
            if( $("#sku"+x).val() !== "" && $("#order"+x).val() !== ""){
                arr[x] = {
                    sku: $("#sku"+x).val(), 
                    order: $("#order"+x).val(), 
                    quantity: $("#reEnterQty"+x).val()
                };   
            }
        }
        console.log('FORM SUBMIT');
        /* 
        $.ajax({
            type: "POST",
            async:false,
            url: "invReturnsRemove.php",
            dataType: "json",
            data: {data: JSON.stringify(arr)},//({sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: quantity}),
            success: function(data){
                console.log('SUCCESS');
            }
        }).fail(function(data) {
            console.log('FAIL');
        });
        */
        $("#returnsNotice").html("<h3>" + x + " return(s) removed.</h3>");

我刚刚注意到的另一件事是arr变量实际上是一个Object,而不是一个Array。不确定这是否会影响 PHP 中的内容。而且,我注意到您x的起始值为1. 这也意味着,在arr创建为的情况下Array,您将拥有undefined第一个元素。

还有,什么是counter?如果您基于此循环,则可能需要查看。

作为故障排除的中间步骤,以下版本的 JavaScript 代码将取消在最近一次未被阻止的提交后 1.2 秒内进行的任何提交调用。我建议将此作为解决方案(它非常糟糕),但它可能有助于解决存在问题的问题。

(function(undefined) { 
    if (window.blockSubmission === undefined) {
        window.blockSubmission = false;
    }
})();

$("#reEnterSKU").on('click', function() {

    // this will make sure your listener only gets called at most once every 1.2 seconds
    if (window.blockSubmission) {
        return false;
    } else {
        window.blockSubmission = true;
        setTimeout(function() { 
            window.blockSubmission = false;
        }, 1200);
    }

    if($("input[name=returnType]:checked").val() == "remove") { //executes when Remove radio button is checked
        var arr = [];
        var counter = 0;

        for(var x = 1; x < 11; x++)
        {
            if( $("#sku"+x).val() != "" && $("#order"+x).val() != ""){
                arr[x] = {
                    sku: $("#sku"+x).val(), 
                    order: $("#order"+x).val(), 
                    quantity: $("#reEnterQty"+x).val()
                };   
            }
        }
        console.log('FORM SUBMIT');

        $.ajax({
            type: "POST",
            async:false,
            url: "invReturnsRemove.php",
            dataType: "json",
            data: {data: JSON.stringify(arr)},//({sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: quantity}),
            success: function(data){
                console.log('SUCCESS'); // how many times do you see this per button click?
            }
        });

        $("#returnsNotice").html("<h3>" + x + " return(s) removed.</h3>");

如果这不能让您获得任何帮助,您可能想在您的问题中详细说明一下。包括额外的代码会很有帮助。也许更长的 PHP / HTML 摘录将至少显示整个form元素。此外,包含更全面的 JavaScript 摘录也可能会有所帮助。例如,表单提交按钮的单击事件侦听器永远不会在您帖子中提供的摘录中关闭。这使得很难看到真正发生了什么。

如果你打算做很多 JS,那么这可能值得一读。它有点过时了,但它是浏览器调试工具的精彩介绍:

http://jtaby.com/2012/04/23/modern-web-development-part-1.html

于 2012-12-09T06:12:59.573 回答
2

在没有看到完整上下文的情况下,我猜测点击是由一些重复触发的。这个小技巧可能会解决它:

var e = false;
$("#reEnterSKU").on('click', function() {
    if (e) return;

    if ($("input[name=returnType]:checked").val() == "remove") { //executes when Remove radio button is checked
        e = true;
        var arr = {};
        var counter = 0;

        for(var x=1;x<11;x++)
        {
            if ($("#sku"+x).val() != "" && $("#order"+x).val() != "") {
                arr[x] ={sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: $("#reEnterQty"+x).val()};   
            }
        }  

        $.ajax({
            type: "POST",
            async:false,
            url: "invReturnsRemove.php",
            dataType: "json",
            data: {data: JSON.stringify(arr)},//({sku: $("#sku"+x).val(), order: $("#order"+x).val(), quantity: quantity}),
            success: function(data) {}
        });

        $("#returnsNotice").html("<h3>" + x + " return(s) removed.</h3>");
        e = false;
    }
});
于 2012-12-07T18:15:16.280 回答