Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

How can I make AJAX Synchronous?

Contributor ,
Dec 24, 2007 Dec 24, 2007
As a virtual newbie (once a CF5 virtuoso returning to programming after a 5 year delay), I'm thrilled to encounter the AJAX capabilities of version 8. But I just hit a problem: After a portion of my page loads (into a CFDIV via ColdFusion.navigate), I would like to focus the cursor on a particular <input> tag within it, but I get a Javascript error because the focus() tries to execute before the target <input> tag gets into the page. (To prove this, all I have to do is put an alert('waiting...') message just before the focus() statement.) So this is one time I need it to be synchronous. I notice in Ben Forta et al Adobe ColdFusion Application Development Volume 2, p. 348, that there's a setSynchMode for the <cfajaxproxy> tag (for other normally asynchronous situations, too, I wonder?). And on p. 344 it is stated that one can obtain 'a complete list of the available JavaScript APIs at the link below:

http://www.adobe.com/coldfusion/8/htmldocs/help.html?content=Part_3_CFML_Ref_1.html

However, as of this afternoon, 12-24-2007, that link does not work.

Four Questions:

1. How do I get to the API information? (I'll search the website but I thought I'd ask now in case my search is fruitless.)

2. Can ColdFusion.navigate be set to be synchronous?

3. If so (in case the answer to question 1 doesn't provide this), what is the correct syntax?

4. Or is there some other technique I should be using? An 'onload' in the AJAX-loaded form just occurred to me as a possible solution, but my O'Reilly HTML book does not list that among the form events...

Thanks for your help.
TOPICS
Getting started
1.5K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

LEGEND , Dec 27, 2007 Dec 27, 2007
here:

JobTypeCallback = function(){
document.fmGenInfo.TkDnStrt.focus();
document.fmGenInfo.TkDnStrt.select();
}

put that in your main page where your cfdiv is. tested in FF2, IE7 &
Safari 3 on Windows

---
Azadi Saryev
Sabai-dee.com
http://www.sabai-dee.com
Translate
Contributor ,
Dec 25, 2007 Dec 25, 2007
It dawned on me that the solution might lie in a callback function, which I had never tried before. I did try it, and it worked! However, I still wonder what the answers might be to my questions 1, 2, and 3!
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 25, 2007 Dec 25, 2007
Oops! I spoke too soon. Apparently It only worked because I had temporarily placed an alert inside the callback function just to track my progress. That provided the requisite delay as I noted earlier. So I still need an answer to question 4.

Oddly, even though letters which I type don't appear in the <input type="text"> control I attempted to place the focus in, Tab and Shift-Tab lead to the behavior one would expect if the cursor were in fact where I attempted to place it.
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 25, 2007 Dec 25, 2007
look up ajaxonload() function in those cf docs you printed out :)

