Selecting default items using ColdFusion 8's AJAX Controls

So here is an interesting question. Take a look at Ben's post on related selects in ColdFusion 8 (and don't forget it is even easier now). Pretty simple, right? Well how do you set a control to use Ajax and have a default selected item? Turns out this isn't so easy.

The first thing I tried was selected=, figuring that would be the easiest solution, but unfortunately it didn't work.

I then tried ajaxOnLoad, thinking maybe I could set the default myself. But ajaxOnLoad() is fired when the page is complete, but before those Ajax calls to populate the drop downs are done.

I then tried onLoad in the cfform tag. This didn't work at all. So I threw the problem over to Todd Sharp, and together we were able to come up with a solution. It ain't pretty, but it works. My hope is that folks can look at this and suggest something nicer. I'm actually a bit surprised this isn't supported out of the box. It seems like I use forms half the time to edit content, not create content, so being able to set defaults is a must.

Anyway - the code:

<cfajaxproxy bind="javascript:test({mediaid},2)"> <head> <script> var imdone = false; function test(x,val) { if(!imdone) { var dd = document.getElementById('mediaid'); for(var i = 0; i < dd.length; i++){ if(dd.options[i].value == val){ dd.selectedIndex = i;

} } imdone = true; } } </script> </head>

<cfform > <table> <tr> <td>Select Media Type:</td> <td><cfselect name="mediaid" id="mediaid" bind="cfc:art.getMedia()" bindonload="true" value="mediaid" display="mediatype" /></td> </tr> <tr> <td>Select Art:</td> <td><cfselect name="artid" bind="cfc:art.getArt({mediaid})" value="artid" display="artname" /></td> </tr> </table> </cfform>

So first off - note the use of cfajaxproxy. It is bound to the first drop down. When the value changes, and this occurs on initial load, code is run to set the default. In this case note the hard coded value of 2. This would be #form.selected# or whatever. Also note the use of a variable to remember that the default value has been selected. The cfajaxproxy will always run on change, so we want to be sure it is run only once.

Thoughts? This code only supports one selected item, and only supports defaulting the left control, but obviously it could be extended to handle both. Again though it is a bit disappointing that essentially one line of code:

cfselect name="mediaid" id="mediaid" bind="cfc:art.getMedia()" bindonload="true" value="mediaid" display="mediatype" />

had to be extended by about 10 lines of JavaScript. To be fair, my beloved Spry doesn't make this much easier. You can use spry:if type conditionals so it is a bit slimmer. Maybe someone can speak to how other frameworks like Prototype does it?

Edit: A followup post by Todd: Selecting Multiple Default Items With ColdFusion 8 Ajax Controls

Archived Comments

Comment 1 by todd sharp posted on 8/7/2007 at 11:12 PM

I've since whipped up a script that would handle multiple selected items by passing an array of them in the ajaxproxy. This uses the mysteriously undocumented ColdFusion.JSON.decode function to handle the array. Obviously you'd also change the size on the select and add multiple=true...

<cfajaxproxy bind="javascript:test({mediaid},'[2,3,4]' )">

<script>
var imdone = false;
function test(x,val) {
if(!imdone) {
var dd = document.getElementById('mediaid');
valArr = ColdFusion.JSON.decode(val);
for(var i = 0; i < dd.length; i++){
//loop over the array of selectedItems
for(var j = 0; j < valArr.length; j++){
if(dd.options[i].value == valArr[j]){
dd.options[i].selected = true;
}
}
}
imdone = true;
}
}

</script>

Comment 2 by todd sharp posted on 8/7/2007 at 11:14 PM

Also worth nothing - if the first select accepts multiple then the bind will receive a comma seperated list of selected items (2,3,4 in this case) - so your CFC will have to accomodate...

Comment 3 by Sean Coyne posted on 8/7/2007 at 11:24 PM

I haven't tried it because I'm lazy but can you just set the default value in the form scope <cfset form.mediaid = 1 /> and then use <cfform>'s preserveData="true" attribute?

Comment 4 by Raymond Camden posted on 8/7/2007 at 11:37 PM

Tried it - didn't work. Good one there though. If that would have worked....

Comment 5 by todd sharp posted on 8/7/2007 at 11:40 PM

Blogged a complete example of supporting multiple selected items (including handling them on the cfc side of things).

http://cfsilence.com/blog/c...

Comment 6 by Will posted on 8/7/2007 at 11:55 PM

