Raymond Camden's Blog Rss

Ask a Jedi: ColdFusion Ajax example of retrieving fields of data (2)

19

Posted in ColdFusion | Posted on 10-18-2009 | 3,994 views

Earlier today I blogged a simple example of using ColdFusion Ajax controls to load detail information based on a primary key. The reader who asked the question sent me a followup asking if it was possible to change the form to use a button instead of a keypress to load the data.

Using the second code sample from my previous entry, I added a button next to the ID field.

view plain print about
1<cfform>
2id: <cfinput type="text" name="artid" id="artid"> <cfinput type="button" name="mybutton" value="Lookup"><br/>
3name: <cfinput type="text" name="artname" id="artname" readonly="true"><br/>
4description: <cftextarea name="description" id="description" readonly="true"></cftextarea><br/>
5price: <cfinput type="text" name="price" id="price" readonly="true"><br/>
6</cfform>

Now for the weird part. It's easy enough to bind to a button. I'd just use {mybutton@click}. However, I still need the ID value. So in order to bind to the CFC, I'd have to use:

view plain print about
1<cfajaxproxy bind="cfc:test.getData({artid@none},{mybutton@click})" onsuccess="showData">

Unfortunately, this then requires that the getData method have a second argument. I could just add a dummy argument to the method, but that felt wrong. I decided to take another approach.

The cfajaxproxy tag allows you to bind to JavaScript functions as well. I switched my tag to the following:

view plain print about
1<cfajaxproxy bind="javascript:getData({mybutton@click})">

Next, I knew I still needed a way to communicate to the CFC. I added another cfajaxproxy:

view plain print about
1<cfajaxproxy cfc="test" jsclassname="dataproxy">

The next change was to add the getData function:

view plain print about
1function getData() {
2    var artid = ColdFusion.getElementValue("artid")
3    if(isNaN(artid)) return
4    dataService.getData(artid)
5}

I have to get the artid value manually so I made use of ColdFusion.getElmentValue. As before, I check for a valid number. Lastly I make use of dataService. What is that? I've added these two lines of JavaScript that make use of the new cfajaxproxy tag I added:

view plain print about
1var dataService = new dataproxy()
2dataService.setCallbackHandler(showData)

Basically, dataService becomes a proxy to my remote methods in the CFC. This is probably a bit confusing now so let me paste in the entire template:

view plain print about
1<cfajaxproxy bind="javascript:getData({mybutton@click})">
2<cfajaxproxy cfc="test" jsclassname="dataproxy">
3
4<script>
5function getData() {
6    var artid = ColdFusion.getElementValue("artid")
7    if(isNaN(artid)) return
8    dataService.getData(artid)
9}
10
11function showData(d) {
12    //convert into a struct
13    var data = {}
14    for(var i=0; i < d.COLUMNS.length; i++) {
15        data[d.COLUMNS[i]] = d.DATA[0][i]
16    }
17    document.getElementById('artname').value = data["ARTNAME"]
18    document.getElementById('description').value = data["DESCRIPTION"]
19    document.getElementById('price').value = data["PRICE"]
20    
21}
22
23var dataService = new dataproxy()
24dataService.setCallbackHandler(showData)
25</script>
26
27<cfform>
28id: <cfinput type="text" name="artid" id="artid"> <cfinput type="button" name="mybutton" value="Lookup"><br/>
29name: <cfinput type="text" name="artname" id="artname" readonly="true"><br/>
30description: <cftextarea name="description" id="description" readonly="true"></cftextarea><br/>
31price: <cfinput type="text" name="price" id="price" readonly="true"><br/>
32</cfform>

I hope this helps and shows yet another variation on the theme from earlier today.

Comments

[Add Comment] [Subscribe to Comments]

How would you add a "Clear" button?
I'm working on a part 3 for the original questioner, I'll try to get that in as well.
Hello Raymond, I recently applied the CF9 9.0.1 patch to our servers and now have an error when using the above solution. the error returns a WDDX packet parse errorat line 1 column 1. Content is not allowed in prolog. I have looked up this error and it seems to point to the way the data is being returned. Have you come across the same issue with using this example on CFP version 9.0.1.
Thanks
Matt
When you use Firebug, or Chrome Dev Tools, what does the Ajax response look like?
Hi Ray, i'm using Firebug and i don't really see anything that resembles the Ajax response. The code just looks like the Standard CF error html. I have expnaded the Ajax error line in the console and looked on the response tab and see the standard CF error html output.
You don't see _any_ Ajax response? There is definitely one there. Is this online where I can see?
Hi Ray,
I can shed a little bit of light on Matt's issue: The difference between 9.00 and 9.01 that breaks the cfc invocation when using a local cfc with access="remote", is the substitution of quotes for curly braces. I've made a cfc available online on a dev server to illustrate the difference - let me know if you need to see it in it's page context or it is otherwise unavailable, I've just dropped our usual directory security on the cfc.

Works (the 9.0 version):
http://128.83.148.234/bookshopdoor/captcha.cfc?met...

Doesn't work:
http://128.83.148.234/bookshopdoor/captcha.cfc?met...
So are you running the same code as me then? The request is what's bad - as you said.
I don't know what all you're running, but the dev server where the request is bad is running Standard Edition 9.0.1 in a Windows Server 2003/IIS6 environment, and the production server where the same code works is running Standard Edition 9.0.0 in a Windows Server 2008/IIS7 environment. I've experienced the same issue with and without cfAjax on the page, and am not using any js libraries that don't come with CF out of the box.

The funny thing about this is the same function works in 9.0.1 when invoked on load, via &lt;cfset foo=CreateObject("component","captcha").createCaptcha()&gt;
but it fails in 9.0.1 when invoked via a JS function, like so:
&lt;cfajaxproxy cfc="captcha" jclassname="cfimageCaptcha"&gt;
&lt;script language="Javascript"&gt;
var refreshCaptcha = function() {
var jsCaptcha = new cfimageCaptcha();
jsCaptcha.setCallbackHandler(populateCaptcha);
jsCaptcha.createCaptcha();
}
&lt;/script&gt;

Spark any ideas?
Not off hand - if you can share _all_ the code via pastebin, and if I can hit it remotely to test, I can try. Or - if you can make a small folder that demonstrates that issue and email me that folder so I can run it here, I can try that too.
We just upgraded our dev server and getting the same issue. Any updates on this? Ray, if you need to get in, I can get you into our site.
This would normally be a paid engagement for me, but if you want to ping me via email I can take a quick look.
Anyone find a solution? Same problem... code was working perfectly with 9.0 and this error on 9.01. Just a simple AJAX call to a CFC. I guess I need to figure out how to downgrade to 9.0 if AJAX is broken with 9.01.
What do you see with Firebug or Chrome Dev Tools?
I ended up reverting to CF 9.0 which fixed the problem and AJAX is now working again. I will try and set up a simple AJAX test on a CF 9.01 server so I can reproduce the error. It was a very simple call to a CFC and like Frijoles said, the issue is CF 9.01 is using the wrong characters to escape quotes. Look at his examples... one is the way 9.0 escapes it, and the other is the way 9.01 does it. Those are generated by the coldfusion AJAX built it stuff.
Hi,

We are having the same issue of CF 9.0.1 breaking the CF Ajax Tag.

Is there any solution for this issue?
No solution found by me yet. Either you have to revert to CF 9.0 or stop using CFAJAX. On one site, I started using the JQuery AJAX and that works fine.
Thanks Ted for your response. Can you please show code sample of how to call JQuery and AJAX?

Thanks.

[Add Comment] [Subscribe to Comments]