Ask a Jedi: Extending ColdFusion's auto-complete feature
David asks what I think is a pretty interesting question concerning ColdFusion, Ajax, and auto-complete style functionality.
I know you have covered the CF8 autocomplete tag, but I am looking to take it one step further, but haven't been able to find any good direction.
I have been building an application for our amateur radio emergency services group that allows us to track our weather spotters while they are in the field. Logging ham operators to the net requires collecting the same information from many time the same people over and over.
I would like to use a form that when the first field is enter (the callsign of the operator) it does a trip to the database and if the ham has checked into a net before, bring back his information and auto complete the remaining form fields.
Example, the first field is Call Sign, I would enter mine, N9CTO and the next three fields would become populated. Those fields would be First Name, Trained Spotter, and my car information to be verified.
I know this is a very specific example, but with CF8, Autocomplete, AJAX I figure this can problem be completed. If I knew Javascript more, I could probably do that as well, just curious to know if the autocomplete can be extended to not only suggest in the first field, but drive answers in the remaining fields. Obviously, if the first field doesn't match in the database, we would enter the details then in the future, our weather spotter would be in the database.
Ask a Jedi: Two CFGRID Questions
Joel asks:
I have problems with using CFGRID and hope you can help. Here are my issues:
1. When sorting the 2nd and 3rd columns sort ok, the first causes an error stating an "Error in executing the Query".
This is actually not a CFGRID issue, but an issue with your data provider, which is most likely a CFC. You need to debug why your CFC is throwing an error. This can be done multiple ways. The easiest is to use Firebug - not the request throwing the error, and open the request in a new tab. You will see more information about the error.
2. And is there a way to prevent the columns from being moved?
Well, I'm not sure why you would want to block that, but if you get access to underlying grid object (using ColdFusion.Grid.getGridObject(), you should be able to use the Grid api to disable this behavior. You may have to look up the Grid docs at Ext first though. (And yes, I'm being lazy, but I figure telling you where to look is a bit helpful. :)
Now let me assume my Stan "I think I've learned something" pose: This blog entry speaks to two topics I've covered a few times before, and I really think it touches on folks who are just now getting into Ajax stuff because of ColdFusion. It is critical you get that:
a) Learn to debug. Tools like Firebug are critical for figuring out what went wrong with an Ajax-based request. You must - I repeat, must get familiar with this as it will make your life much easier to handle.
b) Remember that the Ajax tools that ColdFusion 8 uses are all based on third party tools. You can (and should) go to those sites - read the docs - and get familiar with them if you want to go "beyond the basics" in terms of how you use them within ColdFusion.
ColdFire Update
While not the most important news today, Nathan has released a new update to ColdFire. He talks about the update here:
While there are a number of changes, the big one is the request queue. This means that if you hit a ColdFusion page with Ajax requests, you can introspect all of the ColdFusion debugging information for everything in the browser. This doesn't work well with ColdFusion 8's built in Ajax requests since they pass flags to disable debugging, but for your own Ajax code (like Spry sites) this is awesome!
RIA Dev Shed Review (and Files)
This past Friday I spoke at RIA Dev Shed, a one day RIA-oriented conference held in Salt Lake City. It was organized by Matthew Reinbold (with many sponsors as well) who did a great job and really helped make it easier on the speakers. The conference was very small - around 50 people - which made it a very nice, small, intimate event which I think is a great change from the 'mega-conferences' like MAX. The talks were great and very high quality I spoke on Spry and I've included my slides and code in this blog entry.
I also want to thank the travel gremlins who decided to make a come back. I arrived at the airport and went to the Continental desk. They told me I was on a 'code share' and needed to check in at Delta. No big deal. The Delta representative asked me if I had a "flight coupon." I had never heard of that so I said no. She said no problem, printed me out my boarding passes, and all was well.
Until I went to get on the plane. The Delta gate agent noted that my boarding pass said I needed a flight coupon. I told them that their representative down stairs had said I was fine, but they were having none of it. Luckily there were some phones one gate over... but the lady there kept me on hold just long enough for a) my plane to pull back and leave and b) to tell me, sorry, go to Continental.
So I go back outside security, and Continental tells me that everything is fine on their end, and if Delta had just called, I'd be ok. Of course, the flight they got me on was later in the day, after my connection to Lafayette, and all the flights were booked, so I was looking at spending the night in the Houston airport (and frankly, I'd rather spend the night in a pile of dung). Luckily my awesome wife packed up the kids and drove over to Houston to pick me up.
Any way, I'm glad to be back home with the nice warm weather and the proper beer!
Ask a Jedi: Is my site slow because of Ajax or something else?
Paul asks:
I've been working on a project using Mach-II and Spry, which can be viewed at here. I'm using a Spry master-detail layout on each pages. All of the content is stored in xml files. So, I have Spry datasource configured for each page also.
I'm wondering if the slow page loading is related to Mach-II or Spry. The site is running on a shared hosted server (viux.com). If it's related to Spry, then could some of the problem be resolved by pre-loading the data sources somehow. If so, how would that be done with Mach-II.
I see you've delved into Spry, just not sure how far, or whether my question even makes sense. Anyway, let me know if you can help. I've trawled through Google and not getting many answers. Other people have complained about the slow loading on the Adobe website, but no answer was furnished to that particular point.
Perhaps if you browse my website as shown above, you can see what I mean. The page initially loads real slow, but after its loaded, it's fine. But customers will be gone before that happens.
When it comes to answering "Why is my page slow", there are a number of things you need to look at. A typical request to a ColdFusion site normally involves these items:
- User request URL X.
- CF works on creating the response to X.
- CF returns a response (just a stream of text) to the browser.
- The browser renders the response. This may involve more HTTP requests for CSS, images, and Ajax items.
So which of the above is the slow portion of your site? It seems like the response from the server is a bit slow. Since you are using Mach-II, one of the first things I'd check into is to see if the framework is reloading. If Mach-II is like Model-Glue, there is a setting that determines if the entire framework should reload on every request. This can really slow down the response and you are recommended to turn this off in production. I'd bet Mach-II is the same, and I'd check there first.
My gut here says the issue isn't Ajax. Using Firebug (you are using Firebug, right?) I see that your XML being returned is very little (3KB). Your Spry files look fat, so I'd be willing to bet you aren't using the minimized versions. I'd switch to that.
You also want to get the YSlow plugin to Firebug. As you can guess, it tries to tell you why your site is slow. Your grade was an F, but I'm not sure why. Most of the things it failed you on seemed minimal to me. Your C for JavaScript files doesn't surprise me.
How good is the connection to your site? It may just be the network between here and there. Since your site involves China goods, I'm guessing it may actually be in China. Is it? If so then you could always consider multiple servers based on the location of the requestor. (I've never done that myself.)
I'll let others chime in as well on things they may see in the request.
Quick RIAForge Update
I just spent five minutes on RIAForge changing the search page to use JSON instead of XML. I know I've said this before, but you got to love the size differences. Before the change, the size of the XML packet downloaded was 152KB. With JSON it's down to 72KB.
For those who may view source - please note that I didn't really touch much else - so the code could be even better probably (using the Paged Data support instead of my manual paging for example).
I've blogged about how I integrate Model-Glue with AJAX before, but here is a quick recap. When I make an event that is meant to serve data up to an Ajax client, I first broadcast my message to get my data:
<message name="GetApprovedProjects">
<argument name="mode" value="short" />
</message>
I then broadcast a generic message:
<message name="ToJSON">
<argument name="viewstatekey" value="projects" />
</message>
My controller code for ToJSON does:
<cffunction name="toJSON" access="public" returnType="void" output="true">
<cfargument name="event" type="any">
<cfset var viewKey = arguments.event.getArgument("viewstatekey")>
<cfset var data = "">
<cfset var json = "">
<cfif arguments.event.valueExists(viewkey)>
<cfset data = arguments.event.getValue(viewkey)>
<cfset json = serializeJSON(data,true)>
</cfif>
<cfset arguments.event.setValue("json", json)>
</cffunction>
So in case that isn't obvious - what it means is I can broadcast any message and just pass the results to a generic JSON converter. (The view just dumps out the JSON string.)
BACFUG Spry Preso Files
I'm a bit late on this (been vegging out with the kids since I got back home) but attached this to blog entry are the files and slides I used at my BACFUG presentation last week. You can view the recording here: http://experts.acrobat.com/p24637610/
I want to thank the BACFUG for having me, and thank Donald Booth (one of the Spry engineers) for helping me out during the presentation.
Ask a Jedi: Ajax-bound requests and onRequest
So this is definitely something I've covered more than once, but as the questions keep coming in, I'm going to keep blogging it. My real hope is that Adobe listens in here as I think this is something that really needs changing in ColdFusion. Anyway, the question, from Samer:
I found a wired case, if you use onRequest function in Application.cfc and use cfgrid with bind attribute, it always return empty query to the grid "Response is Empty" !!
Can you help?
This is a fairly simple problem. onRequest, if it exists, breaks all flash remoting and CFC calls (remote calls I mean). Make sure you understand that. It doesn't matter what you do in onRequest - the mere existence of the method will call Flash Remoting/CFC (Remote) operations fail. Period.
As I said, this is something I truly wish Adobe would just fix as all it does is trip people up.
There is a way around it. Sean Corfield has a nice little work around that involves adding the following code to your onRequestStart (not onRequest, but onRequestStart):
<cfif listlast(arguments.thePage,".") is "cfc">
<cfset StructDelete(this, "onRequest") />
<cfset StructDelete(variables,"onRequest")/>
</cfif>
Interesting ColdFusion 8, Auto-Suggest issue to watch for
Thanks to Ed Tabara for pointing this out. If you type "1" in the search field at ColdFusion Bloggers, you will get a JavaScript error:
The page at http://www.coldfusionbloggers.org says:Bind failed for autosuggest search_query, bind value is not a 1D array of strings [Enable debugging by adding 'cfdebug' to your URL parameters to see more information]
If you introspect the result from my server, you see something like this:
[10.0,123.0,"1ssblog","1smartsolution"]
Notice that the first two results were numbers, not strings. I tried to 'fool' JSON a bit. I added "" to the number to see if that would do it and it didn't work. Interestingly enough, if you add " " to your data, serializeJSON will keep the padding on the strings, but removes it from the numbers. So even though my data was "10(space)", serializeJSON ignored it.
So it looks like 2 possible bugs. The client side code should allow for any simple value in the array - numbers, strings, or dates. And it looks like maybe serializeJSON is a bit overzealous in converting values. I can understand converting 10 to 10.0, but "10(space)" should be left alone, especially if "Ray(space)" is left alone.
Ask a Jedi: ColdFusion 8 Ajax Features and JavaScript Detection
Justin asks:
CF8 brought us some pretty rad RAD tools for quick and dirty AJAX and SPRY stuff. However, they did not provide a quick and dirty browser detection method to go along with it. I'm using ugly stuff that isn't so rad or RAD to handle this.
Is there something out there we can include in any necessary page that would direct users to an informational page regarding their unsupported browser? The last customer actually had IE7, but their shop has always used Netscape 7. Unfortunately, CFDIV did not like it, but the user had no idea that entire section of information was invisible.
If I were going to program this, what would be the best CF8 way to go about it? A CFC stored in the application scope? Perhaps checkUserAgent() function with a couple of options for the browser requirements? The same CFC could probably have robot checking as well. Naturally, it shouldn't be used for security, but something is definitely needed.
Once someone does this, it should definitely be dropped on RIAForge as I consider all the new CF 8 SPRY tags to be completely useless for Internet sites without browser detection, intranet is just fine.
So first off - I'm not aware of any ColdFusion-based browser detector. I'm sure some exist. I know I wrote code in that area around 7-8 years ago. It can be done - but it tends to be kind of a pain in the rear. I've also used BrowserHawk in the past. This is a third party tool that provides checks for just about everything.
Secondly - browser detection isn't trivial. I don't think its fair at all to call all the cool new Ajax stuff useless. (Note that CF8's Spry integration is just one small part.) Not every organization needs serious browser detection. I rarely see it myself anymore. I do often see "You need X and Y", which I think is fair and - lets face it - a heck of a lot easier then multiple browser detector tests. That's almost like saying ColdFusion's charting features are useless because some people don't have Flash (all 3 of them - they live next door).
You could try a few simple tricks - for example, this code will show a message to folks with JavaScript turned off:
<cfdiv bind="url:test3.cfm">
No JavaScript? You Suck!
</cfdiv>
If they have JavaScript turned on, the contents of test3.cfm load. It's a rather trivial trick, but it at least can check for JavaScript access. Once past that your best best is to feature detection, not browser detection. So for example:
if(document.images)
Checking for document.images is much simpler than checking a user agent and version, and it accomplishes what you want ("Does the browser support using JavaScript to load images?")
As always - I'm curious as to what others out there are using. Is it just me or are 'browser detector pages' going away?