You read my mind! I knew I should have worked on something else! I spent 2 hours trying to get this to work yesterday before giving up and resigning myself to emailing you about it. I just hadn't gotten around to emailing you yet :)

Comment 7 by Mike Benner posted on 8/8/2007 at 2:25 AM

I think the real question is how to they do it with Ext JS Library, as I believe that is Adobe used to model theirs after.

The docs are here: http://extjs.com/deploy/ext... for anyone to go through. I looked at them briefly but saw nothing off the top of my head. Will take another look after the kids go down for the night.

Comment 8 by Eric posted on 9/14/2007 at 12:17 AM

Thankfully SOMEBODY is talking about this!!! I just spent the last hour and a half scouring the web for some sort of solution to this. Not having this out of the box is shameful on Adobe's part. I surely hope they come up with a clean solution for this as well. Cheers to you for making it work for now.

Comment 9 by Raymond Camden posted on 9/14/2007 at 12:21 AM

Eric - to be fair - I found the same problem in Spry. No simply way to do defaults. Can others on this entry comment on other Ajax frameworks?

Comment 10 by fred posted on 10/21/2007 at 11:08 PM

This works for defaulting the first select... How can the 2nd select be defaulted as well?
I tried updating the javascript by adding the same logic to the 2nd select but it doesn't work.

Thanks.

Comment 11 by Raymond Camden posted on 10/21/2007 at 11:15 PM

I don't have an easy solution for this in CF8 Ajax.

Comment 12 by Fred posted on 10/21/2007 at 11:55 PM

workaround: I'm able to default the second value with the script below. It basically works depending on the time it takes for the CFC query to return. This sets the second select to its corresponding value after 1 second of page loading. If for whatever reason the query takes longer, this doesn't work. No guarantees. In my case 'model' is the name of my 2nd select.

<pre>
<script>
function initSelect(){
var dd2 = document.getElementById('Model');

for(var i = 0; i < dd2.length; i++){
//loop over the array of selectedItems
if(dd2.options[i].value == '<cfoutput>#form.defaultvalue#</cfoutput>'){
dd2.options[i].selected = true;
}
} ;
}

setTimeout("initSelect()",1000)

</script>
</pre>

Comment 13 by Steve Savage posted on 4/3/2008 at 1:48 AM

I think I've found a simpler solution to this.

I've created a .js file that "overrides" a function from coldfusion's cfajax.js library.

The new version of the function allows you to specify which options are selected as part of the array you return from your "bound" .cfc function.

See my site for details.
http://www.realitystorm.com...

Comment 14 by PhilNg posted on 5/12/2008 at 6:57 AM

A useful trick is to tell the calling CFC what the selected value and making sure that it's #1:

<cfcomponent>

<cffunction name="get" access="remote">
<cfargument name="TABLE_NAME" default="">
<cfargument name="VARIABLE_NAME" default="">

<!--- this is kind of lame, but cold fusion will not set the selected variable!!!!! --->
<cfargument name="SELECTED" default="" type="String">
<cfset answer=ArrayNew(2)>

<!--- this is to set the "selected" item first; so that they're um.. selected. --->
<cfset iter = 2>
<cfset answer[1][1]=selected>
<cfset answer[1][2]=selected>
<cfloop index="i" from="1" to="#data.RecordCount#">
<cfif ucase(trim(data.value[i])) neq ucase(trim(selected))>
<cfset answer[iter][1]=data.value[i]>
<cfset answer[iter][2]=data.display[i]>
<cfset iter = iter + 1>
<cfelse>

<!--- ooo! we have the label of the first selected value! --->
<cfset answer[1][2]=data.display[i]>

</cfif>
</cfloop>

<cfreturn answer>
</cffunction>

Comment 15 by Mark Chripczuk posted on 7/16/2008 at 4:02 AM

Thanks for the help guys! This page has been my close friend for the past couple of hours as I tried to figure out how to make this all work. Hopefully Adobe will provide some more functionality soon.

Comment 16 by Nando posted on 7/26/2008 at 8:19 PM

I've worked thru most of the workarounds I've found in this blog entry and on the original by Ben Forta. I finally settled on Steve Savage's solution and it's working very well for me. Once you have his javascript file in place and you wrap your head around the array you need to generate, which has 3 values per record - the id (option value), the display value, and a boolean that indicates if this record should be selected - it's actually very easy to implement.

Ray, if you see this comment, how can Steve's solution be passed on to Adobe for possible inclusion in the next update of CF8?

Comment 17 by Raymond Camden posted on 7/29/2008 at 4:52 AM

Use this form:

www.adobe.com/go/wish

Comment 18 by Nando posted on 7/29/2008 at 4:15 PM

Done!

Comment 19 by George posted on 9/2/2008 at 8:44 AM

Hi Nando,

Can you please give us an example how did you work around with Steve Savage's solution? I'm not sure how to use his new function.

Thanks,
George

Comment 20 by Giedrius posted on 9/18/2008 at 8:50 PM

For some reason IE doesn't work. FireFox is fine. It seems as IE executes the test function before the select is populated with options, so dd.length is 0. Ugh!

I am using the function just for a single cfselect which is using javascript bind.

Comment 21 by Michael White posted on 9/26/2008 at 12:26 AM

a twist on this problem is: how do you select an item in one combo box using the selected value in another combo box. say combo box #1 is a list criteria (fastest, economical, luxuriest, etc), combo box #2 is a list of car models. you don't want to filter combo box #2, you just want to select the default car model for that criteria (you might filter combo box #1 with a MFG combo box but we can skip that for now). How do you set the selected index of the model combo box based on the selection you make in the criteria combo box whenever the combo box is changed?

Comment 22 by Raymond Camden posted on 9/26/2008 at 3:43 PM

Use cfajaxproxy to run JS function foo() when the first drop down changes. In the JS function, use another ajaxproxy to call your cfc to get the right value for the second drop down based on the value in the first. Then simply loop over the options in drop down 2, and when you get the right value, you set it to selected. This is what I told you in email I think. :) Didn't it make sense?

Comment 23 by Chris posted on 12/24/2008 at 5:27 AM

George, It was months ago but if you are still after some more info, I got the solution by Steve Savage working recently (thanks Steve!).

My example uses a product type/category/sub category hierarchy.

I added an argument to each of the functions in the cfc for the ID of the value I wanted to select:

<!--- Get array of product types --->
<cffunction name="getProductTypes" access="remote" returnType="array">
<cfargument name="typeID" type="numeric">
...
<!--- Get category by product type --->
<cffunction name="getCategories" access="remote" returnType="array">
<cfargument name="typeid" type="numeric" required="true">
<cfargument name="catID" type="numeric">
...
<!--- Get sub category by category --->
<cffunction name="getSubCategories" access="remote" returnType="array">
<cfargument name="categoryID" type="numeric" required="true">
<cfargument name="subCatID" type="numeric">
...
In each of the functions I added a cfif to the query to array loop to set the new array element to true for the passed ID:

<!--- Convert results to array --->
<cfloop index="i" from="1" to="#getTypes.RecordCount#">
<cfset result[i][1]=getTypes.typeID[i]>
<cfset result[i][2]=getTypes.type[i]>
<cfif getTypes.typeID[i] is arguments.typeID>
<cfset result[i][3]=true>
</cfif>
</cfloop>
...
(repeat for categories and sub categories)

Then on the display page I included Steve's magic JavaScript and added the arguments to each of the cfselect tags:

<cfselect name="typeID" bind="cfc:typeCatSubCat.getProductTypes(#typeID#)" bindonload="true" />
...
<cfselect name="catID" bind="cfc:typeCatSubCat.getCategories({typeID},#catID#)" />
...
<cfselect name="subCatID" bind="cfc:typeCatSubCat.getSubCategories({catID},#subCatID#)" />

Comment 24 by Frankie posted on 2/19/2009 at 5:56 AM

Hi Chris,

you have used also Steve script?
or you have made this works only with cfc?

I cannot understand how I can make it works...

Comment 25 by Frankie posted on 2/22/2009 at 9:27 PM

Hallo,

this is my code:

<cfcomponent output="false">

<!--- Get array of media types --->
<cffunction name="getRegioni" access="remote" returnType="array" output="no">
<cfargument name="regioneid" type="numeric">

<!--- Define variables --->
<cfset var data="">
<cfset var result=ArrayNew(2)>
<cfset var i=0>

<!--- Get data --->
<cfquery name="data" datasource="#application.dsn#">
SELECT fld_id,fld_provincia,fld_id_regione
FROM tbl_province
ORDER BY fld_id
</cfquery>
<!--- Convert results to array --->
<cfloop index="i" from="1" to="#data.RecordCount#">
<cfset result[i][1]=data.fld_id[i]>
<cfset result[i][2]=data.fld_provincia[i]>
<cfif data.fld_id[i] is arguments.regioneid>
<cfset result[i][3]=true>
</cfif>
</cfloop>
<!--- And return it --->
<cfreturn result>
</cffunction>

