Solved

Update four divs with one javascript ajax call

Posted on 2010-09-03
10
536 Views
Last Modified: 2012-05-10
Hi there,

I'm writing a registration form script for a conference that uses AJAX to calculate the total.  There are four fields (divs), which need updating after a calculation is run.  The fields being calculated are:

- Conference Total
- Post Conference Course Total
- Subtotal (the sum of the conference Total and Post conference Total)
- Grand Total (the subtotal plus any applicable taxes).

I've attached a screenshot of the fields which are updated
 screenshot of fields that are updated
Please note how the conference total is calculated correctly at $585, but the subtotal and total show as $0.00.  You will also see I have echoed my SQL queries to help in my debugging.  Running the query in the database shows that 585 is entered in as the conference total in the database, but the code that calculates the subtotal and total isn't pulling the correct amount from the database in this example (but in other test registrations it is working).

My Ajax code calls PHP scripts which update a database and then calculates the subtotal and grand total based on the data in the database.  The code always seems to calculate and Conference Total and Post Conference Course total and updates the corresponding divs correctly.  However, the subtotal and Grand Total are only correct about 75% of the time.  The database also seems to be updated correctly, but for some reason the scripts called to calculate the subtotal and grand total aren't pulling the correct data from the database.  My suspicion is there is something incorrect with the way my AJAX is put together that is causing the issues.  I've attached my AJAX code for reference.

I've been banging my head over this for a while, so any help is greatly appreciated.

Thanks!




function calculateTotal(){
	
  var ajaxRequest1;  // The variable that makes Ajax possible!
  var ajaxRequest2;
  var ajaxRequest3;
  var ajaxRequest4;
	
	try{
		// Opera 8.0+, Firefox, Safari
		ajaxRequest1 = new XMLHttpRequest();
		ajaxRequest2 = new XMLHttpRequest();
		ajaxRequest3 = new XMLHttpRequest();
		ajaxRequest4 = new XMLHttpRequest();
	} catch (e){
		// Internet Explorer Browsers
		try{
			ajaxRequest1 = new ActiveXObject("Msxml2.XMLHTTP");
			ajaxRequest2 = new ActiveXObject("Msxml2.XMLHTTP");
			ajaxRequest3 = new ActiveXObject("Msxml2.XMLHTTP");
			ajaxRequest4 = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try{
				ajaxRequest1 = new ActiveXObject("Microsoft.XMLHTTP");
				ajaxRequest2 = new ActiveXObject("Microsoft.XMLHTTP");
				ajaxRequest3 = new ActiveXObject("Microsoft.XMLHTTP");
				ajaxRequest4 = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e){
				// Something went wrong
				alert("Your browser broke!");
				return false;
			}
		}
	}
	// Create a function that will receive data sent from the server
	ajaxRequest1.onreadystatechange = function(){
		if(ajaxRequest1.readyState == 4 && ajaxRequest1.status == 200){
			var ajaxDisplay = document.getElementById('total');
			ajaxDisplay.innerHTML = ajaxRequest1.responseText;	      
      
      document.getElementById("total").style.display = "block";
      document.getElementById("total_postconference").style.display = "block";
      document.getElementById("total_subtotal").style.display = "block";
      document.getElementById("calculate_total_textlink").style.display = "none";
      
        
		}
	}
	
	
	var num_attendees = document.getElementById("num_attendees").value;
  	
  var queryString = "?num_attendees=" + escape(num_attendees);   
	
  ajaxRequest1.open("GET", "include_calculatetotal.php" + queryString, true);
  ajaxRequest1.setRequestHeader("If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT");
  ajaxRequest1.setRequestHeader("Cache-Control", "no-cache"); 
  ajaxRequest1.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  ajaxRequest1.setRequestHeader("Content-length", queryString.length);
  ajaxRequest1.setRequestHeader("Connection", "close"); 
  
	
	
	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
	// Create a function that will receive data sent from the server
	ajaxRequest2.onreadystatechange = function(){
		if(ajaxRequest2.readyState == 4 && ajaxRequest2.status == 200){
			var test123 = document.getElementById("total_postconference");
			test123.innerHTML = ajaxRequest2.responseText;
      
      ajaxRequest1.send(null);
      
		}
	}
	
	
  var queryString2 = "?num_attendees=" + num_attendees;  
    
  
	ajaxRequest2.open("GET", "include_calculate_postconference_total.php" + queryString2, true);
	ajaxRequest2.setRequestHeader("If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT");
  ajaxRequest2.setRequestHeader("Cache-Control", "no-cache"); 
  ajaxRequest2.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  ajaxRequest2.setRequestHeader("Content-length", queryString2.length);
  ajaxRequest2.setRequestHeader("Connection", "close"); 
	
	
	
	
	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  
  
  // Create a function that will receive data sent from the server
	ajaxRequest3.onreadystatechange = function(){
		if(ajaxRequest3.readyState == 4 && ajaxRequest3.status == 200){
			var ajaxDisplay = document.getElementById('total_subtotal');
			ajaxDisplay.innerHTML = ajaxRequest3.responseText;	      
      
      ajaxRequest2.send(null);
      
     
        
		}
	}
	
		  	
  var queryString3 = ""; 
  ajaxRequest3.open("GET", "include_calculate_subtotal.php" + queryString3, true);
  ajaxRequest3.setRequestHeader("If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT");
  ajaxRequest3.setRequestHeader("Cache-Control", "no-cache"); 
  ajaxRequest3.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  ajaxRequest3.setRequestHeader("Content-length", queryString3.length);
  ajaxRequest3.setRequestHeader("Connection", "close");  
	
	
	
	
		// Create a function that will receive data sent from the server
	ajaxRequest4.onreadystatechange = function(){
		if(ajaxRequest4.readyState == 4 && ajaxRequest4.status == 200){
			var ajaxDisplay = document.getElementById('grand_total');
			ajaxDisplay.innerHTML = ajaxRequest4.responseText;	      
      
      document.getElementById("grand_total").style.display = "block";
      
      ajaxRequest3.send(null);
      
        
		}
	}

	
  	
  var queryString = ""; 
  ajaxRequest4.open("GET", "include_calculate_grandtotal.php" + queryString, true);
  ajaxRequest4.setRequestHeader("If-Modified-Since", "Thu, 1 Jan 1970 00:00:00 GMT");
  ajaxRequest4.setRequestHeader("Cache-Control", "no-cache");  
	ajaxRequest4.send(null);
	
	
	
	}

