Use Spry's New Auto Suggest Widget To Handle Large Numbers of Suggestions
Introduction
In mid-March 2007, the Adobe Spry team provided developers with a sneak peak at the upcoming Spry 1.5 release (see reference 1). As part of this update, the Auto Suggest widget was given additional capabilities. A new feature of the Auto Suggest widget is the ability to specify a minimum number of characters before auto suggestions are shown and also to dynamically get the auto suggestions from a server, rather than from a cached data set.
The sample code provided in the Spry 1.5 Preview did not include using a ColdFusion backend that was pulling data from a database to populate the auto suggestions. So in this blog entry, I'll explore how you can use ColdFusion on the backend and Spry's updated Auto Suggest widget on the front end to handle large numbers of auto suggestions.
View an example based on this blog entry.
References
- Adobe Spry 1.5 Preview
- Using Spry Widgets: Auto-suggest Overview
- Adobe Spry Auto Suggest Widget Sample
- Bruce Phillips Blog, Return XML to Spry
ColdFusion Backend
I am using a CFC named CXML.cfc, which is located in the same folder as my example. This CFC has the following function.
<cffunction name="getTitles" access="remote" returntype="xml" output="false" description="Returns submission titles">
<cfset var titleQry = "">
<cfset var titleXML = "">
<cfset var parsedTitleXML = "">
<cfquery name="titleQry" datasource="STFM_Presenter">
SELECT top 100 pres_title as title
from submissions
where accepted = 1
<cfif StructKeyExists(URL, 'title') >
and pres_title like '%#URL.title#%'
</cfif>
order by pres_title
</cfquery>
<!---use Ray Camden's toXML CFC to convert the query to an XML file--->
<cfset toXML = createObject("component", "toXML")>
<!---use the queryToXML function to convert the query results to xml text. dataset will be the name
for the root node and row will be the node that repeats for each row in the query result--->
<cfset titleXML = toXML.queryToXML(titleQry, "dataset", "row")>
<!---convert the XML text into an XMLDocument object since we are returning XML--->
<cfset parsedTitleXML = xmlParse( titleXML ) >
<!---Set the content returned so that Spry will recognize it as XML. This command is not needed for
Flex 2.0 to use the XML returned, but is needed for Spry. Without this line Spry does not
recognize the returned value as XML.--->
<cfcontent type="application/xml; charset=UTF-8">
<cfreturn parsedTitleXML />
</cffunction>
I'll use this function to provide the XML data set to Spry. The database query returns the first 100 records matching the where criteria. Note that if the URL that calls this CFC function (since the access of the function is remote, this CFC function can be called like this: /spry/Spry_P1_5_Preview/autosuggest/cfxml.cfc?method=getTitles ) includes a title parameter then the where clause will search for pres_title containing the title parameter's value.
The function uses Ray Camden's toXML CFC to create an XML document using the query results. Consult reference 4 above for more information about how to use ColdFusion to return XML to Spry.
Auto Suggest Front End
Consult references 2 and 3 for how to use the basic Auto Suggest widget. I'm just going to cover what you need to do specify the minimum number of characters and to dynamically get the auto suggestions from the ColdFusion backend.
If you view the example's source code, you see the following javascript in the head section.
var dsTitles = new Spry.Data.XMLDataSet("cfxml.cfc?method=getTitles", "dataset/row");
This javascript creates a Spry data set named dsTitles. This data set will contain the results of running the query in the getTitles function of the cfxml CFC. So initially this data set will only have the top 100 records.
Farther down in the example I create the code to do the auto suggestion. Consult reference 2 for how this code must be written.
<div id="title" class="container" style="float:left">
Enter Part of The Title:
<input type="text" id="title" size="100"/>
<div id="titleMenu" spry:region="dsTitles">
<div spry:repeat="dsTitles" spry:suggest="{TITLE}">{TITLE}<br /><br /></div>
</div>
</div>
<InvalidTag type="text/javascript">
var titleAS = new Spry.Widget.AutoSuggest("title", "titleMenu", "dsTitles", 'TITLE', {minCharsType: 4, loadFromServer: true, urlParam: 'title'});
</script>
The javascript where I create a new AutoSuggest object has a series of arguments. the arguments inside the { } specify the following (taken from reference 2).
Option | Definition | Default | Values |
---|---|---|---|
minCharsType | This determines how many characters have to be typed before results are listed. This is helpful in improving performance, esp. if retrieving results directly from the server | number | |
loadFromServer | This attribute will fetch results from the server directly, rather than from the cached data set. This will trump the default data set caching setting and always fetch the results from the server. | false |
|
urlParam | This is the URL parameter name to which the search field value is attached. i.e. www.adobe.com?urlParam=searchValue |
required if loadFromServer is true. |
These arguments inside the { } are optional and there are other optional arguments you can use (consult reference 2). In my code, I am specifying that the user must type in 4 characters before showing any auto suggestions that match those 4 characters. Also, I want to get the data set from the server after the user types in those 4 characters and not use the cached data set that was initially created when the page loaded. Lastly, the name of the URL parameter that Spry will use when it calls the CFC to recreate the dataset is named title. The value for this parameter will be the first 4 characters the user types into the title text input box.
So in my example, after you type 4 characters, Spry recreates the data set by calling the CFC getTitles function. Since the title URL parameter exists, the query in this function will return the top 100 titles that contain the parameter's value. This data set is then used to show the auto suggestions to the user.
Why Use loadFromServer and minCharsType
The standard auto suggest widget just uses the data set that is created when the page loads. This works fine if the data set is not very large. But let's say you have thousands of possible titles. Creating that large of an XML data set could be time consuming depending on the user's network connection, your server's capability, etc. Then, even after creating the very large data set, filtering that large data set as soon as the user types a character may also not be very responsive. Using loadFromServer and minCharsType can reduce significantly the amount of data that must be transferred from the server in order to show the auto suggestions and make the page and auto suggest widget more responsive. If you have a very large data set of auto suggestions, I would consider using the new Auto Suggest widget and its loadFromServer and minCharsType options.
CAVEAT
I'm not a Spry expert. Also there is not much documentation about and examples of the upgraded Spry 1.5 Auto Suggest widget and these new options. So if I've screwed something up or explained something incorrectly, please post a comment.
great info but about the adobe spry project i could only find references about cfm,
could someone here tell me how to make the loadfromserver work with a php request?
i have the suggest working but as soon as i request from server nothing happens...
i one can help i'd be very gratefull
thanks anyway
new Ajax.Autocompleter('buscar','update','response.php', { tokens: '', callback: function(objImput, queryString){
return queryString+"&comuna="+document.getElementById("textcomuna").value+"&nombre="+document.getElementById("buscar_inter").value+"&tpo1="+document.getElementById("tpo_1").value;
}});
this allows me to $_post more url Parameters than just only urlParan ('buscar') for Adobe Spry...
Can you help searchout for it...