<!--- Get art by media type --->
<cffunction name="getProvince2" access="remote" returnType="array" output="no">
<cfargument name="regione" type="numeric" required="true">
<cfargument name="provinceid" type="numeric">

<!--- Define variables --->
<cfset var data="">
<cfset var result=ArrayNew(2)>
<cfset var i=0>

<!--- Get data --->
<cfquery name="data" datasource="#application.dsn#">
SELECT fld_id, fld_localita
FROM tbl_localita
WHERE fld_id_provincia = #ARGUMENTS.provinceid#
ORDER BY tbl_localita.fld_localita
</cfquery>

<!--- Convert results to array --->
<cfloop index="i" from="1" to="#data.RecordCount#">
<cfset result[i][1]=data.fld_id[i]>
<cfset result[i][2]=data.fld_localita[i]>
<cfif data.fld_id[i] is arguments.provinceid>
<cfset result[i][3]=true>
</cfif>
</cfloop>

<!--- And return it --->
<cfreturn result>

</cffunction>
</cfcomponent>

And this is my form:

<script src="http://www.agriturismoincam...

<cfform>
<cfselect name="regione" bind="cfc:select2.getRegioni(1)" bindonload="true" id="regione" />

<cfselect name="fld_id_localita" id="fld_id_localita" bind="cfc:select2.getProvince2({regione},20)" />
</cfform>

Where is my error?

Comment 26 by Raymond Camden posted on 2/22/2009 at 10:49 PM

What error are you getting? You need to provide a bit more detail.

Comment 27 by Frankie posted on 2/23/2009 at 12:02 AM

I got this error:

bind failed, element not found: regioneid.

Any idea?

Comment 28 by Raymond Camden posted on 2/23/2009 at 12:07 AM

Odd. No where in your clientside code do you use regioneid. You use regione, but not regioneid. Are you sure you pasted the right code? (PS - in the future, please do not post large blocks of code - try to post something smaller, or use a link to pastebin.)

Comment 29 by Frankie posted on 2/23/2009 at 12:18 AM

Sorry.

I have uploaded my code in:

http://www.agriturismoincam...

and the form

http://www.agriturismoincam...

Where is the error? could you help me,please?

Comment 30 by Raymond Camden posted on 2/23/2009 at 12:20 AM

Hmm. Can you put the actual code up where we can run it? Not seeing anything obvious yet.

Comment 31 by Raymond Camden posted on 2/23/2009 at 12:20 AM

Oh wait - try this - in the second select, set bindonload to false.

Comment 32 by Frankie posted on 2/23/2009 at 12:28 AM

Nothing...same error...

I really don't understand where is the error...

I will go crazy!!

Comment 33 by Raymond Camden posted on 2/23/2009 at 12:29 AM

Well, if you can put it online where I can run it, I can try to dig more.

Comment 34 by Frankie posted on 2/23/2009 at 12:32 AM

Same address....

http://www.agriturismoincam...

It's possible my error is how I import the javascript fixColdfusionAjax.js?

Comment 35 by Frankie posted on 2/23/2009 at 12:36 AM

On local machine the debug give me new error:

