Many of us have built related select controls, forms with two (or more) drop down
Select Media Type:
Select Art:
The form contains two controls, one named “mediaid” and the other named “artid”.
“mediaid” is bound to cfc:art.getMedia(), and so to obtain the list of media types to populate the control, the client makes an asynchronous call to the getMedia method in art.cfc, and populates the list with the returned array. As we’d want this control to be automatically populated when the form loads, bindonload is set to “true", this way the getMedia() call is fired automatically at form load time.
“artid” is bound to the getArt method in art.cfc. This method requires that a mediaid be passed to it, and so {mediaid} is used so as to pass the currently selected value of control mediaid (the first ). Because these two controls are bound together, the second dependant on the first, ColdFusion automatically generates JavaScript code that forces artid to be repopulated with newly retrieved data whenever mediaid changes.
This example binds just two controls, but this mechanism can be used to relate as many controls as needed, and not just controls either.
164 responses to “ColdFusion Ajax Tutorial 2: Related Selects”
PISSED OFF
I can’t believe it is still an issue with using an Application.cfc …
No application.cfc and this sample works perfect.
Add an Application.cfc and it goes to crap..
Why pray tell has Adobe not addressed this issue?
This has been a problem since 5/31/07..
Holly crap, do I need to look a for a different programming language, cus if adobe is not working on issues like this after 4 years…… I have to wonder are they working on CF X anymore or will this programming language just get shoved to the side,
And I should start learning @#$#@$#*#$%& PHP?
It would behoove someone to reply to this comment, as I can’t believe the laziness I am seeing with CF issues…
in cf9, this example doesn’t work very well, in fact, i was only able to make it work having a cfselect and a cfgrid, but not with 2 cfselects. on the other hand, it works perfect without arrays:
<pre>
<cfcomponent>
<!— Get array of groups —>
<cffunction name="getGroups" access="remote" returnType="query">
<cfset var groupData = "">
<!— Get data —>
<cfquery name="groupData" datasource="myDSN">
SELECT group_id, group_name
FROM myTable
</cfquery>
<!— And return it —>
<cfreturn groupData>
</cffunction>
<cffunction name="getApps" access="remote" returnType="query">
<cfargument name="group_id" required="true">
<cfset var appData = "">
<cfquery name="appData" datasource="myDSN">
SELECT app_id, app_display_name
FROM myOtherTable
WHERE group_id = #arguments.group_id#
</cfquery>
<cfreturn appData>
</cffunction>
</cfcomponent>
<!————————————————————————>
<cfform>
<cfselect name="groups" bind="cfc:selects.getGroups()" bindonload="true" value="group_id" display="group_name" selected="group_id" />
<p>
<cfselect name="apps" bind="cfc:selects.getApps({getGroups})" bindonload="false" value="app_id" display="app_display_name" selected="app_id" />
</cfform>
</pre>
You may find yourself here looking for help with a "bind failed" error, just as I did a couple of weeks ago. Unfortunately for me, the quick tips I found here and elsewhere didn’t solve my exact problem. Some code I didn’t write that had been "working" for over a year starting producing an avalanche of "bind failed" errors seemingly out of the blue, but only in IE 9 and nowhere else. This in itself is a clue, and if this is your problem, I recommend the following:
I copied the code into a test page and began by eliminating all of the extraneous javascript and formatting in the template of the page. The error still occurred, which ruled out any of that code. Then I began methodically eliminating code until I was able to isolate the problem: improper HTML structure was causing the error. How imperfect was it? It was an unclosed <p> tag. I spent upwards of 5 hours on this problem only to fix it with 3 keystrokes. Imagine the four-letter words I mentally edited out of that last sentence.
It appears that the smallest deviation from proper HTML structure can cause this problem in IE 9. If I had started with methodical instead of looking for a quick fix, I could have saved some hours, but maybe you will see this and save yourself some time. Alas, it is too late for me.
Ben,
I found this is very helpful since I’m not savvy with Javascript but I need the value of my second dropdown be able to do a little bit more thn just showing
a value related to the first drop down.
For example:
The first drop down is listing amount of money such as $10,$20,$30,$40, etc
The second drop down will list the related fees: $2,$5,$10,$20,etc
In certain cases I need to apply dicount to the fee so I need to past 2 values from my second drop down this way when a discount exist for this user
the fee listed on the drop down should show discounted fee.
I tried this to my second drop down but it did not work:
<cfselect name="OurFee" bind="cfc:cfcomponents.mycomponent.getFees({FeeID,Diskon})" class="inputSelect" />
On the component side I did:
<CFIF arguments.Diskon LTE 10>
<cfquery name="datafee" datasource="MyDSN">
SELECT OurFee
FROM tblFeeLookUp
WHERE FeeID = <cfqueryparam cfsqltype="cf_sql_numeric" value="#ARGUMENTS.FeeID#">
</cfquery>
<CFELSE>
<cfquery name="datafee" datasource="MyDSN">
SELECT (OurFee – #arguments.Diskon#) AS OurFee
FROM tblFeeLookUp
WHERE FeeID = <cfqueryparam cfsqltype="cf_sql_numeric" value="#ARGUMENTS.FeeID#">
</cfquery>
</CFIF>
Can I get some help on how to be able to do something like this?
[sign] So I’ve been reading this post up and down and I can’t seem to find the answer to my issue – many close issues but not quite exactly what I am running into.
So, the short of it is my first select drop box works successfully – bind, function, query, array, to drop box. On page load, the second drop box doesn’t have any options. When an option from the first drop box is selected, the second one does not update.
All my functions work – when I hard code and invoke mt CFC at the top of the page, passing in a value from what would be in the second drop box, I get a result. But, the bind in the second select doesn’t seem to either running the update or passing a value in.
There seems to be similar issues here in the past but I can’t seem to find a resolution. I’m running CF 9,0,0,251028 and the following code:
First Select:
<cfselect name="resource_unit" id="resource_unit" bind="cfc:/cfc/Practitioners.aryGetResourceUnits()" bindonload="true" tabindex="4" />
Second Select
<cfselect name="abbreviation" id="abbreviation" bind="cfc:/cfc/Practitioners.aryGetPractitioners({resource_unit})" bindonload="false" tabindex="5" />
I can post more code if needed, but all the functions in the CFC work when invoked on the form page.
Eventually, I want to add this so there is ultimately a third field updated with the selection from the second drop box.
<cfinput type="text" name="employee_name" id="employee_name" value="" size="35" tabindex="6" bind="cfc:/cfc/Practitioners.aryGetPractitioner({abbreviation})" bindonload="false" />
Any help would be greatly appreciated.
Ok – appending my post with an interesting behavior. I added an option to the <cfselect> tag and on page load the options I hard coded appear then are refreshed and removed. The first select drop box successfully populates with the correct options from the database call (the one I hard coded is removed from the options). The value I hard coded in the second drop box appears and then quickly refreshes and is removed and there are no options replaced. Which is fine since it is supposed to be dependent on the first select. But what is interesting is that the third text input field, for that brief moment, correctly grabs the second field value and looks it up to get the value I am ultimate after.
This confirms that I’m not having a lot of the issues discussed here. But I can figure out why the other call backs are not triggered on change. Any ideas?
Unit:<br />
<cfselect name="resource_unit" id="resource_unit" bind="cfc:/cfc/Practitioners.aryGetResourceUnits()" bindonload="true" tabindex="4"><option value="PMRBG">PMRBG</option></cfselect><br />
Abbreviation:<br />
<cfselect name="abbreviation" id="abbreviation" bind="cfc:/cfc/Practitioners.aryGetPractitioners({resource_unit})" bindonload="true" tabindex="5"><option value="GAJOMAGE">GAJOMAGE</option></cfselect><br />
Employee<br />
<cfinput type="text" name="employee_name" id="employee_name" bind="cfc:/cfc/Practitioners.aryGetPractitioner({abbreviation})" value="" size="35" tabindex="6" bindonload="true" /><br />
Functionally, the user selects a unit, which updates the Abbreviation list with a smaller list. When the user selects the abbreviation, it pulls the employee full name and puts it into the text input field.
This tutorial is great, I was able to create 3 drop down selection for countries then states then cities.
They work except when my users are accessing them from iPhone and google chrome they errors out!!!!!
It says: Bind failed, element not found: CountryId [Enable debugging by adding ‘cfdebug’ to your url parameters to see more information]
Not sure why this is happening because the code is not depend on the browser, how come CF can’t handle this? not sure how can I fix this situation because in other browsers, such as, IE and Mozilla, they work just fine!
Hi Ben!
I found this posting very helpful. I did it in one of my registration form and it was working beautifully.
But when I need the same functionality for other form within this same application, the functionality doen’t work.
The error message keep saying bind failed because CountryId is not passed.
I copied and pasted the cfselects from the registration form to this other form and nothing is changed.
Logically the bind on cfselect should call the same component, am I right?
Hi Ben
I love your concise code!
This connected select box trick would be magic but I’m missing something!
The first select works and triggers on the first onchange. The second function works if I invoke the component and manually populate the select with the data from the invoked function. However, the second select with the bind leaves me an empty box everytime.
Also the onchange doesn’t seem to fire a second time.
I’ve tried without the onchange and I’m getting nothingCould you help an old man out.
Thanks terribly
Alan (
Please assist
I am getting the following error:
Bind failed, element not found: catID [Enable debugging by adding ‘cfdebug’ to your URL parameters to see more information]
Here is my form:
<cfform>
<table>
<tr>
<td>Select Media Type:</td>
<td><cfselect name="cat1"
bind="cfc:business.getBizCats1()"
bindonload="true" /></td>
</tr>
<tr>
<td>Select Art:</td>
<td><cfselect name="cat1"
bind="cfc:business.getBizCats2({catID})" /></td>
</tr>
</table>
</cfform>
Here is Method 1
<cffunction name="getBizCats1" access="remote" returnType="array">
<!— Define variables —>
<cfset var data="">
<cfset var result=ArrayNew(2)>
<cfset var i=0>
<!— Get data —>
<cfquery name="data" datasource="#request.dsn#">
select catID, category from category1
where active = 1
order by category
</cfquery>
<!— Convert results to array —>
<cfloop index="i" from="1" to="#data.RecordCount#">
<cfset result[i][1]=data.catID[i]>
<cfset result[i][2]=data.category[i]>
</cfloop>
<!— And return it —>
<cfreturn result>
</cffunction>
Here is Method 2
<cffunction name="getBizCats2" access="remote" returnType="array">
<cfargument name="catID" type="numeric" required="true">
<!— Define variables —>
<cfset var data="">
<cfset var result=ArrayNew(2)>
<cfset var i=0>
<!— Get data —>
<cfquery name="data" datasource="#request.dsn#">
select catID, category from subCats1
where active = 1
and parentID = #arguments.catID#
order by category
</cfquery>
<!— Convert results to array —>
<cfloop index="i" from="1" to="#data.RecordCount#">
<cfset result[i][1]=data.catID[i]>
<cfset result[i][2]=data.category[i]>
</cfloop>
<!— And return it —>
<cfreturn result>
</cffunction>
We use cookies on our website to give you the most relevant experience by remembering your preferences and repeat visits. By clicking “Accept All”, you consent to the use of ALL the cookies. However, you may visit "Cookie Settings" to provide a controlled consent.
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. These cookies ensure basic functionalities and security features of the website, anonymously.
Cookie
Duration
Description
cookielawinfo-checkbox-analytics
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Analytics".
cookielawinfo-checkbox-functional
11 months
The cookie is set by GDPR cookie consent to record the user consent for the cookies in the category "Functional".
cookielawinfo-checkbox-necessary
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookies is used to store the user consent for the cookies in the category "Necessary".
cookielawinfo-checkbox-others
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Other.
cookielawinfo-checkbox-performance
11 months
This cookie is set by GDPR Cookie Consent plugin. The cookie is used to store the user consent for the cookies in the category "Performance".
viewed_cookie_policy
11 months
The cookie is set by the GDPR Cookie Consent plugin and is used to store whether or not user has consented to the use of cookies. It does not store any personal data.
Functional cookies help to perform certain functionalities like sharing the content of the website on social media platforms, collect feedbacks, and other third-party features.
Performance cookies are used to understand and analyze the key performance indexes of the website which helps in delivering a better user experience for the visitors.
Analytical cookies are used to understand how visitors interact with the website. These cookies help provide information on metrics the number of visitors, bounce rate, traffic source, etc.
Advertisement cookies are used to provide visitors with relevant ads and marketing campaigns. These cookies track visitors across websites and collect information to provide customized ads.
Leave a Reply