I have a nagging problem that I have spent many hours trying to resolve with no luck. I have a form that is used to remove items from our database. Here is the form:
EDIT: I have updated the code to something that is a little more reasonable, however I still have my problem.
<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> </th>
<td> </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>
The js to handle this is:
$("#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 is:
<?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();
?>
The issue is that when I try to run it, even with only one record to remove, it runs hundreds of times.
Any idea what I may be doing wrong, and how to fix it?
A comment you made suggests that at least part of the issue is client-side.
You may have added the
'click'event listener multiple times. If the code you add the event listener with is in a loop then you almost certainly have added it multiple times. For instance, if you have several forms on the page and are attaching listeners in the following manner, any time your submit button is pressed it will be triggered several times.As you’re using an event listener directly associated with the
buttonon theform, you should probably eitherreturn false;from the event listener function or calle.preventDefault();(you will have to add theeparameter to your click listener function) to avoid the button submitting theform. (Maybe you’re already doing something like that but did not include the code?) I’m assuming you’re not intending to redirect the page, otherwise you wouldn’t update the content of the<div id="returnsNotice"></div>element.Another thing that could cause problems is if the selectors you’re using to find and add click listeners to your buttons are not specific enough. If this is the case, you may be adding event listeners to more than one button at a time, and therefore a button might end up with more than one event listener.
Also, when working with forms, I believe it’s generally best to avoid attaching event listeners to particular form elements, such as buttons, for the purposes of triggering submission as things can get complicated in the various submission scenarios, like when a user hits the
enterkey while a text input field has the focus. As an alternative, you can use the jQuery.submit() method which is attached to theformelement and should be triggered by any situation that will cause the form to submit. This will allow you to execute a function (the submit listener) and halt the automatic submission with greater reliability. This will also allow you to leverage the browser’s form validation functionality that comes built-in when you apply therequiredattribute to form elements (details and compatibility).Regarding how to fix the issue, the first thing I would do is comment out the form submission statement to just take that out of the equation. Then, in its place, add a
console.log()statement to see a) if it gets called multiple times and b) try to figure out how to have it execute only once if it is being called multiple times. You can also add aconsole.log()statement that gets executed when you’re adding the click event listener to make sure you’re only adding one click event listener. I’ve include these changes below.Something else I just noticed is the
arrvariable is actually anObject, not anArray. Not sure if that would affect things in PHP or not. And, I noticed you’re startingxat a value of1. That also means, in the case thatarris created as anArray, you will have aundefinedfirst element.Also, what is
counter? If you’re looping based on that, it could be something to look at.As an intermediate step in trouble shooting thigns, the following version of the JavaScript code will cancel any submission calls made within 1.2 seconds of the most recent submission that was not blocked. I do not recommend this as a solution (it’s quite wretched), but it might be helpful in trouble shooting where the problem(s) exist.
If that doesn’t get you anywhere you might want to elaborate a bit in your question. Including additional code would be helpful. Maybe longer excerpts of your PHP / HTML that will show at least the entire
formelement. Also, including a more comprehensive excerpt of JavaScript might help, too. For instance, the click event listener for the form submission button is never closed in the excerpt provided in your post. That makes it tough to see what’s really going on.If you’re going to be doing a lot of JS, then this might be worth a read. It’s a little dated, but it’s a fantastic intro to browser debug tools:
http://jtaby.com/2012/04/23/modern-web-development-part-1.html