---
Azadi Saryev
Sabai-dee.com
http://www.sabai-dee.com
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 26, 2007 Dec 26, 2007
Azadi, thanks for alerting me to that technique, which should be useful someday - and maybe useful for this problem, too, if we can figure out why it didn't solve it. At the bottom of the CFM which I'm loading, I inserted the following code: <cfset ajaxOnLoad("JobTypeCallback()")> (using the same function as the one I had tried to access via the callback process, whence the name. The function does nothing to attempt to focus() on an <input> tag in the form loaded by the CFM. And I get the same results with the ajaxOnLoad method as I got with the callback method: in both cases the function tries to run before the form gets into the screen. We know the function runs because of an Javascript alert which exists only there. And we know the CFM loads the form (although belatedly), since AFTER function completes, the form does show up on the screen right where it should be.

I get the same results regardless of whether I invoke the CFM via ColdFusion.navigate or by a source= attribute in the CFDIV or CFLAYOUTAREA. And it makes no difference whether I use the usual function JobTypeCallback() syntax vs. the JobtypeCallback = function() syntax on page 681 of the Reference Manual I printed out. The only difference between them is that placing the alert tag before the focus() statement provides enough delay to solve the problem in the callback case (though not in a real life situation where there would of course be no such alert statement), but it has no effect in the ajaxonload case, where it doesn't work regardless of where I place the alert statement.

It both cases it certainly seems that the method in question is not working as one assumes it must have been designed to work. What would be he point of a callback, or of an ajaxonload, if the function one hopes to run on completion of the CFM does not wait till the CFM completes?? Is there perhaps some parameter I should be setting in the ColdFusion Administrator to turn this functionality on?
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 26, 2007 Dec 26, 2007
PeytonT wrote:
> Azadi, thanks for alerting me to that technique, which should be useful someday
> - and maybe useful for this problem, too, if we can figure out why it didn't
> solve it. At the bottom of the CFM which I'm loading, I inserted the following
> code: <cfset ajaxOnLoad("JobTypeCallback()")> (using the same function as the
> one I had tried to access via the callback process, whence the name.

the correct syntax is actually <cfset ajaxonload("JobTypeCallback")> -
note NO () after function name.
try that fist.

if it does not help - please post sample code to illustrate your problem
- it is a bit hard to guess what to change in your code without seeing it...


---
Azadi Saryev
Sabai-dee.com
http://www.sabai-dee.com
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 27, 2007 Dec 27, 2007
First, many many thanks for solving HALF my problem. All I had to do was remove the parentheses and the code is working beautifully if the data to be loaded already exist in SQL Server. When the data do not exist yet, the situation is improved - sort of. Now placing the alert statement before the focus statement does give it time to work, like what happens with the callback method, though of course we can't have the alert statement there when it all goes live.

The code on the server is as follows. In PostJob.cfm (it's a system for court reporters to report back on how their reporting job went), the server code says:

<CFIF HaveGenInfo>
<!-- Since we have the jobtype, display the General Job Information from populateGenInfo right away -->
<cflayout type="hbox">
<cflayoutarea style="width:100%; height:117px"
source="populateGenInfo.cfm?jobtype=#Session.GenInfo.jobtype#" />
</cflayout>
<CFELSE>
<!-- Wait till we know the JobType, then provide a form for General Job Information via ColdFusion.navigate -->
<cfdiv id='getGenInfo' name='getGenInfo'/>
</CFIF>

When an earlier SQL SELECT to GenInfo produces a record (HaveGenInfo is true), as you can see, a <cflayoutarea> is populated via source="populateGenInfo" (on which more in a moment). When no record comes back, a <cfdiv> is waiting to receive the data after the user tells us the job type, which he does via a <cfwindow> containing a set of HTML radio buttons, which I abbreviate here with only job type "1":

<CFIF not HaveGenInfo>
<cfwindow name="theJobType" title="What kind of job was it?" headerStyle="background-color:c10026" modal="true" height="130" width="400" x="280" y="90" initShow="true" closable="false" resizable="false">
<input type="radio" name="JobType" value='1'
onclick = "JobTypeClick(this.value)">Transcript
</cfwindow>
</CFIF>

That takes us to JobTypeClick(), the code for which is:

function JobTypeClick(type){
ColdFusion.Window.hide('theJobType');
// for now we ignore the user's choice and go with type 1
ColdFusion.navigate('populateGenInfo.cfm?cfdebug','getGenInfo');
}
(as you can see, it begins by closing the window which asked the user for the job type; an earlier version added the third parameter, JobTypeCallback, not in quotes)

The goal is to pass the job type as a parameter to populateGenInfo, although at present that's hard-coded into the CFM in hopes of getting it to pay attention to my request to cfdebug (which it still ignores, although I did set it for AJAX debugging in the CF Administrator).

The code in populateGenInfo.cfm consists of:

<cfscript>action = Iif(Session.GenInfo.RecordCount eq 0,DE("insert"),DE("update"));</cfscript>

<cfset cjobtype="1">
<cfswitch expression=#cjobtype#>

<cfcase value="1">
<TABLE BORDER="1" CELLPADDING="4" WIDTH="100%" CELLSPACING="1" class="blackbgtable">
<form method="POST" id="fmGenInfo" name="fmGenInfo"
action="saveGenInfo.cfm?jn=<cfoutput>#Session.sJobNo#&mode=#action#"</cfoutput>>

-- body of table goes here --

</TABLE>
/cfcase>

<!-- Add other cases later -->

</cfswitch>

<cfset ajaxOnLoad("JobTypeCallback")>

So that's it.

Any ideas?
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 27, 2007 Dec 27, 2007
Oops, I forgot JobTypeCallback, which is:

JobTypeCallback = function(){
//alert('callback');
document.forms['fmGenInfo'].TkDnStrt.focus();
}

As I mentioned, the other syntax, function JobTypeCallback(), produces the same results.

Again thanks for your help.
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 27, 2007 Dec 27, 2007
Also, just as with the callback method, if you hit Tab or Alt-Tab, the cursor moves to the input field either just before or just after the one I tried to focus() (respectively), but the cursor does not appear there, nor do typed characters.
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 27, 2007 Dec 27, 2007
you are not testing just in IE, are you??? in FF it works just fine if
you place your callback function in your MAIN PAGE, where your cfdiv is,
in the <head> section.

IE stubbornly refuses to set focus... i think you have to use
SetTimeout() o make IE work...

---
Azadi Saryev
Sabai-dee.com
http://www.sabai-dee.com
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 27, 2007 Dec 27, 2007
here:

JobTypeCallback = function(){
document.fmGenInfo.TkDnStrt.focus();
document.fmGenInfo.TkDnStrt.select();
}

put that in your main page where your cfdiv is. tested in FF2, IE7 &
Safari 3 on Windows

---
Azadi Saryev
Sabai-dee.com
http://www.sabai-dee.com
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 27, 2007 Dec 27, 2007
Unfortunately, setTimeout doesn't solve the problem. In testing the code below, I have tweaked only the alert (commented out vs. in), and the number of milliseconds delay.

JobTypeCallback = function(){
alert('callback');
setTimeout('document.forms["fmGenInfo"].TkDnStrt.focus()',1);
}

I'm beginning to think that the crucial factor may not be the DELAY after all. In fact the form (the table displaying GenInfo data) appears instantly in the screen ('instantly', of course, from the point of view of a a carbon-based life form like me), and in running the version above, if I press Enter the very instant I see the alert (as fast as the reaction time of this carbon-based life form will permit) the cursor appears in the field requested.

This at least suggests that the crucial factor is the alert itself, not the delay it makes possible, especially when you consider that with the following version the cursor never does appear even after waiting much longer than 8 seconds.

JobTypeCallback = function(){
//alert('callback');
setTimeout('document.forms["fmGenInfo"].TkDnStrt.focus()',8000);
}

I confess that for the most part I am indeed testing only in IE. Although hate Big Brother (Microsoft) as much as the next guy, I can't afford to let that stand in the way of getting things done as quickly and easily as possible, and what I'm writing for is essentially an intranet from the point of view of the users, who will be only the 20 or so court reporters who work for my client. I was thrilled to learn that FF has debugging abilities which are so far superior to those in IE, but I have used them only sparingly since I find that some of the DOM functions I'm using don't work in FF (getElementById, for example). I'd like to write code that works for both, and maybe I will given time, but I'm already worried that my client will be displeased with the number of hours I'll be reporting! And even assuming I write it to use only DOM functions which work in FF, unless I can make it work in IE I will still be faced with telling the users they can only use one or the other browser, and the computer illiterates among them will probably already have IE.

I don't blame you if this leads you to throw up your hands (after all, I'm already grateful that your advice has solved the problem for the source='populateGenInfo' situation), but I still hope you might have other suggestions. Meanwhile, I'm going to attach an onload statement to the fmGenInfo form itself just in case my O'Reilly HTML book was mistaken in not listing it among the available events for forms!
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 27, 2007 Dec 27, 2007
Another potentially useful datum: As expected, attaching an onload event to the form had no effect, but an interesting result emerged in the process. In testing that version, I temporarily removed the <cfset ajaxOnLoad("JobTypeCallback") statement from populateGenInfo.cfm, which means that at the moment there's nothing that attempts to access that function, hence nothing that attempts to focus() on the desired <input> field of the fmGenInfo form. The result is that the cursor is not focused anywhere, but 'resides', so to speak, in a staging area just above the first editable field on the page, which occurs in a form ABOVE form fmGenInfo. So if you press tab, cursor appears in the first field of THAT form. This tells us that, when JobTypeCallback does run, the statement document.forms["fmGenInfo"].TkDnStrt.focus() does get executed, and it puts the cursor just where it was asked to put it, but invisibly so. Indeed it seems to be truly 'in' the desired field since Tab sends it to the NEXT field, while Shift-Tab sends it to the last field in the form which precedes form fmGenInfo. But unfortunately it is not visible there, and does not respond to keyboard input other than the Tab keys apparently. In fact it does not even accept them invisibly since, if you key in something, Tab off, then back to the TkDnStrt field (the one I've been trying to place the focus in), what you keyed does not suddenly appear there.
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Contributor ,
Dec 27, 2007 Dec 27, 2007
Yippee, your solution worked! Thank you thank you thank you!

Although I already have my money's worth, so to speak (and infinitely more than that if you put 0 dollars in the denominator of the fraction!), can I prevail upon you for the answer one more question? While I was waiting I tried on other solution: switching from a blank cfdiv to one with bind="url:populateGenInfo.cfm?jobtype={fmJobType.JobType@click} (since the onchange event would report the previous value, not the one just clicked on), while taking the call to JobTypeClick() out of the JobType radio buttons. That didn't work, and I was surprised to find that it didn't even wait to put the JobType window up but just invoked populateGenInfo.cfm right away. That brings me to my question:

What, in general, is the difference between 'bind=' and 'source='? Since most, though not all, of the bind examples I have seen depend on an event in the element contained between the {} curly brackets, I had assumed that it must wait for that event. But now I see that it need not. What, then, is the difference between 'bind=' and 'source='? When would one use one and not the other?
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Dec 27, 2007 Dec 27, 2007
LATEST
i will try to give you a (hopefully) good answer later today - i am a
bit tied up in things right now.
meanwhile, if you have not seen it already, watch the cf8 ajax ui
features presentation by ray camden - very useful stuff:

http://experts.acrobat.com/p68173954/

---
Azadi Saryev
Sabai-dee.com
http://www.sabai-dee.com
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources