Skip to main content
Inspiring
April 1, 2012
Question

Cascading cfselects in CF 9

  • April 1, 2012
  • 1 reply
  • 3378 views

I've done a good amount of searching, including in this forum, and I'm still missing some important understanding about how to have two or more cfselects in a cfform, each dependent on the previous one. The best reference I've found is from Ben Forta's blog (Surprise! Surprise!) http://www.forta.com/blog/index.cfm/2007/5/31/ColdFusion-Ajax-Tutorial-2-Related-Selects, but when I adapt that to my own database, I get "bind value is not a 2D array." I could probably do my cfselects with JQuery, but using components looks so good to me. Below is the code I'm using. One initial question relates to CFINVOKE. If my CFC has two or more functions, which one do I put here? I jsut guessed and put in the first one. Do I even need CFINVOKE? In his example, I don't think Ben even uses this tag. As an aside, I wish I had the DB that Ben uses, the cfartgallery. Unfortunately, I downloaded my CF and used a license key. I guess the sample DB is included only on media.

At any rate, if you see my error, please point it out. Understanding how cascading cfselects work would be a major step forward for me.

<cfinvoke component="components.forta1" method="getName" returnvariable="u"></cfinvoke>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>Untitled Document</title>

</head>

<body>

    <h1>Select</h1>

    <p>

    Select something

    </p>

   

<cfinvoke component="components.forta1" method="getName" returnvariable="u"></cfinvoke>   

<cfform>

<table>

    <tr>

        <td>Select Name:</td>

        <td><cfselect name="address_book_ID"

                bind="components:forta1.getName()"

                bindonload="true" /></td>

    </tr>

    <tr>

        <td>Select Email:</td>

        <td><cfselect name="listID"

                bind="components:forta1.getEmail()" /></td>

    </tr>

</table>

</cfform>

</body>

</html>

<cfcomponent output="false">

    <cfset THIS.dsn="myDB">

    <!--- Get array of media types --->

    <cffunction name="getName" access="remote" returnType="query">

        <!--- Define variables --->

        <cfset var data="">

        <cfset var result=ArrayNew(2)>

        <cfset var i=0>

        <!--- Get data --->

        <cfquery name="data" datasource="#THIS.dsn#">

        SELECT address_book_ID, lastname

        FROM address_book

        ORDER BY lastname

        </cfquery>

        <!--- Convert results to array --->

        <!---

        <cfloop index="i" from="1" to="#data.RecordCount#">

            <cfset result[1]=data.address_book_ID>

            <cfset result[2]=data.lastname>

        </cfloop>

                    --->

        <!--- And return it --->

        <cfreturn data>

    </cffunction>

    <!--- Get art by media type --->

    <cffunction name="getEmail" access="remote" returnType="query">

        <cfargument name="address_book_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="#THIS.dsn#">

        SELECT email, listID

        FROM email_list

        WHERE listID = '120'

        ORDER BY email

        </cfquery>

   

        <!--- Convert results to array --->

        <!---

        <cfloop index="i" from="1" to="#data.RecordCount#">

            <cfset result[1]=data.listID>

            <cfset result[2]=data.email>

        </cfloop>

                    --->

        <!--- And return it --->

        <cfreturn data>

    </cffunction>

</cfcomponent>

    This topic has been closed for replies.

    1 reply

    sbudlongAuthor
    Inspiring
    April 1, 2012

    Mistake! I copied some code where I hard-coded a value. It's under "Get Data" and "WHERE list ID='120' the line should be

    WHERE address_book_ID = #ARGUMENTS.address_book_ID#.

    I still get the error with this line.

    sbudlongAuthor
    Inspiring
    April 1, 2012

    I finally went ahead and just created a cfartgallery DB with the fields that Ben calls in his CFC. And populated both tables with one record. Still the same error message. "Bind value is not a 2D array."

    Inspiring
    April 1, 2012

    Do I even need CFINVOKE?

    No. It is useful for testing your functions to verify they work. But it is not necessary for your form.

    As an aside, I wish I had the DB that Ben uses, the cfartgallery. Unfortunately, I downloaded my CF and used a license key. I guess the sample DB is included only on media

    It is part of the CF documentation. It is only installed if you select the "documentation" option during the installation.

    "bind value is not a 2D array."

    You are close, but it looks like you mixed up his example a bit.

    1) His function returns an array. But yours is returning a query object (ie "data"). Hence the error. However, things have changed a bit since that article was written. CF8 only supported binding select lists to an array. CF9 supports binding with arrays OR queries. To make your current function work with a query, just supply the query columns you want to bind in your cfselects. For example, with getName():

            <cfquery name="data" ...>

            SELECT address_book_ID, lastname

            ....

            </cfquery>

           <cfselect name="address_book_ID"

                    bind="components:forta1.getName()"

                    display="LastName"

                    value="address_book_id"

                    bindonload="true" /></td>

    2) You dropped the bind relating the second list to the first one. You need to add it back so the list only displays the email for the selected name. Also be sure to add cfqueryparam in your actual query.

                 <cfselect name="listID"

                        bind="components:forta1.getEmail( {address_book_ID} )"

                        display="email"

                        value="listID" />

    Message was edited by: -==cfSearching==-