Multi-Selects Related with AjaxCFC
First, let's look at the component:
<cffunction name="getFillQuery" output="no" access="private" returntype="query">
<cfargument name="itemID" required="true" type="numeric" />
<!--- I am faking the query for test purposes --->
<cfset var selectQuery = queryNew("display,id") />
<!--- this would be where you do your real query --->
<cfset var i = 0 />
<cfloop from="1" to="5" index="i">
<cfset queryAddRow(selectQuery) />
<cfset querySetCell(selectQuery,"display","selected #arguments.itemID# option #i#") />
<cfset querySetCell(selectQuery,"id",i) />
</cfloop>
<cfreturn selectQuery />
</cffunction>
</cfcomponent>
There is not much going on here. Basically, I have a function that returns a query that, if this were real, would be filtered based upon an ID (or whatever criteria you want to send). Now, let's look at the form:
<head>
<script type='text/javascript'>
_ajaxConfig = { '_cfscriptLocation':'/sandbox/com/selectBoxes.cfc',
'_jsscriptFolder':'/sandbox/js',
'debug':false};
</script>
<script type='text/javascript' src='/sandbox/js/ajax.js'></script>
<script language="javascript">
var formItemToFill;
function callFill(thisSelect,target) {
formItemToFill = target;
DWREngine._execute(_ajaxConfig._cfscriptLocation, null, 'getFillQuery',thisSelect.options[thisSelect.selectedIndex].value,fill);
}
function fill(r) {
var getValue = function (thisRow) {
return thisRow.id; // name of the value column }
var getText = function (thisRow) {
return thisRow.display; // name of the display column }
DWRUtil.removeAllOptions(formItemToFill)
DWRUtil.addOptions(formItemToFill, r, [getValue, getText], null);
}
</script>
</head>
<body onload="callFill(document.forms['myForm'].foo1,'foo2');">
<form name="myForm">
<select name="foo1" onchange="callFill(this,'foo2');">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<br />
<select name="foo2" id="foo2"></select>
</form>
</body>
</html>
My callFill() function, for lack of a better name, is called when a new option is selected in my foo1 select box. I also call this function on the page load to pre-fill my second select box (foo2) with the initially selected item. The callFill() function simple calls my getFillQuery() function in my cfc and set fill() as the callback function. Notice how I have set a global JavaScript variable here to allow you to easily set the target select box you would like to fill.
When the data is returned, we set functions to return the data from the query we want used as the value and text of our select box options. Next, we use a built in AjaxCFC utility function to remove all options from the target select box. Finally, we use another built in utility function to add new options to the target using our query data.
That's it! Pretty easy once you are familiar with AjaxCFC. You could also easily expand this to add additional related select boxes as necessary.
This looks simple now that someone else has done the work for me! ;)
Glenn
Your example makes use of a numeric ID (itemID) that get passed to the selectBoxes.cfc (I suppose the number of the selected row of the 1st select box in the form). But what I need is to pass the _value_ of the selected row and that's a string (UUID). I've struggling with your code for a few hours, but don't know how to make it work.
Basically, the first selectbox is a loop from a query that outputs something like:
<select name="Parent">
<cfloop query="getParentIitems">
<option value="#ParentID#">#ParentTitle#</option>
</cfloop>
</select>
Then in selectBoxes.cfc I want to catch the value of the selection (#ParentID#" for the second query, something like:
<cfquery ...>
SELECT *
FROM Child
WHERE ParentID = '#arguments.Parent#'
</cfquery>
Does this makes sense?
rene
the 2nd selectbox returns "undefined" when a record was found in the CFC and nothing when no record was found.
you use "id" and "display" in the Javascript. When I query the database in the CFC I want to get the columns "ID" and "Titel". So I replaced your code with:
return thisRow.ID; // name of the value column
and
return thisRow.Titel; // name of the display column
my query in the CFC is straight forward:
<cffunction name="getFillQuery" output="no" access="private" returntype="query">
<cfargument name="itemID" required="true" type="string" />
<cfquery name="selectQuery" datasource="#application.config.DSN#">
SELECT ID, Titel
FROM toolkit_subdoelgroepen
WHERE DoelgroepID = '#arguments.itemID#'
ORDER BY Titel
</cfquery>
<cfreturn selectQuery />
</cffunction>
Simply based upon what you have provided I cannot see anything obviously wrong with your code. I would throw something like alert(thisRow.titel) in the getText() JS method (same for the id). This should create a popup with the values. If they still come up undefined, my best guess would be that you are running into some case-sensitivity issue here. Try something like thisRow.TITEL because sometimes CF returns query rows in all caps.
So, I'm tryin to modify for my case, I need 3 select boxes...
The first I have parameters like size... 1/2/3
In the DB, I will select the colors of the tips of clothes that is in arguments.itemID
Ok, I had the 1st and 2nd steps, but Now I wanna a 3rd select box, that I wanna the values from the first and secund select
like
<cfqyery>
Select * from tbl where size in (1stfield) and color in (2fiel).
</cfquery>
I dont know so much about JS, Ajax Neither, so, how can I return the next variables?
I've done it and it's right, changed the type to string, this way I could concat 2 variables and separate the information to acess another database.
Thanks


