jQuery UI 1.8 has been out for a while now (see details on their blog) but I've yet to really find the time to play around with it. This weekend I finally took a look at it, specifically the new autocomplete widget, and I thought I'd whip up a few quick examples showing the control being used with ColdFusion.
To begin, I recommend taking a look at, and reading some of the docs, for the autocomplete widget. I'm only going to demonstrate a few aspects of it and the docs will give you the whole story. As with most things jQueryUIish (not a word, I know), you use the widget by simply pointing the library at a DOM item and "enabling" it. So for example, once I've got my libraries loaded, I can turn an input control into an autosuggest with one line of code. Obviously I can, and probably will, use more code to get fine grained control over the widget, but it really is pretty simple to use.
Let's start with a super simple example. This one is taken directly from the docs. The only thing I'll point out is - and this bugs me about all the jQuery UI demos, I'm going to show you the full source behind the code. It really bugs me that their View Source content never shows the included JavaScript and CSS commands. Yes, it is implied, but I know I had a hard time with this when I first began to use jQuery UI. When it comes to docs, I think it's always safe to assume less. Ok, mini rant aside. Here is a simple example of a static autocomplete. jQuery UI's autocomplete widget allows for both static, inline auto suggests as well as Ajax loaded content. We'll be looking at an example of that later on.
<script type="text/javascript">
$(function() {
var availableTags = ["c++", "java", "php", "coldfusion", "javascript", "asp", "ruby", "python", "c", "scala", "groovy", "haskell", "perl"];
$("#tags").autocomplete({
source: availableTags
});
});
</script> <input id="tags" />
<script src="jqueryui/js/jquery-1.4.2.min.js"></script>
<script src="jqueryui/js/jquery-ui-1.8.custom.min.js"></script>
<link rel="stylesheet" href="jqueryui/css/vader/jquery-ui-1.8.custom.css" type="text/css" />
As you can see, we begin with our includes. We grab the core jQuery library, the jQuery UI library, and the style sheet. For my demos, I've chosen the Vader theme for obvious reasons.
My JavaScript consists of only two real parts. I've got a hard coded list of values in an array. Next, I "enable" the autocomplete on a input control (identified by the ID tags) and tell it to source by my array. And that's it. I really love how easy jQuery UI makes things sometimes. You can test this online
Now let's make this a tiny bit dynamic. In my first ColdFusion version, I'll switch my categories to a ColdFusion variable. (And yes, this is still a static variable, but you can easily imagine it being sourced by the database.)
<cfset cats = "Adobe,Adoption,AIR,Books,ColdFusion,Flash,Flex,Groovy,Hardware,JavaScript,jQuery,Lost,MAX,Movies,Music,ORM,Politics,Television"> <script src="jqueryui/js/jquery-1.4.2.min.js"></script>
<script src="jqueryui/js/jquery-ui-1.8.custom.min.js"></script>
<link rel="stylesheet" href="jqueryui/css/vader/jquery-ui-1.8.custom.css" type="text/css" /> <script type="text/javascript">
$(function() {
<cfoutput>
var #toScript(listToArray(cats),"availableCats")#;
</cfoutput>
$("#category").autocomplete({
source: availableCats
});
});
</script> category: <input id="category" />
The first difference here is the cats variable. Again, this would normally come from the database but for now it's just a hard coded set of strings. Going down a bit, take a look at how I translate it to JavaScript. I make use of toScript, a ColdFusion function that translates variables into their relevant JavaScript versions. I first turn the list into an array however. After that, everything else is pretty much the same. You can take a look at this here. (And while there, do a View Source to see how the toScript generated my JavaScript.)
Ok, so while hard coded (or static) variables work, and are ok for small lists, most of the time you will want to load in the data via an Ajax call. The autosuggest widget makes that darn easy. If the value of the source attribute is a string, then jQuery treats it like a URL. In this example, I've pointed my source to a CFC:
<script src="jqueryui/js/jquery-1.4.2.min.js"></script>
<script src="jqueryui/js/jquery-ui-1.8.custom.min.js"></script>
<link rel="stylesheet" href="jqueryui/css/vader/jquery-ui-1.8.custom.css" type="text/css" /> <script type="text/javascript">
$(function() {
$("#category").autocomplete({
source: "service.cfc?method=searchcategories&returnformat=json"
});
});
</script> category: <input id="category" />
Notice that I pass in my method and returnformat. You need to remember that CFCs, by default, return WDDX. Luckily it is easy to get around that (in ColdFusion 8 and higher). The docs did not make it clear, but the name of the argument sent to your server is term. Here is the simple CFC I used.
remote function searchCategories(string term) {
var q = new com.adobe.coldfusion.query();
q.setDatasource("cfartgallery");
q.setSQL("select mediatype from media where mediatype like :search");
q.addParam(name="search",value="%#arguments.term#%",cfsqltype="cf_sql_varchar");
var result = q.execute().getResult();
return listToArray(valueList(result.mediatype));
} }
As you can see, this is nothing more than a simple query. Notice my search string is dynamic on both sides of the term value. This allows me to handle partial matches, so a search for Cold would match both ColdFusion and Ice Cold Baby. If you want to match only results that begin with a term, you simply change how your server side logic works. You can demo this here. The search is against the media table of the cfartgallery demo, so try terms like "Pa" to see a few results.
Ok, so the final demo is pretty cool I think. One of the issues most autocomplete widgets suffer from is that while humans like to work with strings (like "Beer"), the database prefers unique identifiers (like 13). So given that you may return a string, again, "Beer", when you post your form to the server, how do you handle knowing that the value "Beer" referred to row 13 in your database? Typically you need to do another database query. Not a big huge deal, but wouldn't it be nice if your autocomplete could work with both strings and numbers? jQuery UI's autocomplete does this and does it well! Let's begin by modifying our CFC.
remote function searchCategories(string term) {
var q = new com.adobe.coldfusion.query();
q.setDatasource("cfartgallery");
q.setSQL("select mediaid as id, mediatype as value from media where mediatype like :search");
q.addParam(name="search",value="%#arguments.term#%",cfsqltype="cf_sql_varchar");
var query = q.execute().getResult();
var result = [];
for(var i=1; i<=query.recordCount; i++) {
result[arrayLen(result)+1] = {};
result[arrayLen(result)]["id"] = query.id[i];
result[arrayLen(result)]["value"] = query.value[i];
}
return result;
} }
In this example I've changed from returning an array of strings to returning an array of structs. Notice that I've got an ID and VALUE key being returned. (*) These values will be recognized by the widget, specifically the value attribute. By itself this won't solve our problem, but we can use the "select" option to handle the user selection event:
This code says - when the user selects an item, grab the ID value and set it to the catid DOM item's value. Let's look at the complete page so it makes more sense.
<script type="text/javascript">
$(function() {
$("#category").autocomplete({
source: "service2.cfc?method=searchcategories&returnformat=json",
select:function(event,ui) {
$("#catid").val(ui.item.id)
}
});
});
</script> <form action="test3.cfm" method="post">
category: <input name="category" id="category" />
<input name="catid" id="catid" type="hidden">
<input type="submit" value="Submit">
</form> <cfif not structIsEmpty(form)>
<cfdump var="#form#" label="Form">
</cfif>
As you can see, I've added the select handler to my widget constructor. I've also added the hidden form field catid. Finally I added a real submit button and a cfdump so I can see the result. Now when I select a media type, the user will see the nice string, and the hidden form field gets the proper primary key. You can see this for yourself here. All in all I think it works really nicely.
Again - please note there is more to this control then what I've shown here. Check the docs and have fun with it! (And if you are using it in production, please feel free to share the URL here.)
* Did you notice I used struct notation ["id"] instead of dot notation? Dot notation creates JSON with upper case keys. jQuery UI won't pick up on that automatically. By using bracket notation I ensure my JSON maintains the same case.
component {
component {
select:function(event,ui) {
$("#catid").val(ui.item.id)
}
<script src="jqueryui/js/jquery-1.4.2.min.js"></script>
<script src="jqueryui/js/jquery-ui-1.8.custom.min.js"></script>
<link rel="stylesheet" href="jqueryui/css/vader/jquery-ui-1.8.custom.css" type="text/css" />
Archived Comments
Great post Ray.
I've just finished writing a magazine tutorial on the revised 1.8 UI, and had great fun playing around with the new features in the library, especially the autocomplete widget.
I love the use of the source param pulling in the data from the web service, and jQuery makes it incredibly easy to pull out the information as you've shown here using the ui.item method.
CF and jQuery go together incredibly well - both rapid development, both extremely extensible, both with a great community.
Am I missing something obvious with the demo . . . when I go to the demo it comes looking plain-vanilla form with no skinned elements. And, how would one hook it up using the Solr search engine? I'm thinking, like keep track of tables with entered information about stuff like book titles and descriptions of plots, and user searches for a particular book and it would "look" ahead for matching strings to search on.
@Lola: Exactly Lola - it is an autosuggest widget. You won't see _anything_ at first. Begin typing in the control field though, like the letter e, and you should see something.
As to your second point - you would simply change the db query to a cfsearch call instead.
I would be interested to see how it handles extremely long matching result lists. I have a place I was thinking about writing the auto complete in. Until it gets drilled down a bit things might be a little hairy (hundreds of results).
Thanks for the nice little demo Ray.
@Robert: Two things. One- you can control _when_ the auto suggest begins to look. There is a minlength attribute.
Secondly - _you_ have ultimate control over the data. I could have easily added a maxrows/top/limit to my query to keep things under control.
One thing that confused me for a few seconds in the demo...the auto-suggest list is case-sensitive. It threw me off when "p" didn't return "Painting". This is just a DB thing, and not a jQuery issue.
When using the demo "p" returns "Photography" but not "Painting". I thought this sample only returned 3 results, so I typed "pain". No results.
I can search for "hotogr" and "Photo", but not "pho".
Is this a jQuery issue? Is there a trick to not having it be case-sensitive? (I use a different jquery autosuggest plugin and was eager to see a demo of this one.)
I did something similar but with US states. It uses a call to a cfm page and serializeJSON to return the results.
http://www.jensbits.com/201...
@James: Yes, the db is case sensitive. I should have made that clear. That's a db issue - not a jQuery issue.
That's a sweet tip about how to return lower-case JSON variables from a remote CFC. I have always hated how CF serializes variable names to upper-case. Any idea why CF doesn't maintain the original case?
There isn't an original case really. When you do x.y=1, you aren't specifically a string, but a variable name. Well, that's my opinion anyway. There is probably some much more technical low-level reason why. ;)
I generally use bracket notation on a set and I suppose it has kept me out of trouble because I generally camel-case my vars. I also use *a lot* of AJAX/JSON and haven't really run in to a case problem. The one notable exception being returning queries through JSON.. :/
Thanks for the post Ray - I implemented a jQuery autocomplete a few months ago using calls to a cfm file. I'll remember this example if I want to tie it to a cfc instead. Do you think there is a performance gain doing the call with a component instead?
Performance - not really. I used an example of hitting a CFC because, typically, the type of data I'd need would come from a CFC.
jQuery is indeed quite easy to use.jQuery coupled up with CF is efficient for the development process.But I agree with Lola on it's dubiousness about usage with Solr search engine and also will the case sensitive factor remain with JSON when used by solr as output. I also reviewed Solr's complete reference guide (http://www.lucidimagination... ) for concept insights and found it useful.
I'm sorry - maybe I'm not quite getting you. It isn't case sensitive. My DB is. And I could have gotten around that I'm sure.
Hi,
Not really about autocomplete, but as you said that you had work a lot with JQuery the last time (and jqgrid ?), Could you maybe have an example on how to join a jqgrid cell to a popup window to show data from another table related to the clicked cell (foreign key)
I tried this with the fancybox(http://fancybox.net/home) plugin as follow:
custom formatter to show an icon and to put an id attribute to the 'a' tag as the plugin requires an id attribute. then I should have to link this id attribute to the .fancybox method... but... someone has maybe an idee to accomplish this ?
Greetings,
Michel
It sounds like you are saying - when a user clicks a row, show a dialog window - right?
Right, or more, when a user clicks a particular cell where you see an icon, but the data is the key to details data. This should have to open a popup window with those details. I got it working, but it opens the window I call to make the query. What I should like is to get this data not in a reloaded window, but in a little popup... and ideally in the fancybox jquery plugin... or what should also be nice in a tootip -)
Thanks for your reply,
Michel
Well it certainly should be possible. :) I know jqGrid is very powerful and obviously allows you to respond to click events. It sounds like you got that, but you need to get the data from the client side where it already exists. If you look at the jqGrid API (I'm there now) you can see methods to get the data from the grid.
I confirm, it is possible -)
I made a custom formatter to add an id attribut to the cell data (and btw an icon), and from there
I call a cfm giving the key as parameter to retrieve the data.
And instead of loading this in another page, I try to show this in a fancybox jquery plugin with this:
gridComplete: function(){
$("a[id='userDetails']").fancybox({'type':'ajax'});
}
});
My problem was only to get the userDetails id of the a tag to link it to the fancybox method.
This did nothing: $('#userDetails), but this is ok: $("a[id='userDetails']")
Thank you for your reaction,
Michel
Hi Ray,
I am newbie to jQuery.Kindly help for the below requirement.
I am having 3 controls say Department, Locations & Name.
In search form,If the user chooses a department with auto suggest & then he comes to location, we need to show all locations of that department in auto suggest and when he comes to Name control,we need to show only names of the persons working in selected values of department & location controls.
Like the way we need to filter, for the user chooses any of the control.
Let me know if you have any questions.
Thanks in advance
I'll be happy to help, but I think you have everything you need already. Remember the last part of my demo specifically mentions how you can store a primary key for the string in a hidden form field. You would use that value then for your second and third autocomplete lookups. You could just append the value to the URLs used.
Hi,
I am getting an empty string, when I try to read out a value of a first text box which I am using as a URL param for second text box.
Any clues,code as follows.
$(function() {
$("#department").autocomplete({
source: "test2.cfm"
});
$("#location").autocomplete({
source: "test2.cfm?department="+$("#department").val() //Value in the department text box need to get here & results need to be filtered based on Department
});
});
<form name="frm" action="test.cfm" method="post">
Department: <input id="department" />
Location: <input id="location" />
</form>
Is the full code online where I can run it? This is really a simple thing- it should work. :)
From Ray:
*********
$("#department").autocomplete({
source: "test2.cfm?vType=department",
select:function(event,ui) {
var sel = ui.item.value
$("#location").autocomplete("option","source","test2.cfm?vType=location&department="+escape(sel))
}
});
Thanks Ray, its working pretty good now.
I'll be doing a blog entry today that demonstrates this more fully.
Follow up blog post: http://www.coldfusionjedi.c...
I keep getting this error:
a is null
"string"){c=this.options.source;this.s...=this._normalize(a);this._suggest(a);
Any ideas?
Thanks
Mike
Nope - is it online where I can see it?
I'm all good now. I got a hint from another post where requestCFC was causing problems and apparently that was my issue too.
Thanks
Keep up the good work :)
Mike
hey raymond sorry bother you but its that the real CFC code? im newbee im and copying and pasted but
dosnt work
It was short enough to fit into a comment:
component {
remote function searchCategories(string term) {
var q = new com.adobe.coldfusion.query();
q.setDatasource("cfartgallery");
q.setSQL("select mediatype from media where mediatype like :search");
q.addParam(name="search",value="%#arguments.term#%",cfsqltype="cf_sql_varchar");
var result = q.execute().getResult();
return listToArray(valueList(result.mediatype));
}
}
i have the same question about this cfc code its that the real CFC code? and its doesnt work, can i get the full source code of the demo page, please ray
Not quite sure I get you. How does the CFC code not work? Can you be more specific? As for the code for the front end - you just need to view source.
Sorry Ray im newbee, i paste this code to a new cfc file
component {
remote function searchCategories(string term) {
var q = new com.adobe.coldfusion.query();
q.setDatasource("cfartgallery");
q.setSQL("select mediatype from media where mediatype like :search");
q.addParam(name="search",value="%#arguments.term#%",cfsqltype="cf_sql_varchar");
var result = q.execute().getResult();
return listToArray(valueList(result.mediatype));
}
}
should it use
<cfcomponent>
<cffunction>
"the code"
<cffunction>
<cfcomponent>
or could you just share the whole source, please.
Thank u Ray
No, the code is the whole source. It is a script based CFC. Are you on CF9? If not - the code will not work for you. You would need to convert it to a tag based one - including changing the script based query too. Shouldn't take more than 3 minutes though.
Oh i see, im running it on CF 8 ,okey i get it
Thank You Ray
Hey I know this post is a bit old but I was wondering if you know how I would go about using this being able to type multiple categories in. If you have any ideas on it please let me know.
Thanks
-Jay
How would it work? Like after you pick one would it add a comma and let you type more?
That is exactly how I would want it to work.
What do you think? Worth pursuing with jqueryui or should I see if there is another implementation out there that can do something like that?
Looks like jQuery UI already supports it:
http://jqueryui.com/demos/a...
Thanks Ray that's a good start. I'll have to configure it to have a hidden field with to put the ID's in for each selection. Thanks!
Thank you so much for this tutorial. It is the only reason that I got Autocomplete working on my current development project.
Glad to be of service!
love the lowercase json return. Any issue with using the following structure instead:
for(var i=1; i<=query.recordCount; i++) {
result[arrayLen(result)+1] = {
"id" = query.id[i],
"value" = query.value[i]
};
}
If that's JS, then you need to use arr.length, not arrayLen(arr). arrayLen is a CF function.
Is it possible to supply a zip with the full source code here? I mean, a complete zip file. I'm confused about implementing the CFC (new to CF -- but I'd love to see a specific example).
Does anything else need to be added to the CFC above?
Confused. (I just name it with the .cfc extension?)
Unfortunately I don't think I have the full folder anymore. I can say that the first script is a regular CFM. You can call it whatevr. Ditto for the very last code sample.
The CFC should be named service2.cfc. You can tell this by the URL used in the last code sample.
Does that make sense?
Thanks (again and as usual) for a really helpful post -
I'm missing something though - I'm getting a JSON return as I'd expect (according to firebug) - but no suggestion is appearing in the field. Any advice appreciated thanks Ray.
jquery:
$("#category").autocomplete({
source: "getNames.cfc?method=getContacts&returnformat=json"
});
and on the page:
<input type="text" id="category" />
Looks fine to me. Is this online where I can see?
Sorry Ray - it's not. I can publish it tonight (Australian time about 8 hours from now) or I can send you files in a zip.
Thanks for the prompt reply.
It's easier if you just let me know when it's live. No rush.
Fair enough - had a window of connectivity and was able to bump up the site. The query in the cfc uses a cookie based ID so you will need to log in (username=simon@hinesight.com.au pwd=simon) to see the functionality.
On the newAppointment page is the text field in question - entering s returns json data Simon and Sam but nothing appears in the field.
Really appreciate the help. Thanks
Did you mean to tell me the site so I can login? :)
echoes of "help me to help you" in my ears...
sorry - I added the site to the website field in the comments box- http://www.yournextvisit.co...
Thanks again Ray, apologies for being a bit of a dolt!
Simon
You aren't returning the values in the way. View my demo with Firebug (or Chrome tools), and you can see how the data is different. I made use of listToArray in CF. You are returning a query object I think.
Thanks Ray - I think my problem is to do with my attempt to translate your script cfc to a tag based one (still on CF 8).
This is what I tried:
<cfargument name="term" required="false" default=""/>
<cfset var myQuery = "">
<cfset var searchFor = arguments.term>
<cfset result = arrayNew(1)>
<cfquery name="myQuery"
query statements here
</cfquery>
<cfloop query="myQuery">
<cfset result[myQuery.currentRow] = structNew()>
<cfset result[myQuery.currentRow].firstName = myQuery.contactFirstName>
</cfloop>
<cfreturn result>
I'm not sure that the cfloop at the end is doing what I need.
Your data returns like:[{"value":"Painting","id":"1"}]
mine is currently like: [{"FIRSTNAME":"Simon"},{"FIRSTNAME":"Sam"}]
Thanks again for your help, it's really appreciated.
Simon
Well, first off, you want to try for lower case just to make your JS code a bit more readable. That's easy to do. Change .firstName to ["firstname"] or even ["firstName"]. Then you have the issue of letting the auto complete know what to use for display and ID. I don't remember the options offhand, but try using value instead of firstname for now.
Ok - I've amended the end of the cfc like so:
<cfset result[myQuery.currentRow] = structNew()>
<cfset result[myQuery.currentRow].id = myQuery.ID>
<cfset result[myQuery.currentRow].value = myQuery.value>
and I'm now seeing data that looks more like the data in the example - and I'm getting no errors in firebug. When I enter a value in the filed a container for the autosuggest appears, but still has no content.
I've uploaded the amended files if you want to observe the behavior I'm talking about, and I'm heading over to the jquery doco to revisit again. Thanks for the help (again).
Simon
You are still using "dot" notation, .id, .value. Change to bracket notation:
["id"]
["value"]
Awesome!
That got it Ray - thanks so much (for the patience as well as the help).
Simon
Hey Ray,
Have you ever seen the page throw an SQL command not properly ended error on the cfc? Here's some of the key debug info:
[Macromedia][Oracle JDBC Driver][Oracle]ORA-00933: SQL command not properly ended
The error occurred in C:\ColdFusion9\CustomTags\com\adobe\coldfusion\base.cfc: line 449
449 : <cfloop index="i" from="2" to="#ArrayLen(sqlArray)#">
And the query looks something like this:
select distinct table_column, table_column_id from db.table where table_column like (param 1) limit 0,15
It's odd that it is doing this. I mean, I barely touched any of the example code. I'm just researching if something like this would work for a page I'm working on.
I know there was a bug with CF9 that could cause this to occur
Nevermind, I had to check my sytax a little better. Looks like I had a small typo. Thanks anyways.
I am using Coldfusion MX 7 and had to utilize a different JSON solution because I don't have the luxury of CF8 (bummer). I'm also using Model-Glue. So, how do i get the search term in my controller since i can't just add an argument called term to my function?
Your Ajax calls pass data either via a GET call or POST. But that doesn't matter as Model-Glue will combine them all into the Event scope. So in MG, you just grab what was passed in and pass it to your model.
here is coldfusion wrapper for autocomplete in case anyone interested
http://www.thecfguy.com/pos...
I'm running into a problem where the values in the database contain commas; when I output the query results using the following, post titles with a comma in them return as two results instead of one.
<cfreturn listToArray(valueList(qSiteAutoCompleteSearch.postTitle)) />
Any idea on how to fix this?
Writing this by hand - ignore errors.
<cfset arr = arrayNew(1)>
<cfloop query="qSiteAutoCompleteSearch">
<cfset arrayAppend(arr, postTItle)>
</cfloop>
You are a beast! (That's a good thing.) Thanks, Ray. Not sure why I didn't think of that. Some days I wonder if I should take up funambulism.
Thanks for sending me to the dictionary. ;)
Hi. Thanks for the excellent tutorial. I was lost for a while with why the suggestions weren't displaying in my development environment. Firebug displayed the json from my cfc ok and everything else was fine. Then I had a mini brainwave and turned cfdebugging off and the suggestions magically appeared. Has anyone else had this issue and found a workaround that doesn't require turning debugging off? Cheers!
Just turn debugging off the _that_ request. In your CFC method:
<cfsetting showdebugoutput="false">
Thanks Ray!
Thanks Ray for your twitter answer, as usual you rocks :)
So I first tried to follow your second example, and made the wsdl result call in a variable, and everything is so OK, but when I try to call www.mydomain.com/cfc/MyWebs... directly in the source of the autocomplete, I see in the firefox console that the term variable is appended but the call doesn't show any result. Did I made a wrong call to the wsdl ?
Michel
First off - I hate people who get pedantic about language, but you aren't using WSDL here. WSDL is a term that refers to a form of XML used when talking to web services. CFCs can output WSDL but you aren't using that feature here. (And since I said pedantic above it pretty much guarantees someone is going to call me out on it. ;)
Ok - that being said, did you look in the FIrebug _console_ or the Network tab? It's a subtle difference and you probably meant console as a way to refer to all of Firebug, but they are separate tools within FIrebug itself. If you are indeed in the Network tab and not seeing anything, maybe scroll down. Don't forget CF can sometimes output a bunch of white space.
It would be best if you could share a public URL so we can see. Or if you want to email me directly, that's fine. (Although I ask that when we find the issue you share the result back here.)
Ray: any way to do your code above that does not reference the custom CF tags in CF9. Your code works on my local machine but when I upload it to the server I get an error calling the var q = new com.adobe.coldfusion.query(); So I'm assuming my shared hosting environment that the mapping is not there for such functionality. see here: http://www.northernkyhomese...
Just rewrite my script-based CFC as an old school tag based one. Or, you can find out where CF is installed by cfdumping the server scope. Note the root directory. In your Application.cfc, add a new custom tag path that points to (rootdir)\customtags.
Sorry Ray not following you as I'm a newb to this kinda coldfusion (cfc's, custom tags, CF9). I ran some code regarding the server scope and I think I found the root directory (on a shared environment) but as far as the custom tag in the cfc you wrote not sure what's up there.
Do you know how to use the Application.cfc feature? There's docs on that, and blog posts here, in Google, etc. It's a 'controller' for your CF apps and can be used to set things like custom tag paths. Read up on that, and then make use of the feature. It should be as simple as adding
<cfset this.customtagpaths = "(yourroot)\customtags">
to the file. If that doesn't work, well, I'd look at the docs for CFCs in general. It's a big topic, but one you need to pick up on sooner or later anyway. To be honest, the code above could be rewritten in about 5 minutes once you get a hang of the syntax.
Oh I know what an application.cfc is as I'm currently using one with limited knowledge talking to you of course. I guess I'm not sure how deep to go into the drive as I'm in a shared environment.. the path seems pretty deep all the way down to the c: drive.
I wrote this version -very- quickly - so it may not work 100%:
http://pastebin.com/Yq68rdR9
You are the man... I can't wait to play for that, thank you for taking the time. So I have added the following to my Application.cfc after tracking down the root of the server:
<cfset this.customtagpaths = "C:\glassfish3\glassfish\nodes\node1\cf01\applications\cfusion\WEB-INF\cfusion\CustomTags\">
Still not having any luck getting the functionality to work online... locally yes but not on the stupid shared environment.
Maybe do a quick check using directoryExists? It's possible the custom tags aren't there.
I'm checking with my hosting provider who is apparently have never been asked this before... as they don't know what I'm talking about :) Also, in your new code (component) posted above I noticed you did not reference the customtag or query (cfset var q = "") is there a reason or do you need to have this to make the code work. I used your new function locally and still can't get the new code to work. As always, thank you for your time and hard work.
As of right now this is what I have so far:
http://pastebin.com/tGxrJF9z
To your first comment - the new pastebin is a tag based version of the code. I know you are new to CF, but you have done queries before, right? When you tried it locally, what error di you get?
Remove this line:
<cfset var q = new query()>
Make it
<cfset var q = "">
Sorry Ray... I just updated that code locally and still can't get it to work... link above has been changed as well as a reference. Just to recap your original code (cfc) works locally not on the server, the new reformated cfc does not work on either for me. Any other thoughts?
At this point it makes sense to switch off blog. Basically, I'd focus on the tag based version. You say it doesn't work, but how? Did you check the CF logs for an error? Did you try using Firebug or Chrome network tools ? THey would show the response from the CFC and help isolate the issue. Follow up with me off blog though please.
Ok sorry about that. How to contact you via contact form?
See "Contact Me" waaaay up there on top? :)
If i dont want to change text box value unless final selection of suggestion then what can ido..in where exactly i want to made change...
I have no idea what you mean. Are you saying you don't want to allow free form text, just values from the suggest?
I've been using Drew Wilson's AutoSuggest jQuery Plugin. It feels a lot like Facebook's AutoSuggest and allows you to allow free text additions, restrict to only certain values and also allow multiple values.
http://code.drewwilson.com/...
Damn Ray you look like a homeless mutha with that beard, hat and whatnot.
Heh, what can I say - I'm a bum. ;)
Please can you tell me how to use in coldfusion 8 can't get to work that's my cfc
:
<cffunction name="getNames" access="remote" returntype="String" >
<cfargument name="search" type="any" required="false" default="">
<cfset var data="">
<cfset var result=ArrayNew(1)>
<cfquery name="data" datasource="dbNAme">
SELECT NAME
FROM myTable
WHERE NAME LIKE '%#trim(ARGUMENTS.search)#%'
ORDER BY NAME
</cfquery>
<cfloop query="data">
<cfset returnStruct = StructNew() />
<cfset returnStruct["label"] = NAME />
<cfset ArrayAppend(result,returnStruct) />
</cfloop>
<cfreturn serializeJSON(result) />
</cffunction>
and im this my cfm:
<script src="jquery-1.4.2.min.js"></script>
<script src="jquery-ui-1.8.custom.min.js"></script>
<link rel="stylesheet" href="jquery-ui-1.8.custom.css" type="text/css" />
<script type="text/javascript">
$(document).ready(function(){
$('#Names').autocomplete(
{source: function(request, response) {
$.ajax({
url: "cfc/getValues.cfc?method=getNames>&returnformat=json",
dataType: "json",
data: {
search: request.term,
maxRows: 10
},
success: function(data) {
response(data);
}
})
},
parse: function(data){
return $.map(data, function(item) {
return { data: item, value: item, result: item };
});
}
});
});
</script>
category: <input id="Names" />
but i can't get to work
The reason it isn't working is because you are converting the result to json here:
<cfreturn serializeJSON(result) />
but you told CF to convert it for you here too:
url: "cfc/getValues.cfc?method=getNames>&returnformat=json"
(I assume the > is a typo, if not, that's a problem)
Basically, you are turning JSON into JSON. Change your cfreturn to be just
<cfreturn result>
Btw, not to sound like a broken record, but if you use Google Chrome Dev Tools or Firebug, you would have seen the result and noticed it was double encoded JSON. I strongly urge folks to use tools like this so you can see what is being returned.
Thanks for the information but the cfc page isn't being called.No javascript error but when i write in the textbox nothing happens.sorry Im new to coldfusion :)
Need to know if there is any error in my query string that calls the cfc file cause the ajax call is not being performed .
Did you try removing the > from the url?
Yes this is typing mistake this > is not contained in my url .
Even if i change the cfc file name no error is fired what could it be the reason i need ? Im using CF 8
Do you see a network request at all in Firebug or Chrome Dev Tools?
No Network request are shown
Well, is it online where we can all see?
hi ray. thanks a lot for the post on using autocomplete with CFC's. I'm noticing that demo2 and demo3 don't work in firefox. demo 1 works ok.
I think I can figure out how to use it based on your examples, but wanted to let you know the demos don't seem to working.
Ugh, it looks like the artgallery db isn't set up right for my server, which means lots of demos will be down. Will try to fix later this week.
Fixed.
thanks ray. I saw that in firebug last night, but wanted to let you know. (not that you don't have enough to do, or people to help!)
thanks to your post, I'm levitating x wing fighters out of swamps with autocomplete!
cheers
I've tried to add error function to my script
like this :
error: function (xhr, textStatus, errorThrown){
// show error
alert(errorThrown);
}
when i try to write in the textbox i have an alert with undefined value inside. Sorry but it isn't published online .
What about textStatus?
Unfortunately - if I can't see this myself, I'm limited on how much more I can help.
Is there a way to apply this autocomplete feature to cfgridcolumn instead of just a text field? I have a client who wants the job description field to autocomplete using a query result of previous descriptions.
In fireFox I can see results in this Form :
"[{\"label\":\"AABDALLAH\"},{\"label\":\"AABDALLAH\"}.....
but nothing appearing in the Textbox how i can i fix this issue
+Ray: cfgrid makes use of Ext - an entirely different JavaScript UI framework. I'm sure something like that could be done. But not with the jQuery UI plugin. It's totally different.
+Nath: I don't know. :) What else do you see? Do you see an error? Is it online where I can run it?
Just wanted to say thank you very much, I have wasted hours trying to get the ability to send a hidden field as described above and finally I have it. Once again many thanks!
Glad it was helpful.
Coming in a bit late, but have a fun fact.
If you will be returning numeric values for the dropdown, you will want to use quotedValueList instead of valueList. Otherwise you get this:
[123,234,345]
Instead of:
["123","234","345"]
The result without the quotes is that the JQuery autocomplete dropdown is created, but with no values.
This is something easily figured out in a few minutes. Unless you are stubborn and sleep deprived. Not that I am, but just sayin'...
There is probably a better way, but this works too.
Thanks for sharing that!