Fast consecutive XmlHttpRequest doesnt work - php

I have a code where when a div is clicked, an XmlHttpRequest is sent to a PHP script and some data is sent back. When the response is received by the client, some CSS work is done. But, if I click on a div and then after one second I click on another one, the second one doesn't fire the event.
How can I fix this issue?
Is there is a way to free memory after xmlhttp request is done?
This is my mousedown event function:
.on("mousedown",function () {
var idgroup = $("#group_" + idBlock).val();
var idProf = $(this).attr("name");
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
// css color change is done here
}
}
xmlhttp.open("GET", "../dnd_jq/getProfTime.php?idprof=" + idProf + "&idgroup=" + idgroup);
xmlhttp.send();
}

Chances are the XHR object can't only fire if it is still waiting for a request.
What I would do is make 2 XHR objects that fire for each request?
P.S. I am very new to XHR and bad explanation skills, so take my response with a grain of salt!

Related

Second AJAX call unloading result of the first

Code below is run in the onLoad event of the page. I first would like to populate a drop down menu with getCompany() and then fill in data from the server into text boxes and choose the selected option.
Both functions work, in fact when I reload the page with debugger running and step into everything both do what they are supposed to.
When I just open the page or reload with out debugger the text boxes are filled but the options disappear from the dropdown, why is that?
<script>
var result;
function init(){
var name = window.name;
name = name.split(",");
getCompany();
setTimeout(200);
if (name[0] = "update"){
id = name[1];
getTenant(id);
//get the info for the line that called the edit function
//fill fields with information from server
}
}
function getCompany() {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function x() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("company").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET","getCompany.php",true);
xmlhttp.send();
}
function getTenant(id){
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function y() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
result = xmlhttp.responseText;
result = result.split(",");
//fill the form with old information
document.getElementById("fname").value = result[0];
document.getElementById("lname").value = result[1];
document.getElementById("company").selectedIndex = result[2];
document.getElementById("phone").value = result[3];
document.getElementById("email").value = result[4];
document.getElementById("crm").value = result[5];
}
}
xmlhttp.open("GET","getTenant.php?p=" + id,true);
xmlhttp.send();
}
</script>
I assume the input fields you are filling in data in the second request belong to the data fetched from the first request. I also assume you are using the setTimeout() to delay the 2nd request...
Javascripts are single threaded. To provide asynchronous behavior js uses callback mechanism. After sending a request to the server, js doesn't wait until the response comes. JS keeps executing the rest of code until the results from the server comes. When the response comes from the server the code in the callback function xmlhttp.onreadystatechange is executed. Because of that, both requests may happen at almost the same time and consequently the response for the 2nd request may come before the first response which leads the behavior you see as an error.
When you debug, you execute line by line. Therefore there is enough time to get the response for the first request before getting the response for the second request.
As a solution you can move the code for the second request inside the xmlhttp.onreadystatechange callback in the code for the first request. Then as the callback is always executed after the results are fetched, the second request is sent after the response for the first one comes.
You may google about asynchronous javascript and learn in details...
<script>
var result;
function init(){
var name = window.name;
name = name.split(",");
getCompany(name);
}
function getCompany(name) {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function x() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("company").innerHTML = xmlhttp.responseText;
if (name[0] == "update"){
id = name[1];
getTenant(id);
//get the info for the line that called the edit function
//fill fields with information from server
}
}
}
xmlhttp.open("GET","getCompany.php",true);
xmlhttp.send();
}
function getTenant(id){
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else { // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function y() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
result = xmlhttp.responseText;
result = result.split(",");
//fill the form with old information
document.getElementById("fname").value = result[0];
document.getElementById("lname").value = result[1];
document.getElementById("company").selectedIndex = result[2];
document.getElementById("phone").value = result[3];
document.getElementById("email").value = result[4];
document.getElementById("crm").value = result[5];
}
}
xmlhttp.open("GET","getTenant.php?p=" + id,true);
xmlhttp.send();
}
</script>
It is happening because of a race condition between the two XHR calls made from getCompany and getTenant methods. Even though you are making the getTenant call 200ms after making the first XHR call there is no guarantee that the getComapny XHR call will finish first. When that happens the follwoing line of code
document.getElementById("company").innerHTML = xmlhttp.responseText;
removes all the options from the menu and also resets the selected index. To circumvent this issue do not make getTenant(id); call from init method. Instead make it from the success handler of the getCompany XHR call.
xmlhttp.onreadystatechange=function x() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
document.getElementById("company").innerHTML = xmlhttp.responseText;
**getTenant(id);**
}
}
Make two different object name instead of one (xmlhttp). Like
in 'getCompany()' function object name is 'xmlhttp'
in 'getTenant()' function changed object name to 'xmlTalenthttp' (or any other name which you wish)

