ColdFusion Development
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
User Name:
Password:
Remember me

The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.

Go Back   Dev Shed ForumsProgramming Languages - MoreColdFusion Development

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Rate Thread Display Modes
 
Unread Dev Shed Forums Sponsor:
  #1  
Old December 8th, 2012, 01:10 PM
Xophe Xophe is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2012
Posts: 11 Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 1 h 10 m 3 sec
Reputation Power: 0
Ajax instead of cfflush?

Using CF8 - I have an action page that loops through a list of IDs and plugs them into a CF function. This process can take some time depending on the number of IDs, so I want to output a line of text to the browser (IE8) each time an ID has been processed, so the user isn't sitting there staring at a blank screen.

ID 1 has been processed.
ID 2 has been processed.
...
ID n has been processed.

Problem is, cfflush is terrible for this; I've played with the interval attribute, but it will wait for a while then output 3 1/2 lines, then wait a while again and output 2 lines, etc. Instead, I want 1 complete line and only 1 complete line to appear at a time, as soon as the function has processed the ID and returned something. So I'm not going to use cfflush.

I've researched the web and played with Ajax to try to get this to happen (I can't use jquery because our servers don't have the libraries on them), but I don't seem to be doing it correctly. Can someone give me a basic idea in pseudocode of what I want to do, or point me to a url that explains how to do this in AJAX?

Reply With Quote
  #2  
Old December 9th, 2012, 06:44 PM
kiteless kiteless is offline
Moderator
Dev Shed God (5000 - 5499 posts)
 
Join Date: Jun 2002
Location: Raleigh, NC
Posts: 5,091 kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level) 
Time spent in forums: 2 Weeks 5 Days 2 h 53 m 27 sec
Reputation Power: 966
There probably isn't an "example" of this that you can look at, but what you're talking about is creating a queue. So you'd send a "start" request to the server to initiate the process. You'd then have JavaScript on the client that polls the server to check the status of the queue and display the current status. Unfortunately, it's not really a simple thing to do.

Reply With Quote
  #3  
Old December 10th, 2012, 06:56 AM
Xophe Xophe is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2012
Posts: 11 Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 1 h 10 m 3 sec
Reputation Power: 0
Thanks much for that explanantion - I figured it wouldn't be simple, but that's certainly a point in the right direction. I picked up "Learning jQuery" by Chaffer and Swedberg; hopefully that'll bring me closer to figuring how to do it. In the meantime, I suppose I'll stick with cfflush for my page; maybe I can scrap that and implement the solution you describe in a future release when I've gotten my feet a lot wetter with jQuery.

For anyone else reading this who's had the same problem -- after looking at the example of cfflush in the CF8 Livedocs, I did a view source of the rendered page and realized the example renders neatly, 1 line at a time, only because it creates a massive amount of whitespace with each line. Other articles I've read explain that recent browers tend not to flush if there's too little data, and suggest using repeatString(" ", 250) with each flush to create enough data to convince IE to flush. With IE8 I've found that it has to be 100,000 instead of 250, in order to get my lines to come out neatly 1 at a time (that's with the cfflush interval set to a low value of 10, as in the Livedocs example). Not the most elegant solution, but in my case it's only an action page/popup; whitespace is less of an issue than it would be on a normal UI display page.

Reply With Quote
  #4  
Old December 12th, 2012, 03:20 PM
Xophe Xophe is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2012
Posts: 11 Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 1 h 10 m 3 sec
Reputation Power: 0
Found a simple solution, but...

I created a simple AJAX model of what I'm trying to do and it works fine in Firefox, but not in IE8. In IE8, instead of displaying the lines of text one at a time as each item is completed, the page continues working for several seconds, and then when it's done renders all 10 lines of text at once. (Also IE8 seems to cache the page sometimes - can I prevent that somehow?) Below is the code for the page, callAjax.cfm:

Code:
<script>

function ajax(url, n) {
  // native XMLHttpRequest object
  var objDiv = document.getElementById('myDiv');
  if (window.XMLHttpRequest) {
    req = new XMLHttpRequest();
    req.onreadystatechange = function() {ajaxDone(objDiv, n);};
    req.open("GET", url, false);
    req.send(null);
    // IE/Windows ActiveX version
  } else if (window.ActiveXObject) {
   		req = new ActiveXObject("Microsoft.XMLHTTP");
    	req.onreadystatechange = function() {ajaxDone(objDiv, n);};
    	req.open("GET", url, false);
    	req.send(null);
    }
}

function ajaxDone(objDiv, n) {
  // only if req is "loaded"
  if (req.readyState == 4) {
    // only if "OK"
    if (req.status == 200) {
      results = req.responseText;
	  //alert(req.responseText);
	  if (n == 1) {
	  	objDiv.innerHTML = '';
	  }
     objDiv.innerHTML = objDiv.innerHTML + results + '<br>';
	 if (n == 10) {
	 	objDiv.innerHTML = objDiv.innerHTML + '<br> All done.';
	 }
    } 
  }
}
</script>

<cfoutput>
<!--- the div is created. IE8 wants it to be populated with something, else the div object will be null, hence the nbsp --->
<div id="myDiv">&nbsp;</div>

<!--- then populated via 10 ajax requests--->
	<script>
	<cfloop from="1" to="10" index="n">
		ajax('ajaxPage.cfm?rnd=' + Math.random() + '&n=#n#', #n#);
	</cfloop>
	</script>
</cfoutput> 


and this is the page that is called via ajax (ajaxpage.cfm)):

Code:
<!--- make it wait a little bit... --->
<cfloop index="randomindex" from="1" to="200000" step="1">
    <cfset random=rand()>
</cfloop>
<!--- then output the text --->
<cfoutput>Line #url.n# ---- random number is: #random#</cfoutput>


Notice the commented out alert in the js on callAjax.cfm. I was using it to see what the response text is at that point in the function. In IE8, the alert box always comes up blank, except for a triangle icon with a "!" inside it. Which makes no sense to me - the readyState is 4, the status is 200, so the responseText should be there. And in any case, all 10 lines are rendered correctly, so it's receiving the responseText at some point.

Reply With Quote
  #5  
Old December 12th, 2012, 04:55 PM
kiteless kiteless is offline
Moderator
Dev Shed God (5000 - 5499 posts)
 
Join Date: Jun 2002
Location: Raleigh, NC
Posts: 5,091 kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level) 
Time spent in forums: 2 Weeks 5 Days 2 h 53 m 27 sec
Reputation Power: 966
I would look at something like jQuery to do the Ajax calls, since it handles all the various browser inconsistencies.

Reply With Quote
  #6  
Old December 12th, 2012, 06:17 PM
Xophe Xophe is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2012
Posts: 11 Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 1 h 10 m 3 sec
Reputation Power: 0
Yeah, I would, but they don't have jQuery functionality on our servers yet (for the app I'm working on), unfortunately.

A couple of small things I discovered, though:

1) Since I'm getting synchronously (3rd argument in open() is "false"), it's not necessary to define a function for onreadystatechange; I can just put the code in ajaxDone() right after the send() line.

2) alert(req.responseText) -- the responseText is there, it just has so much whitespace that the alert box will stretch down below the window and the text will be out of view. If I trim the response text, the alert box shows it just fine.

Reply With Quote
  #7  
Old December 13th, 2012, 08:44 AM
kiteless kiteless is offline
Moderator
Dev Shed God (5000 - 5499 posts)
 
Join Date: Jun 2002
Location: Raleigh, NC
Posts: 5,091 kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level)kiteless User rank is General (90000 - 100000 Reputation Level) 
Time spent in forums: 2 Weeks 5 Days 2 h 53 m 27 sec
Reputation Power: 966
jQuery is just a JavaScript library, so if you can put files on the server you can use jQuery.

To get rid of the whitespace, you can wrap everything before your cfoutput in cfsilent tags.

Reply With Quote
  #8  
Old December 13th, 2012, 01:21 PM
Xophe Xophe is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2012
Posts: 11 Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 1 h 10 m 3 sec
Reputation Power: 0
You're preaching to choir . I've said the same thing to mgmt, but they're not ready to put the jQuery libraries on the servers just yet.

As to the whitespace, it turns out the code I was using for the process was based on an example of cfflush from the CF8 Livedocs. I realized that that loop was intentionally creating whitespace in order to get the cfflush example to work. So, I got rid of the loop, and also added <cfsetting enablecfoutputonly="yes">, and also wrote a simple js trim function to clean up the response text clientside if cf doesn't do the trick. If you're interested, I've included my cleaner, simpler code below (I'm putting it in and continuing this thread only because I'm dead set on figuring out the problem for the sake of anyone else who encounters the same and goes web surfing for a solution).

callAjax_v3.cfm:
Code:
<script>
var req;

function ProcessAjax(url) {
  // IE8 - has native  object
  req = new XMLHttpRequest();
  req.onreadystatechange = function() {displayTheLine();};
  req.open("GET", url, false);
  // null for GET with native object
  req.send(null);
}

function displayTheLine() {
  if (req.readyState == 4 && req.status == 200) {
    var results = fncTrim(req.responseText);// take off any whitespace from the response
	var theDiv = document.getElementById('theDiv');
    theDiv.innerHTML = theDiv.innerHTML + results;
  }
}

function fncTrim(str) {
	str = str.replace(/^\s+|\s+$/g,'');
	return str;
}
</script>

<div id="theDiv">Here come 10 random numbers...<br></div>

<cfloop from="1" to="10" index="i">
	<script>
		ProcessAjax('createRandomNumber.cfm?rnd=' + Math.random());
	</script>
</cfloop>


and the page called, createRandomNumber.cfm:
Code:
<cfsetting enablecfoutputonly="yes">
<cfscript>
	sleep(1000);//delay by 1 second to simulate a longer process
</cfscript>
<cfset random=rand()>
<cfoutput>random number is: #random#<br></cfoutput>


I'm also researching for an answer as to why the ajax has to be synchronous in this example in order for it to work. If I set the 3rd argument of the open() function to "true" rather than "false", and thus make it asynchronous, it doesn't work in either FF or IE8. It displays the first line only, and then it quits.

Reply With Quote
  #9  
Old December 14th, 2012, 10:58 PM
Xophe Xophe is offline
Registered User
Dev Shed Newbie (0 - 499 posts)
 
Join Date: Dec 2012
Posts: 11 Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level)Xophe User rank is Corporal (100 - 500 Reputation Level) 
Time spent in forums: 1 h 10 m 3 sec
Reputation Power: 0
The answer...

I finally found this blog post, which explains why I (and lots of other people) are having this problem with IE when using AJAX synchronously: http://www.blacksquare.co.za/blog/?p=458.

IE intentionally delays rendering layout changes until the entire javascript thread has completed. If you use AJAX synchronously (or SJAX, I should say), the return processing is done on the same thread, so the rendering is delayed until after the response has been processed.

And so the solution, according to this blog post, is simple - don't do it. Use AJAX asynchronously, which, so I keep hearing, is the ideal approach 99% of the time.

If interested, I've been discussing this problem and my new approach in greater detail at http://www.codingforums.com/showthr...010#post1300010

Reply With Quote
Reply

Viewing: Dev Shed ForumsProgramming Languages - MoreColdFusion Development > Ajax instead of cfflush?

Developer Shed Advertisers and Affiliates



Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.

© 2003-2013 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap