
Question:
I am using jQuery (version 1.8.1) with PHP (version 5.3) to submit a form adding an entry into a mySQL database, what is happening is on the first submit everything is fine but for each subsequent submission without a page refresh it adds an additional entry.
In addition I'm also using Bootstrap (version 2.1.1) and the upload widget from Jasny for Bootstrap (version j1a) in the UI. I have not yet connected the upload widget to the processing or submit as I detected the duplication problem when I was implementing it.
Please note that this is a proof of concept system so the code is rough as I'm not going to invest in cleaning it up until the project is confirmed. Due to this, you will notice some inline mySQL queries, I know that this isn't the best way to do it however it works for the purpose of demonstration and will be cleaned up later. Also as a POC system it is on an internal server currently, I can share the code but cannot show an example site at this time unfortunately.
Now back to the issue, as an example, the first post for "Company 1" has 1 record added for "Company 1", the second record for "Company 2" adds 2 records for "Company 2", the third record for "Company 3" adds 3 records for "Company 3" and so on. If I reload the form page in any way (refresh or a new request) the problem restarts from the first submission.
I am using jQuery serialize
with ajax
to post the data to the PHP processor. I have logged all of the posts being received by the processor and I see the processor is receiving multiple records from the form, I thought it may have been caused by a foreach
loop in the PHP but this is not the case.
I have removed the jQuery functions and it works perfectly each time without any duplicates on normal PHP submit.
I have manually processed the entries via jQuery instead of serialize
but as there is a dynamic array via PHP I still used serialize
on that array, this produced the duplicates as described above.
I have searched the issue for a number of days but cannot find anything definitive to clear up the issue, all suggestions on blogs and forums that looked to be related did not work, I have tried around 10-15 different options.
The combination of all of this leads me to believe the issue is coming from the jQuery serialize
and/or ajax
functions but my eyes have become glazed each time I look at this code now.
I am also considering placing the form in an external file and reloading it fresh via ajax or cleaning the form setting it back to defaults via jQuery for each new entry required however I do not believe either of these approaches will solve the problem.
Any help is greatly appreciated, thanks in advance for the help!
<strong>jQUERY code</strong>
<script>
$(document).ready(function() {
$('.fileupload').fileupload('name:logo');
$('.help-inline').hide();
$("#btn_process").click(function() {
$('form').submit(function() {
$('.help-inline').hide();
var company_name = $("#company_name").val();
if (company_name === "") {
$("div#name_group").addClass("error");
$("span#name_error").show();
return false;
}
var dataString = $('form').serialize();
$.ajax({
type: "POST",
url: "inc/addcompany.php",
data: dataString,
success: function(html) {
if(html === 'success')
{
$('#message')
.addClass("label label-success")
.css("margin-bottom","20px")
.html("<h3>Login successful</h3>Company added
")
.slideDown(1500, function() {});
}
else
{
$('#message')
.addClass("label label-important")
.css("margin-bottom","20px")
.html("<h3>Error</h3>There was an error, please check the information and try again
")
.slideDown(1500, function() {});
$("div#name_error").addClass("error");
$("span#name_error").show();
$("div#type_error").addClass("error");
$("span#type_error").show();
return false;
}
}
});
return false;
});
});
});
</script>
<strong>HTML markup</strong>
<form class="form-horizontal" id="add_company" method="POST" action="">
<fieldset>
<div id="message"></div>
<div id="name_group" class="control-group">
<label class="control-label" for="company_name">Company name </label>
<div class="controls">
<input type="text" id="company_name" name="company_name" />
<span id="name_error" class="help-inline">This needs to be more than 3 characters</span>
</div>
</div>
<div id="type_group" class="control-group">
<label class="control-label">Company type </label>
<div class="controls">
<?
$sql = "SELECT description,id FROM types ORDER BY description";
$qry = mysql_query($sql) or die("ERROR: could not get company types => ".mysql_error());
while($company_type = mysql_fetch_array($qry)) {
echo '
<label class="checkbox inline"><input type="checkbox" name="type[]" value="'.$company_type['id'].'" /> '.$company_type['description'].' </label>';
}
?>
<span id="type_error" class="help-inline">Please select a minimum of 1 type</span>
</div>
</div>
<div id="website_group" class="control-group">
<label class="control-label" for="website">Website </label>
<div class="controls">
<input type="text" id="website" name="website" placeholder="www.something.com" />
</div>
</div>
<div id="logo_group" class="control-group">
<label class="control-label">Logo </label>
<div class="controls">
<div class="fileupload fileupload-new" data-provides="fileupload">
<div class="fileupload-new thumbnail" style="width: 50px; height: 50px;"><img src="/img/50x50.png" /></div>
<div class="fileupload-preview fileupload-exists thumbnail" style="width: 50px; height: 50px;"></div>
<span class="btn btn-file"><span class="fileupload-new">Select image</span>
<span class="fileupload-exists">Change</span>
<input type="file" /></span>
<a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
</div>
</div>
</fieldset>
<input type="hidden" name="action" value="add_company" />
<button class="btn" data-dismiss="modal" aria-hidden="true">Close</button>
<button class="btn btn-primary" name="btn_process" id="btn_process">Save changes</button>
</form>
<strong>The PHP processor</strong>
$error = false;
$error_company_name = false;
$error_type = false;
$error_website = false;
$company_name = $_REQUEST['company_name'];
$type = $_REQUEST['type'];
$website = $_REQUEST['website'];
$logo = $_REQUEST['logo'];
if(empty($company_name)) {
$error = true;
$error_company_name = true;
}
include_once('db.php');
$sql = "SELECT description,id FROM company_types";
$qry = mysql_query($sql) or die("ERROR: could not get company types => ".mysql_error());
$type_count = 0;
while($array = mysql_fetch_array($qry)) {
$type_count = $type_count+1;
}
if($type_count == 0) {
$error = true;
$error_type = true;
}
$ic = 0;
foreach($_REQUEST['type'] as $item) {
$ic = $ic+1;
}
if($ic == 0) {
$error = true;
$error_type = true;
}
if(isset($website) && $website != ' ') {
$url = 'http://'.$website;
if(!filter_var($url, FILTER_VALIDATE_URL)) {
$error = true;
$error_website = true;
}
}
if($error == false) {
$sql = "INSERT INTO company_list (name,website,logo) VALUES('$company_name','$website','$logo')";
$qry = mysql_query($sql) or die ("ERROR: could not add company => ".mysql_error());
$company_id = mysql_insert_id($link);
if($company_id == '' || $company_id == null || empty($company_id)) {
echo 'fail';
exit;
}
foreach($_REQUEST['type'] as $company_type) {
$sql = "INSERT INTO companies_types (companies_id,type_id) VALUES('$company_id','$company_type')";
$qry = mysql_query($sql) or die("ERROR: could not link company type: => ".mysql_error());
}
echo 'success';
}
Answer1:Add $('form').unbind('submit');
immediately above this line: $('form').submit(function()
.
I found this solution here: <a href="https://stackoverflow.com/a/668354/300575" rel="nofollow">https://stackoverflow.com/a/668354/300575</a>
Note: I verified that this works by copying your code and testing it on my server.
Answer2:It may be a patch and dont know if it will work but there is a jQuery ajaxStop
which can be called at the success call back.