Our Blog

I just read this post by Paul Roberston, Dynamically change a cfinput form field’s label. I agree that the way the input is generated into mxml does not make it easy to access the label. However, I think there is a simpler solution to the problem. Granted, this solution does not give you a "direct" pointer to the label, but it does change the label as needed.

The key change is that instead of separating the label and the field, you can use the label property of the input and a binding. He also makes the input appear and disappear depending on the dropdown selection. That too, can be done with a binding.

<cfinput type="text" name="payDetail" label="{payMethod.selectedItem.data}" visible="{payMethod.selectedItem.data != ''}" />

The complete code:

<cfform name="paymentForm" format="flash" style="labelWidth:100;">
   <cfselect name="payMethod" label="Method" >
      <option></option>
      <option value="Account #">Department Account</option>
      <option value="PO Number">Purchase Order</option>
      <option value="Check #">Check</option>
      <option value="Card #">Credit Card</option>
   </cfselect>
      
   <cfinput type="text" name="payDetail" label="{payMethod.selectedItem.data}" visible="{payMethod.selectedItem.data != ''}" />
</cfform>

Live example

Download the source

Laura

Laura

33 Comments

  1. Todd
    OK - where did you get the red skin? Is that an option?
  2. Paul Robertson
    Hi, thanks for the feedback.

    While writing the article I realized that for the example I was giving this could be done just with bindings and without the onchange handler.d I wondered whether someone would notice and point that out. I guess someone noticed =).

    However, in the real-life case where I figured out this approach, things weren't so simple. In that case, the combo box data wasn't hardcoded -- it was retrieved from a database. There were actually two text fields whose labels were changed. In some of the cases only one of the two text fields was displayed. The size of the text fields was changed according to the selection (think Check # versus Credit Card #). And so on. For that case, I don't think it would have been possible to just use bindings.

    I wanted to give a minimal complexity example to make it easier to understand. At the same time I know that most real-world applications are more likely to be complex, so I chose to demonstrate the more complex solution (using the event handler and ActionScript) rather than the easier but less likely to be useful approach of just doing databinding.

    That said, I didn't think of binding the visibility of the input field -- I thought that was a nice touch.
  3. Laura
    Todd,
    It is not a halo skin option, it is using style=&quot;themeColor:##cc0000&quot; You can have any themeColor you want by writing the hex code. I left the red color that Paul had in his example.

    Paul,
    I agree with you. Sometimes simpler examples are not enough. I hope it didn't bother you that I made this post. I just thought people would benefit from alternative solution.
    Now, let me ask you, since you already have a hidden input, why not bind that value directly to the label instead of adding the cfformitem? That would let us avoid having to change all other labels to text so that they align.

    Cheers
  4. Paul Robertson
    Laura,
    "I hope it didn't bother you that I made this post."

    Not a bit. On the contrary, I've learned some great things from this (and many of your other) posts.

    "since you already have a hidden input, why not bind that value directly to the label instead of adding the cfformitem?"

    Um...that sounds like a great idea. I remember when I was first trying to work this out, I tried to do it with binding and couldn't get it to work for some reason, so I went to the cfformitem approach. I went back and played around with it some more, and I absolutely agree that it's better to just bind the hidden field to the label attribute directly rather than using the cfformitem workaround.

    So thanks for your advice and thoughts; I've gone ahead and posted a new version of my original tutorial to show how to do it using bindings:

    http://probertson.com/articles/2005/10/03/dynamic-cfinput-label-2/

    Paul
  5. Philippe Maegerman
    If you had more fields in your form and want the field not only to be invisible, but also to take no space, you could bind its height too

    height="{payMethod.selectedItem.data != '' ? undefined : 0}"
  6. Jason
    Need help on cfselect binding on cfgrid

    <cfselect name="Roles" width="200" multiple="yes" size="5"
    onchange="myGrid.dataProvider.editField(myGrid.selectedIndex, 'Roles', Roles.selectedItem.data);"
    query="qry_roles" value="id" display="name" >
    </cfselect>

    "Roles" is a comma-delimited number list (e.g. 1,2,3,6,8)

    Now it only store one selected row in the dataProvider if I select the multiple listbox, but I want my dataProvider on the grid column to store all selected row on my multiple listbox. So if I select row1 + row2 + row3, it will store as 1,2,3

    And how to highlight/select all the rows in my multiple listbox if it is a comma-delimited list?

    Any help will be really appreciated... thank you.
  7. Tim
    If you set a [cfinput type="text" visible=no]
    The label is still visible. Do you know of a way to make it appear and disappear as well?
  8. Willis

    Willis

    Great example. Got a question. If I only wanted the text box and label to appear when a certain item is selected (say Card # and Check #) and not the other options, how would I do that?

    In other words, only show the text box with label when Card # or Check # is selected.

    Any help will be really appreciated...Cheers
  9. Jimmy
    I'm trying to do a If/Then with Binding, but not sure if this is possible. I keep getting an error.

    Say I have a cfgrid.
    How can I do a
    IF
    {GridName.selectedItem.Name} EQ "Hello"
    Then
    Display Hello
    Else
    Display Good Bye
    EndIF

    I'd tried, but everytime it try to run the page is keeps on saying that the {GridName.selectedItem.Name} does not exist.

    Thanks
    Jimmy
  10. Laura
    Jimmy,
    To do small if-else statements in a bind, you can use:
    {(GridName.selectedItem.Name == 'Hello')?'Hello':'Good Bye'}
  11. casey
    Laura,

    How about.... Larger Bindings? I've been working with this code all day...

    <cfformgroup type="page" label="PMP: Action Steps">
    <cfformgroup type="vertical">
       <cfformgroup type="panel" label="Panel Viewer">

    <cfgrid name="stepList" height="90" rowheaders="false" SELECTMODE="single" onchange="myField.text =

    stepList.selectedItem.ActionStep">
       <cfgridcolumn name="ActionStep" header="Process Step">
          <cfgridrow data="Job Clarification">
          <cfgridrow data="Individual Development Action Plan (IDAP)">
          <cfgridrow data="Mid-Year Appraisal">
          <cfgridrow data="Annual Performance Review">
          <cfgridrow data="Ongoing Coaching & Feedback">
          <cfgridrow data="Team Goal & Objective Setting">
          <cfgridrow data="Team Development Action Plan (TDAP)">
          <cfgridrow data="Quarterly Review">
    </cfgrid>

    <cfformitem type="html"><i><b>Page Navigation</b></i> - Select the 'step' of most interest to you; corresponding information

    will be displayed below.</cfformitem>

    <cfinput type="text" name="myField" width="120" label="Filter by:">

    <cfset myXbind = '{stepList.selectedItem.ActionStep}'>

    <cfif myXbind eq "Job Clarification">
    <cfformitem type="html" bind="Display: JC blah blah blah"/>

    <cfelseif myXbind eq "Something else">
    <cfformitem type="html" bind="Display: SE blah blah blah"/>

    <cfelse>
    <cfformitem type="html" bind="Display: #myXbind#"/>
    </cfif>
       </cfformgroup>
    </cfformgroup>
    </cfformgroup>
  12. Maggie

    Maggie

    Hello,

    Can someone please let me know if it is possible to bind a value from one cfform (format=flash) to another one on the same page? The issue that I'm running into,is that in order to preserve the design I'm using, I want to use one cfform for the left nav, and have the data grid in the main center of the page to be able to bind to the left nav.

    I've tried using something like
    bind="{(_root.form1.dataGridName.selectedItem!=undefined)?_root.form1.dataGridName.selectedItem.TITLE:''}"
    in the form2, which doesn't throw an error, but doesn't work either. When I just try to reference the form name, I get an error that the form name cannot be referenced.

    Please, please help!! Thanks in advance!
  13. Laura
    Maggie,
    The only way to communicate between different Flash movies is by using "local connection". It is not an easy topic and I doubt it will work well in cfforms.
  14. Maggie

    Maggie

    Thanks so much for the rapid reply Laura, is there anything that you can recommend as a workaround? Is there any topic outlining how I might be able to experiment to see if it would work with the local connection? I thought that perhaps I might be able to save and define variables from one of the forms on the page and call it from the other using cfsavecontent and embedding some as in there. Do you think that is possibly a viable option?
  15. Maggie

    Maggie

    Hi again Laura, I just redesigned the page so that I can just use the one form - I figure it's more headache than it's worth :)
  16. Charlie

    Charlie

    Hope this is an easy binding question...
    I would like to bind a <cfinput> and a <cfformitem> to a couple columns from a <cfselect>. Here's the code:

    <cfquery name="myqry" datasource="mydatasouce">
    select col1, col2, col3, col4 from mytable
    </cfquery>

    <cfselect name="col2" Label="My Col 1:" multiple="no" query="myqry" Display="col1" value="col2" onchange="thegrid.dataProvider.editField(thegrid.selectedIndex, 'col1', col2.text); thegrid.dataProvider.editField(grid.selectedIndex, 'col2', col2.value);"></cfselect>
    <!---these bindings work, they populate two columns of a grid (not shown--->

    <cfformitem type="text" bind="{col2.selectedItem.data}" />
    <!---this binding also works--->
       
    I have not been able to bind a control, <cfinput> or <cfformitem>, to col3 or col4.
    I have tried a few things including an AS function to step thru the select, then grab the array elements from col3 or col4, but no luck. Can someone help. Thanks!
  17. Alain
    Hello,

    I am pulling my hair on that one, so I hope someone can help...
    I would like a cfformgroup to show only if a particular string (which I pull from a datagrid) is 1.Not undefined and 2.Not null. I have tried the code below. I think it should work...but it doesn't!!! Any idea??

    visible="({ResultGrid.selectedItem.mystring != undefined}) && ({ResultGrid.selectedItem.mystring.length > 0})"

    Any help greatly appreciated!

    Alain
    alainlevy at tele2 dot ch
  18. Don Kerr

    Don Kerr

    How do you bind a cfinput button to a cfformitem text onclick? In this simplified example below:

    <cfloop query="getbuttons">
    <cfinput type="button" name="#getbuttons.buttonname#"
    value"#getbuttons.buttonname#" onclick="????">
    </cfloop>

    Onclick of one of these dynamic button names, I want the selected buttonname text to appear in:

    <cfformitem type="text" id="buttonSelected" bind="????"></cfformitem>

    This is for a heading above a cfgrid, which is filtered based on which button. I have the filter working using your applyFilter function (excellent...thank you!), but just want to show which button was selected above it.

    If anyone could help, I'd appreciate it very much.

    Thanks,
    Don
  19. Tony
    Follow up from Maggie on number 12. if anyone could give some guidance is greatly appreciated.
    I have 2 separate forms, one in flash (params)for search criteria and one in HTML (params2) for display of data. I am trying to do header sorting, but based off the criteria selected.
    I have a hidden field on main form to capture the sort criteria from header selected calling a function to bind the value and enable a submit process. I've tried using javascript, but it does not recognize the field and have tried using <cfsavecontent>, but i'm not sure know how to pass the value as you would in javascript as such from one to the other:

    <A href = "##" onClick = "return SortResults(''RequestNo DESC')">Request</A> located in params2

    <SCRIPT type="text/javascript">
    function SortResults(ColumnToSortBy)
    {
       document.params.SortBy.value= ColumnToSortBy;
        submit();
       return false;
    }
    </SCRIPT>

    thanks
    Tony
  20. Erik
    Great information, but I have a question, I've been looking around but haven't been able to find any information on it, hopefully someone can help.

    I see you can change the label of a field, but how do I change the value of a cfinput field?

    Ex.
    CFC returns 1 record (will only ever return 1 record.), I want the (query) returned to populate the cfinput fields.

    Right now I have a hidden grid that recieves the data, then auto selects the first row, which is bound to the cfinput fields.

    Any help would be appreciated.
  21. Anthony

    Anthony

    I can't seem to figure out why the filter as you type feature isn't working. When I type some text in the text-box it clears the grid. I can't get it to work with Flash remoting.



    <cfsilent>
    <!--- make an empty query to populate the grid with no records --->
    <cfset memberList = queryNew("CustName,TechCode") />
    </cfsilent>

    <
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
    <head>
       <title>Populating a cfgrid with Flash Remoting</title>
    </head>

    <body>
    <cfform name="myform" height="550" width="499" format="Flash" timeout="300" onload="onFormLoad()">
    <cfformitem type="script">
    function onFormLoad(){
    var listener:Object = {};

    //put the controls in scope to avoid calling _root

    var getData:Function = getData;
    var search:Function = search;
    var whereismytech:mx.controls.DataGrid = whereismytech;


    listener.modelChanged = function(evt):Void {
    alert('Data loaded... clear datagrid until department is selected');

    whereismytech.removeEventListener('modelChanged',listener);

    <!--- empty search, should return no value --->

    search('',whereismytech,[]);
    }

    listener.search = search;

    getData();

    whereismytech.addEventListener('modelChanged',listener);
    }

    function getData():Void{
    <cfoutput>
    //create connection

    var connection:mx.remoting.Connection = mx.remoting.NetServices.createGatewayConnection( "http://#cgi.HTTP_HOST#/flashservices/gateway/";);
    //declare service

    var myService:mx.remoting.NetServiceProxy;
    </cfoutput>

    var responseHandler:Object = {};

    //put the controls in scope to avoid calling _root

    var whereismytech:mx.controls.DataGrid = whereismytech;


    responseHandler.onResult = function( results: Object ):Void {
    //when results are back, populate the cfgrid
    whereismytech.dataProvider = results;

    mx.managers.CursorManager.removeBusyCursor();
    }

    responseHandler.onStatus = function( stat: Object ):Void {
    //if there is any error, show an alert
    alert("Error while calling cfc:" + stat.description);
    mx.managers.CursorManager.removeBusyCursor();
    }

    //get service, make sure you write the correct path
    myService = connection.getService("/Working-Remoting/xxxx/flashRemotingResponder", responseHandler );
    mx.managers.CursorManager.setBusyCursor();
    //make call

    myService.getMembers();
    }

    <!--- search function --->
    function search( term:String, grid:mx.controls.DataGrid, columns:Array ):Void {

    var filterTerm:String = term.toString().toLowerCase();

    if(_global.unfilteredData[whereismytech.id] == undefined){
    if (_global.unfilteredData == undefined){
    _global.unfilteredData = {};
    }
    _global.unfilteredData[whereismytech.id] = grid.dataProvider.slice(0);
    }

    if(filterTerm.length > 0) {

    var filteredData:Array = [];

    for(var i = 0; i< _global.unfilteredData[grid.id].length; i++) {
    var item:Object = _global.unfilteredData[grid.id][i];
    var added:Boolean = false;

    for(var j = 0; j< columns.length; j++){
    if(!added){
    var value:String = item[columns[j]].toString().toLowerCase();
    if(value.indexOf(filterTerm) != -1) {
    filteredData.push(item);
    added = true;
    }
    }
    else {
    break;
    }
    }
    }

    grid.dataProvider = filteredData;

    }
    else
    {
    if (_global.unfilteredData[grid.id] != undefined)
    {
    grid.dataProvider = _global.unfilteredData[grid.id];
    }
    }
    }
    </cfformitem>
    <cfinput type="text" name="secondTerm" onchange="search(secondTerm.text,whereismytech,[column.selectedItem.data])" width="90" label="Filter by:">
             <cfselect name="column" label="in:" onchange="secondTerm.text=''" width="90">
    <option value="CustName">CustName</option>
    <option value="Job_ID">Job ID</option>
    <option value="Supvsr">Supvsr</option>
    <option value="CustAddr">CustAddr</option>
    </cfselect>

    <cfgrid name="whereismytech" query="memberList" height="200" rowheaders="false" >
             <CFGRIDCOLUMN NAME="TechCode" header="Tech Code">
             <CFGRIDCOLUMN NAME="CustName" HEADER="CustName">

       </cfgrid>
       <cfinput type="button" name="getValues" value="Populate data grid" >
    </cfform>
    </body>
    </html>
  22. Alex
    I am using <cfformitem type="html" bind="{(_root.employees.selectedItem.eval_complete!=1)?'<a href=\'pm_evaluationpop.cfm?eeid={employees.dataProvider[employees.selectedIndex]['last_name']}\'><b><u>Click Here to Complete Evaluation</b></u></a>':'Evaluation Complete'}"></cfformitem>

    Which doesn't work, if I remove the binding to the employees.dataprovider and manually enter a number or text item, the conditional works and I get my link. How do I do this and keep the link variables?
  23. Alex
    The bindings from a grid are not working with visibility of a button. My goal is to have the button area blank until they click on a grid item. What I get is a blank button. When they click on a grid item, the button value shows up.

    <cfinput type="button" name="EdSvDevPlanItem" value="Edit Dev Plan Item {devplanitems.dataProvider[devplanitems.selectedIndex]['train_plan_nbr']}" visible="{(devplanitems.selectedItem.object_desc != '') }">

    What am I doing wrong?
  24. Paul Ihrig

    Paul Ihrig

    how do i bind a text field, visible to a checkbox?
    <cfinput type="checkbox" name="vm_O" label="Others" />
    <cfinput type="text" name="vm_Other" label="Please specify"
    visible="{vm_O.selectedData = 'True'}" />
    and
    <cfinput type="checkbox" name="vm_O" label="Others" />
    <cfinput type="text" name="vm_Other" label="Please specify"
    visible="{vm_O.selectedItem.data != 'false'}" />
    dosnt seem to work.
    thanks
    -paul
  25. BKBK
    Hi Paul Ihrig,

    you could do in either of two ways:

    <cfform format="Flash">
    <cfinput type="checkbox" name="vm_0" label="Others" >
    <cfinput type="text" name="vm_Other" label="Please specify" visible="{vm_0.selected}">
    </cfform>

    or, alternatively,

    <cfform format="Flash">
    <cfformitem type="script">
    function vm_other_visible() {
       vm_Other._visible = vm_0.selected;
    }
    </cfformitem>
    <cfinput type="checkbox" name="vm_0" label="Others" onclick="vm_other_visible()" >
    <cfinput type="text" name="vm_Other" label="Please specify" visible="No">
    </cfform>
  26. Paul Ihrig

    Paul Ihrig

    THANKS..
    is there a way to make other required if the check box is checked?
    i tried required="{imp_O.selected}" but that throws an error.

    <cfinput type="checkbox" name="imp_O" label="Others" />
    <cfinput type="text" name="imp_Other" width="200" visible="{imp_O.selected}" />
  27. Paul Ihrig

    Paul Ihrig

    got it...
    <cfinput type="text" name="imp_Other" width="200"
    label="{(imp_O.selected == true)?'Please Specify':' '}" visible="{imp_O.selected}" />

    problem now is that it jogs text to left a few pixels when check...

    i am tring to find the right number of spaces to add..
    is there a way to make label show up on right side...
    guess i could just use type text to add label...
  28. Paul Ihrig

    Paul Ihrig

    didn't get it
    required="{(imp_O.selected == true)?'yes':'no'}"
    dosn't work.. for required...
    The value cannot be converted to a boolean because it is not a simple value.



    got it...
    <cfinput type="text" name="imp_Other" width="200"
    label="{(imp_O.selected == true)?'Please Specify':' '}" visible="{imp_O.selected}" />

    problem now is that it jogs text to left a few pixels when check...

    i am tring to find the right number of spaces to add..
    is there a way to make label show up on right side...
    guess i could just use type text to add label...
  29. BKBK
    Paul Ihrig wrote:
    > required="{(imp_O.selected == true)?'yes':'no'}"
    > dosn't work.. for required...
    > The value cannot be converted to a boolean

    I suspect the 'required' attribute cannot be expressed as actionscript. It apparently must be literally "yes" or "no". I wonder whether that is a bug.

    > {(imp_O.selected == true)?'Please Specify':' '}

    Better is:
    {imp_O.selected?'Please Specify':' '}

    > problem now is that it jogs text to left a few
    > pixels when check...

    Use cfformgroup. It enables each form control to be in its own separate container. For example,

    <cfform format="Flash">
    <cfformgroup type="HORIZONTAL">
    <cfinput type="checkbox" name="imp_0" label="Others" >
    </cfformgroup>
    <cfformgroup type="HORIZONTAL">
    <cfinput type="text" name="vm_Other" label="{imp_0.selected?'Please Specify':' '}" visible="{imp_0.selected}">
    </cfformgroup>
    </cfform>
  30. Justin M.
    I desperately need some help and I think you guys can probably help me. I don't know anything about ActionScript, or FLASH, but I am using CF Flash forms. My problem involves needing the ability to display text and an image inside of my flash form without doing a submit. I am using binding successfully in some parts of it, but I can't seem to get this other section to work. I have pasted a small peice of the code below.

    Preferably, I would like to do a cfif based on the bindings value. If that is not possible then I need to do if statements in actionscript based on the bindings value. Any help you could provide would be greatly appreciated.

       <cfformitem type="text" name="OfflineLabel" style="font-size:14px; color:660099; text-align:justify" visible="{Offline.selectedData != ''}">Offline:</cfformitem>

    My problem in this small example is that the code above still shows the "Offline:" even if Offline.selectedData == NULL.

    I have this situation in several locations throughout the code.

    Thank you for your help!
  31. Justin M.
    Philippe Maegerman's solution of "If you had more fields in your form and want the field not only to be invisible, but also to take no space, you could bind its height too

    height="{payMethod.selectedItem.data != '' ? undefined : 0}" "

    Does not work either.
  32. Justin M.
    You guys haven't responded in almost 3 weeks. That is pretty sad. Nevermind answering my response. What a joke.