Open in new window

0
Comment
Question by:ims1010
  • 3
  • 2
  • 2
  • +2
10 Comments
 
LVL 75

Accepted Solution

by:
Michel Plungjan earned 400 total points
ID: 33594520
I STRONGLY suggest you do ONE ajax call, return some JSON and fill the divs with the result based on ONE return from the server.

For example:
totals = { "Conference Total" : 234.50,  "Post Conference Course Total":345.50, "Subtotal":675.00, "Grand Total":912.50 }

It is not optimal to do more than one ajax call and I do not see why you would have more than one php do this calculation
0
 
LVL 2

Expert Comment

by:xlt77
ID: 33594765
Maybe here :  if(ajaxRequest4.readyState == 4 && ajaxRequest4.status == 200){

if ajaxRequest4.status changes after onreadystatechange() event, the code should randomly return false;

The better way is check responseText;
0
 
LVL 34

Assisted Solution

by:Beverley Portlock
Beverley Portlock earned 100 total points
ID: 33595616
Ajax is asynchronous so the calls may not happen in the order you suspect. If (say) call #1 did all the calculation and call #2 brought back the results then everything is fine as long as call #1 always COMPLETES before call #2. If they execute in parallel or if #2 goes before #1 then you will have problems.

Really what you need is ONE call that brings back four results as a string (JSON encoded?). Return your result to a single javascript function and write code in that function to split the string and then update the DIVs etc from there.
0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 33595990
yes, as I said earlier
0
 
LVL 29

Expert Comment

by:Badotz
ID: 33596850
>>Ajax is asynchronous...

It can be synchronous, too.
0
 
LVL 34

Expert Comment

by:Beverley Portlock
ID: 33596897
"yes, as I said earlier"

I know, but I felt that the explanation "It is not optimal to do more than one ajax call" was a bit on the thin side and so I expanded on it, although I probably could have dropped the JSON bit.

To be honest (since I'm in an expansive mood) I have to say that I don't like JSON due to the way it is usually evaluated via an EVAL which could do just about anything to your code. I usually use implode() in PHP and split() in javascript to avoid the security issues that JSON can raise.
0
 
LVL 29

Expert Comment

by:Badotz
ID: 33597095
There is built-in JSON support for IE (and FF?) I believe. No "eval" is used, although there are implementations of JSON that do not rely on eval.
0
 
LVL 29

Expert Comment

by:Badotz
ID: 33597102
And I must say, JSON is far easier to use than XML, which it is intended to replace.
0
 

Author Comment

by:ims1010
ID: 33599056
Thanks for your responses so far - much appreciated!   I'm looking into using JSON and will post further comments/award points shortly.  Thanks!
0
 

Author Closing Comment

by:ims1010
ID: 33602170
Thanks for the help!  I ended up using JSON and it works great.   mplungjan provided the roadmap, but i did find the comments bportlock provided helpful as well (especially the JSON encoded tip).
Cheers!
0

Featured Post

Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction A frequently asked question goes something like this:  "I am running a long process in the background and I want to alert my client when the process finishes.  How can I send a message to the browser?"  Unfortunately, the short answer …
International Data Corporation (IDC) prognosticates that before the current the year gets over disbursing on IT framework products to be sent in cloud environs will be $37.1B.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question