window:global: Error loading script (http://www.agriturismoincam..., line 1)

Comment 36 by Raymond Camden posted on 2/23/2009 at 1:34 AM

I don't get any error. The first drop down never loads - nor do I see an ajax request. I see other JS code involved here - the google map stuff. I'd recommend creating a new page that doesn't do this. In other words, simplify your page as much as possible in order to make it easier to find what is wrong.

Also, what is fixColdFusionAjax.js?

Comment 37 by Frankie posted on 2/23/2009 at 2:39 AM

fixColdfusionAjax.js is script of Steve Savage, posted on this blog.

I've simplified my page....I have red the example in the comment of Chris...

Comment 38 by Raymond Camden posted on 2/23/2009 at 3:03 AM

I think I see it. A typo. No closing quote on the script src:

<script src="http://www.agriturismoincam...

Comment 39 by Frankie posted on 2/23/2009 at 3:42 AM

Thank you, Raymond.

But I think there is another problem, because the second select doesn't retrive any value....

I don't think I will make it work....

Comment 40 by Frankie posted on 2/23/2009 at 3:48 AM

Now the problem is:

error:http: Error invoking CFC /CMS/select2.cfc : The REGIONEID argument passed to the getProvince2 function is not of type numeric.

Probably because if I type http://www.agriturismoincam... it give me the value with true on the selected value....

I need to change my cfc?

Sorry if I stress you with many question but in Italy there aren't many coldfusion's developers...

Comment 41 by Raymond Camden posted on 2/23/2009 at 4:00 AM

I'm not seeing an error now. Not on your online version.

Comment 42 by Frankie posted on 2/23/2009 at 4:08 AM

Not error, but the second select doesn't retrieve any value...

Comment 43 by Raymond Camden posted on 2/23/2009 at 4:18 AM

Did you set the second one to bindonload=false?

Comment 44 by Frankie posted on 2/23/2009 at 4:26 AM

DONE!!!!

Finally I made it works....

Thank you for your support...

Comment 45 by Raymond Camden posted on 2/23/2009 at 4:40 AM

I live to serve. You owe me one good beer now. ;)

Comment 46 by Frankie posted on 3/12/2009 at 3:43 AM

Only one?

Two or more....

Comment 47 by Sheldon Goldberg posted on 4/8/2009 at 3:45 AM

Has this problem ever been fully resolved? The js override function looks interesting. But, how/when do
you call getValues?

Is there any code to show this being implemented?

Any help would be really appreciated.

Comment 48 by dan fredericks posted on 7/6/2009 at 7:25 PM

Here is my code:

<cfselect name="courseType" id="courseType" bind="cfc:cfcs.template.getCourseType()" value="courseMethodID" display="courseMethodDescription" bindOnLoad="true" tooltip="Course Type"> <option value="0">Select Type</option></cfselect>

On my initial screen, the option will not show up...first problem.
When the user submits that page back to itself, I need to value they selected to be autoselected on the page again...need a summary page they can change before submiting to db. I tried the JS solution on this page, however, I received an error stating my courseMethodID value was undefined.

<cfajaxproxy bind="javascript:test({courseType},#form.courseType#)">
<script language="javascript">
var imdone = false;
function test(x,val) {
if(!imdone) {
var dd = document.getElementById('courseType');
for(var i = 0; i < dd.length; i++){
if(dd.options[i].value == val){
dd.selectedIndex = i;

}
}
imdone = true;
}
}
</script>

Below is the source of my file where the error is located:
<script type="text/javascript">
_cf_bind_init_1246893138308=function()
{
ColdFusion.Bind.register([['courseType','','change']],{'bindTo':ColdFusion.empty,'bindToAttr':'true','callFunction':'test','bindExpr':[['courseType','','value'],ILT]},ColdFusion.Bind.jsBindHandler,false);
};ColdFusion.Event.registerOnLoad(_cf_bind_init_1246893138308);
</script>

any help would be appreciated

Comment 49 by dan fredericks posted on 7/6/2009 at 11:26 PM

Figured out my issue, if you don't use numeric values in the cfajaxproxy:
<cfajaxproxy bind="javascript:test({courseType},#form.courseType#)">

it won't work right. Once I figured out I was not using numeric, and switched, it works just fine.

thanks for the code.

Comment 50 by Francesco posted on 7/17/2009 at 5:25 AM

Hallo,

I've made this related select, but I have problem with charset. In fact one of my value has accent but I cannot make it formatted properly....

Could someone help me?

This is the link to the component output:
http://www.agriturismoincam...

And this is on site: http://www.agriturismoincam...

What I have to do to make this work? I have tried to put cfheader on utf-8 but nothing change...

Comment 51 by Steve Savage posted on 7/17/2009 at 5:32 PM

You could try replacing the character with it's html entity equivalent.
http://www.w3schools.com/ta...

Comment 52 by Anthony posted on 9/3/2009 at 9:29 AM

Brilliant, works perfectly

Comment 53 by Sean Sekora posted on 12/9/2009 at 11:16 PM

Steve Savage's fixed worked perfect for me. I have a vehicle look up that has 14 <cfselect>s all binding to javascript functions that call CFCs to get there options. I just include Steve's js file and added the third value to the return array for each option setting the currently selected value to true and everything just worked. Thanks Steve

Comment 54 by Alex Moustris posted on 2/5/2010 at 4:39 PM

The code below works fine without any extra javascript. Only native CF9:
<cfselect bind="cfc:hotelier.components.GeoInfo.getRegionsByCountry({CountryID})" enabled="No" bindonload="yes" name="RegionID" class="FormFields" id="RegionID" multiple="no" value="RegionID" display="RegionStringEN" selected="#HotelDetails.RegionID#">
<cfoutput> <option value="#HotelDetails.RegionID#" selected="selected">#HotelDetails.REGIONSTRINGEN#</option></cfoutput> ---></cfselect>

Comment 55 by Andrew posted on 2/27/2010 at 2:41 AM

Great function Ray, but what if I needed to default two drop downs?

For instance, I have two cfselects, a country drop down and a state drop down list bound to the country drop down. I want the selected values from the previous post to the form to be the default selected values... let's see if I can quickly post some code:

<cfform name="f">
Country:<br>
<cfselect id="listCountryCodes" name="listCountryCodes" required="yes" bind="cfc:path.to.my.cfc.that.returns.countries()" bindonload="yes" display="CountryName" value="CountryCode" /><br>
Select State:<br>
<cfselect
id="listStateCodes" name="listStateCodes" required="yes" bind="cfc:path.to.my.cfc.that.returns.states.based.on.Country.Selected(CountryCode={f:listCountryCodes})" bindonload="yes" display="StateName" value="StateCode" />
</cfform>

having two cfajaxproxy tags (both bound to their respective selects) doesn't seem to do the trick. any thoughts based on the above, or do you need more info?

Thanks in advance!

Comment 56 by Raymond Camden posted on 2/27/2010 at 7:16 AM

I've done this before - in jQuery. I'm sure it could be done here. It just gets more complex. On load you set that first select. The second select will then load, right? You then use code to say, "If this is the first time the second select has loaded, then default to X".

Comment 57 by Bobbi posted on 7/1/2010 at 8:52 PM

I'm having a problem with an "element var_proposal not defined". I can't understand why it isn't found!
<cfselect name="cbo_status"
bind="cfc:proposal_status_cfc.getStatus()"
bindonload="true"
display="prop_status"
id="prop_status"

/>

<cfselect name="cbo_proposal"
bind="cfc:proposal_status_cfc.getProposal({cbo_status})"
value="prop_number"
size="3"

/>

Then in the cfc: I have a function (getStatus) with a query that "Select distinct prop_status". Then in the function (getProposal), I set cfargument name="var_proposal". This is where I get the "element var_proposal not defined" error. I'd be glad to post the full code, but I didn't want to clog up the blog.
Thanks!!!

Comment 58 by Raymond Camden posted on 7/2/2010 at 2:10 AM

I believe because on load, your second select is sending _nothing_ to the CFC because nothing is picked yet. You can make the argument optional and simply return nothing when no value is passed.

Comment 59 by Gurpreet posted on 7/8/2010 at 9:37 PM

Hi!
i came across the same type issue but a bit confusing! i got 4 select statements!. I am trying to edit the value of the record. So countryid is the one selectbox which is calling no bind operation, it is just listing the countries and countryid is already get populated when we try to edit as it fetches infor from database:

the problem is with the remaining cfselect.. The selects are dependent upon one another!

like the Country >> Province >> Town >> Suburb

Province, town and suburb are using the bind attributes, i want that when my country is selected, it should automatically get the values from the database for the follwing three selects and populate them with the exact info.

code like this:

<tr>
<td align="right"><strong>Country : </strong></td>
<td><select name="countryid" id="countryid" class="inputstyle">
<option value="none">(Select One)...</option>
<cfoutput query="getcountries">
<option value="#countryid#">#country#</option>
</cfoutput>
</select>
</td>
</tr>
<tr>
<td align="right"><strong>Province : </strong></td>
<td><cfselect name="province" bind="cfc:com.remoteCalls.getRemoteProvince({countryid})" bindonload="false" class="inputstyle"><option value="0" selected>Select One</option></cfselect></td>
</tr>
<tr>
<td align="right"><strong>Town : </strong></td>
<td><cfselect name="town" id="town" class="inputstyle" bind="cfc:com.remoteCalls.getRemoteTowns({province})" bindonload="false"><option value="0" selected>Select One</option></cfselect></td>
</tr>
<tr>
<td align="right"><strong>Suburb : </strong></td>
<td><cfselect name="suburb" id="suburb" class="inputstyle" bind="cfc:com.remoteCalls.getRemoteSuburb({town})" bindonload="false"><option value="0" selected>Select One</option></cfselect></td>
</tr>

