Adobe ColdFusion 8

Using CFC functions in bind expressions

As with JavaScript functions, you can pass arguments to a CFC function specified in a bind expression positionally. When you do this, the argument names in a CFC function definition do not have to be the same as the bind parameter names, but the arguments in the bind expression must be in the same order as those in the CFC function definition.

Alternatively, you can pass named CFC function arguments. Then, the bind expression and CFC function must use the same names for the arguments, and the function does not have to define the arguments in the same order as they are passed. To specify argument names in a bind expression, use a format such as the following, which uses two named parameters, arg1 and arg2:

bind="cfc:mycfc.myfunction(arg1={myform:myfield1},arg2={myform:myfield2})"

Using binding in control attributes

When you use direct binding you specify a bind expression in a ColdFusion form or display control attribute. In the simplest, form of binding you can use form fields, such as a name field, to fill other fields, such as an e-mail field, as the following example. shows. When you enter a name or domain and tab to click in another field, the name is added to the e-mail field.

<html>
<head>
</head>
<body>

<cfform name="mycfform">
    First Name: <cfinput type="text" name="firstname" value=""><br>
    Last Name: <cfinput type="text" name="lastname" value=""><br>
    Domain: <cfinput type="text" name="domain" value=""><br>
    E-mail: <cfinput type="text" name="email1" size="30"
        bind="{firstname}.{lastname}@{domain}"> 
</cfform>
</body>
</html>

The following example shows the results of binding to radio buttons and check boxes with the same name attribute but different id attributes. Notice that because each control as a separate id value that is used in the label tags, you can click the labels to select and deselect the controls.

<html>
<head>
</head>
<body>

<cfform name="myform">
    Pick one:
    <cfinput id="pickers1" name="pickone" type="radio" value="Apples">
        <label for="pickers1">Apples</label>
    <cfinput id="pickers2" name="pickone" type="radio" value="Oranges">
        <label for="pickers2">Oranges</label>
    <cfinput id="pickers3" name="pickone" type="radio" value="Mangoes">
        <label for="pickers3">Mangoes</label>
    <br>
    <cfinput name="pickone-selected" bind="{pickone}"><br />
    <br />

    Pick as many as you like:
    <cfinput id="pickers4" name="pickmany" type="checkbox" value="Apples">
        <label for="pickers4">Apples</label>
    <cfinput id="pickers5" name="pickmany" type="checkbox" value="Oranges">
        <label for="pickers5">Oranges</label>
    <cfinput id="pickers6" name="pickmany" type="checkbox" value="Mangoes">
        <label for="pickers6">Mangoes</label>
    <br/>
    <cfinput name="pickmany-selected" bind="{pickmany}"><br />

</cfform>
</body>
</html>

Most applications call a CFC function, or JavaScript function, or use a URL to make an HTTP request (typically to a CFML page), and pass bind parameters as the function or URL parameters.

The following example uses the same form as the first example in the preceding section, but uses a different bind expression with the following features:

  • It uses the keyup events of the name and domain fields to trigger binding. So the e-mail field gets updated each time that you enter a letter in any of these fields.
  • It calls a CFC, which uses only the first letter of the first name when forming the e-mail address, and forces the domain name to be all lowercase.

The following example shows the bindapp.cfm page:

<html>
<head>
</head>
<body>
<cfform name="mycfform">
    First Name: <cfinput type="text" name="firstname" value=""><br>
    Last Name: <cfinput type="text" name="lastname" value=""><br>
    Domain: <cfinput type="text" name="domain" value=""><br>
    E-mail: <cfinput type="text" name="email"
        bind="cfc:bindFcns.getEmailId({firstname@keyup},{lastname@keyup},
        {domain@keyup})"> 
</cfform>
</body>
</html>

The following example shows the bindFcns.cfc CFC file:

<cfcomponent>
    <cffunction name="getEmailId" access="remote">
        <cfargument name="firstname"> 
        <cfargument name="lastname"> 
        <cfargument name="domain"> 
        <cfreturn "#left(arguments.firstname,1)#.#arguments.lastname#@#lcase(arguments.domain)#">
    </cffunction>
</cfcomponent>

Many of the examples in the documentation for ColdFusion Ajax features use binding, including more complex forms of binding.

Using the cfajaxproxy tag to bind to display controls

The cfajaxproxy tag with a bind attribute makes any of the following elements dependent on one or more bound ColdFusion Ajax controls:

  • A single CFC function
  • A single JavaScript function
  • An HTTP request; for example, the URL of a CFML page

The function or request executes whenever a specific event (by default, the onChange event) of the bound control occurs.

Note: if you specify a bind attribute with a URL, the HTTP request includes a _CF_NODEBUG URL parameter. ColdFusion checks this value, and when it is true, does not append to the response any debugging information that it normally would send. This behavior ensures that JSON responses to Ajax requests do include any non-JSON (i.e., debugging information) text.

The cfajaxproxy tag includes the following attributes that determine how the proxy handles the data returned by the function or the page:

  • The onError function specifies code to handle an HTTP error return. You can use this attribute with a URL or CFC bind.
  • The onSuccess function handles a valid return from the function or page and updates the display as required with the returned information.

Binding a function or request by using the cfajaxproxy tag enables you to perform a server-side action, such as updating a database by using bind parameter values based on a user action in some control, and then invoke a specific action or set of actions in one or more controls based on the server response. Because it uses an onSuccess function to process the return from the server, this form of binding provides substantially more flexibility than a CFML control bind parameter. This format also lets you use a control bind parameter for one kind of action, and the cfajaxproxy tag for a different activity.

For example, you might have a form with an editable cfgrid control and a delete button that a user clicks to delete a grid row. The application must have the following behaviors:

  • When the user clicks the delete button two things must happen:
    • The application must call a mycfc.deleteButton CFC function to delete the row from the database.
    • The grid must update to remove the deleted row.
  • When the user edits the grid content, the grid must call a mycfc.update function to update the database.

You can implement these behaviors by doing the following:

  • In the cfgrid tag, specify a bind attribute that uses a bind expression to call a mycfc.update function each time the user changes the grid contents.
  • In a cfajaxproxy tag, specify a bind attribute that calls the mycfc.deleterow CFC function, and specify an onSuccess attribute that calls the ColdFusion.Grid.refresh function to update the displayed grid when the CFC function returns successfully.

The following code snippets show how you could do this:

<cfajaxproxybind="cfc:mycfc.deleteRow({deletebutton@click},
        {mygrid.id@none}"onSuccess="ColdFusion.Grid.refresh('mygrid', true)">

...

<cfinput type="button" name="deletebutton">
<cfgrid name="mygrid" bind="mycfc.update({cfgridpage}, {cfgridpagesize},
        {cfgridsortcolumn}, {cfgridsortdirection})>

The following complete example shows a simple use of the bind attribute in a cfajaxproxy tag. For the sake of brevity, the bind expression calls a JavaScript function; as a result, the cfajaxproxy tag cannot use a onError attribute.

<html>
<head>
<script language="javascript">
    function test(x,y){
        return "Hello, " + x + "!";
    }
    function callbackHandler(result){
        alert("Bind expression evaluated. Result: \n" + result);
    }
</script>

<cfajaxproxy bind="javascript:test({input1@none},{button1@click})" 
        onSuccess="callbackHandler">
</head>

<body>
<cfform name="mycfform">
        <cfinput type="text" value="" name="input1" size="30">
        <cfinput type="button" name="button1" value="Submit">
</cfform>
</body>
</html>

Getting bindable attribute values in JavaScript

You can use the ColdFusion.Ajax.submitForm function in your JavaScript code to get the current value of any attribute of a bindable control. This technique is particularly useful for getting values for complex controls such as cfgrid and cftree. For more information, see the ColdFusion.Ajax.submitForm function in the CFML Reference.