Reputation: 3171
I have a small form which contains a first name, last name and a date. On clicking to submit the form I want it to check the database for a duplicate entry (with Ajax), and if there is already 1+ entries, present a confirm window confirming another submission. The confirm shouldn't show if there aren't any entries.
For some reason it seems to be presenting the confirm without the result from the Ajax PHP page. If I introduce an alert after the xmlHttp.send(null)
line, it gets the text from the PHP (as wanted), making me think I misunderstand the order the code is executed. Here is the code:
Javascript:
function check_duplicates() {
var first = document.getElementById('first_name').value;
var last = document.getElementById('last_name').value;
var date = document.getElementById('event_date').value;
var xmlHttp = GetXmlHttpObject();
if (xmlHttp == null) {
alert ("Your browser does not support AJAX!");
return;
}
var result = "ERROR - Ajax did not load properly";
var url="check_duplicate.php";
url=url+"?first="+first;
url=url+"&last="+last;
url=url+"&date="+date;
xmlHttp.onreadystatechange=function() {
if(xmlHttp.readyState==4) {
result = xmlHttp.responseText;
alert("RESULT="+result);
if(result != "clean") {
var validate = confirm(result);
return validate;
}
}
}
xmlHttp.open("GET",url,true);
var test = xmlHttp.send(null);
}
function GetXmlHttpObject() {
var xmlHttp = null;
try {
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e) {
// Internet Explorer
try {
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
PHP:
// DATABASE CONNECTION INFORMATION REMOVED
$first = $_GET['first'];
$last = $_GET['last'];
$date = date('Y-m-d',strtotime($_GET['date']));
$sql = "SELECT COUNT(*) AS count FROM Table WHERE First='$first' AND ".
"Last='$last' AND Date='$date'";
$result = mysql_query($sql);
$row = mysql_fetch_array($result);
if($row['count'] > 0) {
if($row['count'] == 1) {
echo "There is already an entry for ".$first." ".$last." on ".
date('M jS',strtotime($date)).".\n".
"Are you sure you want to submit this entry?";
}
else { // plural version of the same message
echo "There are already ".$row['count']." entries for ".$first." ".
$last." on ".date('M jS',strtotime($date)).".\n".
"Are you sure you want to submit this entry?";
}
} else {
echo "clean";
}
Upvotes: 0
Views: 1654
Reputation: 11307
Here is an answer using synchronous AJAX. This way, you don't have to overload the default form handling to get it to work. However, all javascript will be blocked while the confirmation request is running, which means your web page may appear to come to a screeching halt for however long the confirmation request lasts.
This function will return true if the record should be added, and false otherwise.
function check_duplicates() {
var first = document.getElementById('first_name').value;
var last = document.getElementById('last_name').value;
var date = document.getElementById('event_date').value;
var xmlHttp = GetXmlHttpObject();
if (xmlHttp == null) {
alert ("Your browser does not support AJAX!");
return false;
}
var result = "ERROR - Ajax did not load properly";
var url="check_duplicate.php";
url=url+"?first="+encodeURIComponent(first);
url=url+"&last="+encodeURIComponent(last);
url=url+"&date="+encodeURIComponent(date);
xmlHttp.open("GET",url,false);
xmlHttp.send(null);
var validated = true;
var result = xmlHttp.responseText;
if (result != 'clean')
validated = confirm("RESULT="+result);
return validated;
}
Upvotes: 1
Reputation: 11307
This line of code return undefined
.
var test = xmlHttp.send(null);
What you have to understand is that the send()
call returns immediately and Javascript keeps running. Meanwhile, your AJAX request is running in the background. Also, your onreadystatechange
handler is called once the request is done, whether it takes 10ms or 100s, and its return value is not received by the rest of your code.
I think what you wanted to submit the form AFTER the confirmation was finished. You only know when the request is finished from inside your onreadystatechange
handler. The problem here is that, in order to wait for the AJAX request to finish you have to override the default behavior of the form.
You'll need to call preventDefault()
on the form-submit event, and then submit the data manually after confirmation.
xmlHttp.onreadystatechange=function() {
if(xmlHttp.readyState==4) {
var confirmed = false;
var result = xmlHttp.responseText;
if (result == "clean")
confirmed = true;
else
confirmed = confirm("RESULT="+result);
if (confirmed) {
var url = "addData.php";
url=url+"?first="+encodeURIComponent(first);
url=url+"&last="+encodeURIComponent(last);
url=url+"&date="+encodeURIComponent(date);
window.location = url;
}
}
}
Also, when you're building your URL you should use encodeURIComponent.
url=url+"?first="+encodeURIComponent(first);
url=url+"&last="+encodeURIComponent(last);
url=url+"&date="+encodeURIComponent(date);
Upvotes: 0