CFGRID Cell Renderer - ComboBox (Select)

As promised in my last post, here is an example of creating a custom cell renderer for a select in a cfgrid. To be fair, the code isn't my own (though I can't seem to find where I originally found it. This example is purely to show that the custom renderer can be applied to a cfgrid within a Flash Form and can easily be customized to meet your individual needs.

The dataprovider is hardcoded in this example, but I imagine it could easily be dynamic with a little Flash remoting. The cool thing is that existing grid data item is pre-selected if it exists in the select's dataprovider. In the example, you'll also see that when the selected item changes, the data is populated in the appropriate grid cell.

Here's the code - first the cfm page:

<cfform format="flash" name="test" onload="setCellRenderer();">
<cfformitem type="script">

function setCellRenderer(){
testGrid.getColumnAt(2).cellRenderer = ComboBoxCell;
}
</cfformitem>
<cfformitem type="spacer"/>
<cfformgroup type="horizontal">
<cfgrid name="testGrid" width="260" selectmode="edit">
<cfgridcolumn name="dataCol" header="data col" width="100">
            <cfgridrow data="data,low">
            <cfgridrow data="data,medium">
            <cfgridrow data="data">
<cfgridcolumn name="sel" header="select" width="200">
</cfgrid>
       <cfinput type="button" name="testbtn" value="Show Value in Grid" onclick="alert(testGrid.selectedItem.sel);">
   </cfformgroup>
</cfform>

Now the ComboBoxCell.as - residing in the same directory as the cfm page:

import mx.core.UIComponent
import mx.controls.ComboBox

class ComboBoxCell extends UIComponent
{
   var combo : MovieClip;
   var owner : MovieClip;   // The row that contains the cell.    var listOwner : MovieClip; // the reference we receive to the list    var getCellIndex : Function; // the function we receive from the list    var   getDataLabel : Function; // the function we receive from the list    private static var COMBOBOX_DATA_PROVIDER : Array = [{label:"", data:""},
                              {label: "unrated", data: "unrated"},
                              {label: "low", data: "low"},
                              {label: "medium", data: "medium"},
                              {label: "high", data: "high"}];
   function ComboBoxCellRenderer()
   {
   }

   function createChildren(Void) : Void
   {      
      //Creates a ComboBox object and listen to changes       combo = createObject("ComboBox", "Combo", 0, {styleName:this, owner:this});
      combo.addEventListener("change", this);
      combo.dataProvider = COMBOBOX_DATA_PROVIDER;
      size();
   }

   // note that setSize is implemented by UIComponent    //and calls size(), after setting    // __width and __height    function size(Void) : Void
   {
      
   var h = __height;
var w = __width;
combo.setSize(w - 2, Math.max(h, listOwner.rowHeight - 2));   
   }

public function setValue(str:String, item:Object, sel:Boolean) : Void
   {
      /* Sets the ComboBox to the correspoinding
      cell data from the list owner's data provider
      if the cell data matches
      with any items available for the ComboBox. */

      
      var drawCombo:Boolean = true;
      if (item[getDataLabel()]!=undefined)
      {
         /* For each item's data in the ComboBox, verify if it matches
         the assigned data for the cell this ComboBox is in.
         Set the selectedIndex of the ComboBox to what matches. */

         for(var i:Number = 0; i < combo.length; i++)
         {
            if( combo.getItemAt(i).data == item[getDataLabel()] )
            {
               combo.selectedIndex = i;
               break;
            }
            if ( i == combo.length - 1 )
            {
               // There was no matching data, the ComboBox should not be shown.                //drawCombo = false;                // The original function hid the combobox if no data, i leave it in             }
         }
      }
      else
      {
         // There was no data, set the combobox to blank          combo.selectedIndex = 0;
      }
      
      combo._visible = drawCombo;
   }

   function getPreferredHeight(Void) : Number
   {
      return owner.__height;
   }

   function getPreferredWidth(Void) : Number
   {
      return owner.__width;
   }
   // This re-builds the dataProvider, the selected item    // as the first in the array    function reorder(datos:Array, choice:String):Array {
      var index:Number = 0
      var newArray = new Array()
      for(var i=0; i<datos.length; i++){      
         if(datos[i].label!=choice){
            index++
            newArray[index] = datos[i]
         } else newArray[0] = datos[i]
      }   
      return newArray
   }


   
   public function change()
   {
      // Handler for the ComboBox change event.       
      // Set the listOwner's data to the currently selected item's data of the combo box.       listOwner.dataProvider.editField(getCellIndex().itemIndex, getDataLabel(), combo.selectedItem.data);   
      listOwner.selectedIndex = getCellIndex().itemIndex;
   }

}

Live Example.



Related Blog Entries

Comments
Hello, I am unable to get this code to run? Am I doing something incorrect? Basically I have found that as soon as that script is call the flash form does not load. Any help would be much appreciated.
# Posted By Steve | 6/16/06 9:53 AM
Steve:

Are you saving ComboBoxCell.as in the same directory as the cfm page? Did you make any changes to the ComboBoxCell.as file? If there are errors in the Actionscript code the form won't load (and it won't give you an error sometimes either) :(
Post your AS code here if you've made changes and I'll see if I can spot any errors.
# Posted By todd | 6/16/06 10:08 AM
Is there a way to populate the combo box with a query instead of hard-coding?
# Posted By ray | 6/28/06 1:27 PM
ray:

Check out my post tomorrow morning - I'll show how to populate with a query.

todd
# Posted By todd | 6/29/06 9:22 PM
Did I miss something? Did you ever post an example of how to populate with a Query???
# Posted By boybles | 8/22/06 9:35 PM
Never mind...I just found it on the 6/30 post. Great work, Todd!!
# Posted By boybles | 8/22/06 9:36 PM
I copied and pasted the information found above into two new files and ran the .cfm file. The Flash form won't load unless I comment out onload="setCellRenderer();" and the entire <cfformitem type="script>...</cfformitem>.

I'm using MX7 on a Windows XP machine. Nothing else is in either file except for the code above.

What am I missing? Thanks!
# Posted By Jason | 6/12/07 5:12 PM
What version of 7 are you running? cfformitem type = script was not introduced until 7.0.1.
# Posted By todd sharp | 6/12/07 7:08 PM
I'm running 7,0,2,142559. If you're available to talk through IM, you can reach me on AIM or Yahoo at JasonCTIstl.
# Posted By Jason | 6/13/07 9:27 AM
Great stuff, my customers like the look and feel, and I like how easy it was to get all the sorting and resizing into a "code table".

Has anyone run into a problem, when using a dynamic source for the combo box, of the Grid rendering and being presented without the combo box? It seems that the combo box only appears about 1/3 of the time. Is there something I need to use to "slow down" the rendering of the grid until after the combo box has been created?
# Posted By Bingo | 8/31/07 6:43 PM
Bingo: I've seen that, but I haven't touched a Flash Form in so long I honestly can't remember if there is a fix. Is Flex not an option for you? You'd be much happier in the long run I think if you could make the switch.
# Posted By todd sharp | 9/2/07 12:30 PM
Unfortunately, Flex isn't currently an option. The powers-that-be are still debating between OpenLaszlo and Flex as a development standard. My CFGRIDs are being used in production, and the combo-box rendering was one of their "get to it when you can" items I finally have a chance to look into.

Once we do settle on a UI, I will be re-writing those code tables, but was basically checking to make sure I wasn't alone, or if someone had a silver bullet to solve my problem.

Thanks!!
# Posted By Bingo | 9/3/07 12:02 PM
How can add a checkbox component into a list component in flash..can u pls help me with the source code..
# Posted By kashi | 11/21/07 4:41 AM
Its done by using cell rendering method-by overriding the component class with 4 methods.
# Posted By Kashi(NDS) | 11/23/07 9:01 AM
How would you accomplish this with cfgrid format="html"?

I have a cfgrid bound to a cfc. It'll have one (and only one) editable column, ActiveStateID, which will be a select box on each row. My attempt to do this includes:

<cfgrid selectmode="edit" format="html" [snip] >
<cfgridcolumn name="ActiveStateID" header="State" select="yes" display="yes" values="1,2,3" valuesdisplay="Active,Enabled,Paused">
[snip]
</cfgrid>

The problem is that this gives me an ActiveStateID column containing the integer values of the foreign key (1, 2, or 3) instead of select boxes with Active, Enabled, and Paused and the correct option selected.

Ideas...?
# Posted By John | 9/22/08 1:20 PM

Calendar

Sun Mon Tue Wed Thu Fri Sat
      1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30       

Subscribe

Enter your email address to subscribe to this blog.

Tags

actionscript ajax blogging cfsnippets coldfusion flash forms flex funny stuff misc model-glue off topic personal project learn slidesix sql

Recent Comments

Editing A Query In A SQL Server DTS Package
JD said: Thanks for your post. Never unlike Microsoft to hide stuff in the hardest part time find. [More]

Mashing Spry Effects With CF8 Ajax Goodness
Mark Pitts said: I have had moderate success implementing Spry Accordian. Sadly the part that does is not working wil... [More]

Chinese Birth Calendar Accuracy Test
Toni Lehman said: This calendar was accurate for both my daughters and 4 grandchildren. I tried it for 11 of my other ... [More]

Virtual Memory - Am I The Last To Know?
Larry Miller said: The authors friend was right. Windows virtual memory system was designed by experts and they fully u... [More]

Using A PlayStation 2 HDD In Your PC
Alacres said: Thanks so much for the guide man! I did have a more specific question though, since I didn't see it ... [More]

RSS


coldfusionbloggers

FullAsAGoog MXNA

Consumed By Feed-Squirrel.com