Solved

Update four divs with one javascript ajax call

Posted on 2010-09-03
10
531 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
 
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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 
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

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

705 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

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now