Comment 60 by Gurpreet posted on 7/11/2010 at 5:47 PM

any update on this ray!

Comment 61 by Raymond Camden posted on 7/11/2010 at 8:20 PM

Well whats not working? I don't think you said.

Comment 62 by Gurpreet posted on 7/11/2010 at 8:45 PM

All good!

trouble i am lost where i should use the ajaxproxy to load the contents based upon one after anotehr select box! like the countries selected is ZIMBABWE, so i loaded province,town,suburn based upon each other, so how to make use of ajaxproxy to load the contents based upon one another

Comment 63 by Raymond Camden posted on 7/11/2010 at 11:27 PM

You shouldn't need cfajaxproxy to just do binding.

Comment 64 by alonso posted on 7/13/2010 at 11:27 PM

I want used bind with cfselect and I found many example like your but any one work.
I received a empty combo with any example I used it.
this my code
<cfinvoke component="test" method="A_Showhistory_level"

returnvariable="ret_Showhistoryitem" >
</cfinvoke>
<cfdump var="ret_Showhistoryitem" >

<cfform name="OutputHistory">
<table>
<tr><td> Description : </td>
<td> <cfselect name="testbind"
bind="cfc:store.A_Showhistory_level()"
bindonload="true"
>
<option name="blank" >--Select-- </option>
</cfselect>
</td></tr>
</table>
</cfform>

and My component is :
<cfcomponent output="no" >
<cfset datasource = 'Store' >
<cffunction name="A_Showhistory_level" access="remote" returntype="array" >
<cfset a="0" >
<cfquery name="data" datasource="#datasource#" >
Exec sp_showhistoryitem1 '13'
</cfquery>
<!--- <cfdump var="#qShowhistory_level#" >--->
<cfset alevel=arraynew(2) >
<cfloop index="i" from="1" to="#data.RecordCount#">
<cfset result[i][1]=data.cases_location_id[i]>
<cfset result[i][2]=data.boxname[i]>
</cfloop>
<cfreturn result >
</cffunction>
</cfcomponent>
I very apreciate any help with this problem

Comment 65 by Raymond Camden posted on 7/14/2010 at 12:00 AM

What does Firebug, or Chrome Dev tools tell you?

Comment 66 by Alonso posted on 7/14/2010 at 5:24 PM

I use IE8 and didn't notice small yellow triangle with admiration sign said Done on the left lower corner of the browser
I copy and paste the error

Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.2; Trident/4.0; GTB6.5; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)
Timestamp: Wed, 14 Jul 2010 13:22:49 UTC

Message: Exception thrown and not caught
Line: 803
Char: 1
Code: 0
URI: http://localhost/CFIDE/scripts/ajax/package/cfajax.js

Comment 67 by ALONSO posted on 7/14/2010 at 5:41 PM

I review source code in chrome and I went to script and this code return on my browser.

<tr><td> Description : </td>
<td> <select name="testbind" id="testbind">
<option name="blank" >--Select-- </option>
</select>
</td></tr>
Any suggestion

Comment 68 by Raymond Camden posted on 7/14/2010 at 5:59 PM

I'd switch to Firefox or Chrome. You don't have to switch forever, just long enough to use the nice Ajax debugging tools included with them.

Comment 69 by Alonso posted on 7/14/2010 at 7:08 PM

I get this error :

/CFIDE/scripts/ajax/package/cfajax.js:803Uncaught SyntaxError: parseJSON

Comment 70 by Raymond Camden posted on 7/14/2010 at 7:09 PM

What do you see in the XHR request? Firebug/Chrome dev tools will show you the JSON returned. Do you see stuff _after_ or before the JSON?

Comment 71 by Alonso posted on 7/14/2010 at 7:47 PM

No on Chrome show me only the error I sent you.
Also I test result from the array and query and I used dump to view the result and averything looks fine.
Also I see on Jedi blog and I comment all query's from application.cfm and rename application.cfc

if you want I have print screen how I sent to you :
Thanks a lot

Comment 72 by Raymond Camden posted on 7/15/2010 at 2:08 AM

Chrome has developer tools and a resource tracker. It allows you to monitor Ajax based requests (they call em XHR requests). You need to check that. Does that make sense?

Comment 73 by Jbradley posted on 7/21/2010 at 9:57 AM