AJAX no data in responsetext

Right up front...I am very new to using Ajax.
I'm working on a web site where I want the results of one Select object to determine the options in the second Select object(from a database query). I'm using PHP and it appears that the only way to do this is to use Ajax. I've written a short html page to test my Ajax knowledge and it seems to work just find on Firefox but not on Chrome or IE. I've done a lot of research and found all sorts of folks with similar problems but no real solution.
I'm making the XMLHTTPRequest call to a local file in the same folder even so I should not be experiencing any cross-domain problems. Any help would be greatly appreciated.
Here's my Javascript function that gets called when the Select box is changed:
...
function getData(str)
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","ajax_info.php?color=",true);
xmlhttp.setRequestHeader("Content-Type", "text/xml");
xmlhttp.send();
alert(xmlhttp.responseText);
}
********ajax_info.php
+++++++++++++++++++++
//this is the php file that runs in response to the xmlhttprequest. It just generates a string of number at this time.
<?php
$str = "";
$i = 0;
for($i; $i<1000; $i++)
{
$str = $str.$i."-";
}
echo $str;
?>
You need to attach an event handler to your xmlhttp object to catch the onreadystatechange event. Note that when you alert your value, the asynchronous ajax call has just fired and has not finished yet (you are not checking for that anyway):
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
alert(xmlhttp.responseText);
}
}
xmlhttp.open("GET","ajax_info.php?color=",true);
xmlhttp.setRequestHeader("Content-Type", "text/xml");
xmlhttp.send();
Well in that case you should try jQuery. It will be lot easier for you to make ajax request.
Here is an example for your problem
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
// FOR GET REQUEST
$.get("ajax_info.php",{color:'value'},function(data) {
alert(data); // RETRIEVE THE RESULT
});
</script>

Modifying Results Table to use AJAX

