2012-12-04 169 views
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(); 
?> 

的问题是,当我尝试运行它,即使只有一个记录删除,它运行数百次。 任何想法我可能做错了,以及如何解决它?

+1

为什么同一个查询三个时间???在第一个代码 –

+2

SQL注入..alert ....坏人将符号您的数据库 –

+0

每行可以有一个不同的货架位置输入,并且数据输入需要能够单独选择位置 – Jim

回答

3

A comment you made表明至少部分问题是客户端。

您可能多次添加了'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 
    }); 
}); 

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

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

$("#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

+0

感谢您的非常详细的答案。正如你所说的,问题是我在同一页面的不同标签上的几个地方使用sku。将其更改为returnsku后,页面现在可以完美运行。再次感谢您的详细解释。 – Jim

+0

没问题。很高兴帮助! – tiffon

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