The sample that comes with cold fusion returns "result" and fills the select box choices . How do you address the array that it uses while working in the form? If you treated the 1st record of the array like a variable and could change that to be the selected value you want, would that work some how?

Comment 74 by Jbradley posted on 7/21/2010 at 10:02 AM

Is there a way to send more then one value with each cfselect.
like send the id and the description along with it?

Comment 75 by David Miller posted on 8/18/2010 at 2:41 PM

I am getting the parseJSON Error at line 803 as well. The response shows one entry in the XHR request response field preceded by a comment that has some sort of number in it. Maybe the serialization?
<!-- 34586154205 --> ["HAZEN TRANSPORT"]
Is there a CF Patch available?

Comment 76 by David Miller posted on 8/18/2010 at 3:35 PM

I found out the the cfinclude at the beginning of my cfc was outputting

an html comment (with my session id) and that was being returned with my JSON. Ergo, parseJSON error.

I removed the cfoutput from the file being cfincluded and voila, no more parseJSON error.

The Net tab in the firebug debug window was really helpful once I knew what I was looking for.

The XHR tab shows all of the information being passed in ajax including request and response.

The response tab, having expanded the URL shows the information that you are getting back.

Comment 77 by Saad posted on 1/30/2014 at 7:37 PM

Hello Raymond,

I am using Ben Forta's related selects example.

I am able to get 2 Related Selects to Work. But when using 3rd one, getting CF-Invoke Error. But the 3rd select does populate and works. CFDebug does not show any errors with the cfc.

What am I doing wrong?

CFM.
<cfform>

<table>
<tr>
<td>Select Device Type:</td>
<td><cfselect name="device"
bind="cfc:art.getDevice()"
bindonload="true" /></td>
</tr>
<tr>
<td>Select Problem Type:</td>
<td><cfselect name="problem"
bind="cfc:art.getProblem({device})"
bindonload="false" /></td>
</tr>
<tr>
<td>Select Description Type:</td>
<td><cfselect name="description"
bind="cfc:art.getdescription({device},{problem})"
bindonload="false"/></td>
</tr>
</table>

CFC.
<cfcomponent output="false">

<!--- Get array of media types --->
<cffunction name="getDevice" access="remote" returnType="array">
<!--- Define variables --->
<cfset var data="">
<cfset var result=ArrayNew(2)>
<cfset var i=0>

<!--- Get data --->
<cfquery name="data" datasource="#dsn#">
SELECT device_id, device_list
FROM pa_device
ORDER BY device_list
</cfquery>

<!--- Convert results to array --->
<cfloop index="i" from="1" to="#data.RecordCount#">
<cfset result[i][1]=data.device_id[i]>
<cfset result[i][2]=data.device_list[i]>
</cfloop>

<!--- And return it --->
<cfreturn result>
</cffunction>

<!--- Get art by media type --->
<cffunction name="getProblem" access="remote" returnType="array">
<cfargument name="device_id" type="numeric" required="true">

<!--- Define variables --->
<cfset var data="">
<cfset var result=ArrayNew(2)>
<cfset var i=0>

<!--- Get data --->
<cfquery name="data" datasource="#dsn#">
SELECT problem_id, problem_list
FROM pa_problem
WHERE device_id = #ARGUMENTS.device_id#
ORDER BY problem_list
</cfquery>

<!--- Convert results to array --->
<cfloop index="i" from="1" to="#data.RecordCount#">
<cfset result[i][1]=data.problem_id[i]>
<cfset result[i][2]=data.problem_list[i]>
</cfloop>

<!--- And return it --->
<cfreturn result>
</cffunction>

<!--- Get art by media type --->
<cffunction name="getdescription" access="remote" returnType="array">
<cfargument name="device_id" type="numeric" required="true">
<cfargument name="problem_id" type="numeric" required="true">

<!--- Define variables --->
<cfset var data="">
<cfset var result=ArrayNew(2)>
<cfset var i=0>

<!--- Get data --->
<cfquery name="data" datasource="#dsn#">
SELECT description_id, description_list, device_id
FROM pa_description
WHERE device_id = #ARGUMENTS.device_id# and problem_id =#arguments.problem_id#
ORDER BY description_list
</cfquery>

<!--- Convert results to array --->
<cfloop index="i" from="1" to="#data.RecordCount#">
<cfset result[i][1]=data.description_id[i]>
<cfset result[i][2]=data.description_list[i]>
</cfloop>

<!--- And return it --->
<cfreturn result>
</cffunction>