I have a PHP website that allows users to search a library catalog and then select/add books to a shopping cart. This all works well but we would like to implement AJAX into the search results table so that instead of clicking a link which runs another php script to add the selected record to their cart, it does this inline within the same page. This will remove the search results page refreshing when they "select" a record and it pops back to the top of the page (annoying if you were at the bottom of the page).
I've found a similar example of implementing AJAX with a link - this is my first time with AJAX - but I'm stuck as nothing happens when the user clicks the link.
Here's my script:
function selectRecord() {
// Allocate an XMLHttpRequest object
if (window.XMLHttpRequest) {
// IE7+, Firefox, Chrome, Opera, Safari
var xmlhttp=new XMLHttpRequest();
} else {
// IE6, IE5
var xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
// Set up the readyState change event handler
xmlhttp.onreadystatechange = function() {
if ((this.readyState == 4) && (this.status == 200)) {
document.getElementById("selectRecord").innerHTML=xmlhttp.responseText;
}
}
// Open an asynchronous POST connection and send request
xmlhttp.open("POST", "selectRecord.php", true);
return false; // Do not follow hyperlink
}
and here's the table cell with the link:
<td class="hidden-narrow" id="selectRecord">
<?php
if (in_array($bookID, $_SESSION['selectedBooks'])) {
echo "Selected";
} else {
echo 'Select';
}
?>
</td>
In case it's not clear the result I'm after is a link ("Select") in the table cell - when the user clicks this link it then performs the selectRecord.php script which will echo "Selected" or an error message if there was an error. At present nothing happens when the user clicks the Select link.
I also need to work out how to pass the $bookID PHP variable to the AJAX script so the selectRecord.php knows which Book ID to add to the cart.
You can add a parameter to your selectRecord() call like this:
echo 'Select';
Then your selectRecord function should look like this:
function selectRecord(id) {
// Allocate an XMLHttpRequest object
if (window.XMLHttpRequest) {
// IE7+, Firefox, Chrome, Opera, Safari
var xmlhttp=new XMLHttpRequest();
} else {
// IE6, IE5
var xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
// Set up the readyState change event handler
xmlhttp.onreadystatechange = function() {
if ((this.readyState == 4) && (this.status == 200)) {
document.getElementById("selectRecord").innerHTML="Selected";
}
}
// Open an asynchronous POST connection and send request
xmlhttp.open("POST", "selectRecord.php", true);
xmlhttp.send("id="+id);
return false; // Do not follow hyperlink
}
This works well as long there is only one element in your document with id selectRecord. You can always modify the id of any link by simply adding the BookId number as a postfix.
Please note your code wasn't working because it was missing the .open call on the xmlHttpRequest object which actually perform the request.

xmlhttp.open(url) and Calling php function using AJAX not working?

Just beginner in php, I want to call php method using AJAX. I tried every thing but don't know what error is. Not getting any response from object xmlhttp.
Heres my java script code :
function loadData(){
var mID=ddItems;
var method=2;
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
if (xmlhttp.readyState == 4 || xmlhttp.readyState == 0) {
xmlhttp.open("GET", "../code/GetItemsInDD.class.php?id=" + mID + "&method=" + method, true); **// is this statement correct**
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200) **//conditin is false,**
{
document.getElementById("ddItems").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.send();
}
}
My js file is on "projectname/javascript/script.js" and my php file is in "projectname/code/GetItemsInDD.class.php" dir.
Why don't you use jQuery for making AJAX requests? Its as simple as this, include jQuery in your page
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
and JS code,
$.ajax({
type: 'GET',
url: '../code/GetItemsInDD.class.php?id=" + mID + "&method=" + method',
success: function (data) {
document.getElementById("ddItems").innerHTML = data;
}
});
This way, you don't need to check for the readyState and status thing
jQuery follows object oriented approach for declaring XMLHttpRequest objects, so you won't have to worry about creating multiple objects for making more than one AJAX requests.
function loadData(){
var xmlhttp;
var mID=ddItems;
var method=2;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("ddItems").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET", "../code/GetItemsInDD.class.php?id=" + mID + "&method=" + method, true);
xmlhttp.send();
}
I have made 2 desired changes to your code, try running it now. Make sure the URL is correct.
function loadData()
{
var mID=ddItems;
var method=2;
var xmlhttp;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
}
else //For some versions of IE
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200) **//conditin is false,**
{
document.getElementById("ddItems").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET", "../code/GetItemsInDD.class.php?id=" + mID + "&method=" + method, true); **// is this statement correct**
xmlhttp.send();
}
}
Change 1 : You may be running the code in an older version of IE, where ActiveXObject is used.
Change 2 : The open() method should not be called if the readyState changes ( as you have written it within the IF block), readyState changes only after the ajax call is initialized by the open() method and then send by the send() method.

favorite button for article

I want to create for my blog an articles fav button. First I use :
<script type="text/javascript">
function AddPost(str,user)
{
if(str == "")
{
document.getElementById("txtHint").innerHTML = "";
return;
}
if (window.XMLHttpRequest)
{ // code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
}
else
{ // code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function()
{
if (xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
document.getElementById("txtHint").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET", "addfav.php?p=" + str + "&u=" + user, true);
xmlhttp.send();
}
</script>
Where p is post ID and u is the user who fav'd the article. In the loop for the articles I add an image with:
onclick="AddPost(<php echo of the post id>, <php echo of the current user id>)"
And that was stupid because the function works for all of them, not for just one. In addfav.php I just get the p and u parameters and then INSERT into the database. I'm new to Ajax and I dont know how to make it different for the articles.
Your PHP code needs to not allow any more favorites to be added (I cannot comment further on that because you did not include the PHP/SQL code). Also, in your javascript code, once AJAX has returned successful, disable the other Fav buttons.
By the way, using a well-tested library like jQuery (especially for AJAX) will greatly speed development.

Categories