CFGRID Cell Render - Enhancing the CheckBox

Posted By : todd sharp Posted At : June 10, 2006 12:34 PM Posted In: Flash Forms, ActionScript, ColdFusion

1

Jari asks:

"Would it be possible to use an mxml custom cell renderer to add on a cfgrid a checkbox, which would fire the onclick events."

The short answer is "kinda" - I'm guessing it could be done with mxml (as I did in this post but i'm not quite sure how to tackle it that way since I've yet to dig too deep into Flex. However, there is an easier way to go get the cell renderer to do what Jari is looking for using Actionscript.

Using the type="boolean" attribute of the cfgridcolumn presents us with a handy checkbox in the grid column. The only problem with this checkbox is that checking/unchecking it does not fire any events within the grid. To get around this restriction, we simply have to modify the custom cell renderer that is used to create the checkbox.

The cfm page looks like this:

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

function setCellRenderer(){
testGrid.getColumnAt(2).cellRenderer = CustomCheckCellRenderer;
}

function test(){
alert('This function is in the cfm page and is called from CustomCheckCellRenderer.');
}

</cfformitem>
<cfformgroup type="horizontal">
     <cfgrid name="testGrid" width="260">
        <cfgridcolumn name="dataCol" header="data col">
            <cfgridrow data="hi">
            <cfgridrow data="hi2">
            <cfgridrow data="hi3">
        <cfgridcolumn name="check" header="check box">
     </cfgrid>
     <cfinput type="text" name="testText" label="Text input populated by CustomCheckCellRenderer">
</cfformgroup>
</cfform>

The only thing I've done special here is call the setCellRenderer function onload of the form which sets the cell renderer of the second column of the grid to be CustomCheckCellRenderer.

The code for CustomCheckCellRenderer.as follows (saved within the same directory of the cfm page):

import mx.core.UIComponent
import mx.controls.CheckBox

class CustomCheckCellRenderer extends UIComponent
{

    var check : MovieClip;
    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
    var init = false;

    function CheckCellRenderer()
    {
    }

    function createChildren(Void) : Void
    {
        check = createClassObject(CheckBox, "check", 0, {styleName:this, owner:this});
        check.addEventListener("click", this);
        size();
    }

    // note that setSize is implemented by UIComponent and calls size(), after setting
    // __width and __height
    function size(Void) : Void
    {
        check.setSize(20, layoutHeight);
        check._x = (layoutWidth-20)/2;
        check._y = (layoutHeight-16)/2;
    }

    function getPreferredHeight(Void) : Number
    {
        return 16;
    }

    function getPreferredWidth(Void) : Number
    {
        return 20;
    }

    function setValue(str:String, item:Object, sel:Boolean) : Void
    {
//width = 0 is the same as hidden
var w = 0;
if( listOwner.__columns[getCellIndex().columnIndex] != undefined && listOwner.__columns[getCellIndex().columnIndex]['width'] != undefined )
{
     w = listOwner.__columns[getCellIndex().columnIndex]['width'];
     }
// set visible if display is true (width >
0)
check.visible = false;
if( item != undefined && w > 0 )
{
check.visible = true;
}

if( item != undefined )
{
check.selected = false;
if( item[getDataLabel()] == 1 || item[getDataLabel()] == "true" || item[getDataLabel()] == "yes" )
{
check.selected = true;
listOwner.dataProvider[getCellIndex().itemIndex][getDataLabel()] = "true";
init=true;
}
else
{
if( !init && item[getDataLabel()].length == 1)
{
init=true;
this.click();
}
else
{
init=true;
}

listOwner.dataProvider[getCellIndex().itemIndex][getDataLabel()] = "false";
}
}
    }

    function click()
    {
        //the original click() function edits the grid to be true/false
        //depending on the check value

        listOwner.editField(getCellIndex().itemIndex, getDataLabel(), check.selected);
        
        //I've added the following code to show
//how to extend the click function
        
        //set the selectedIndex of the grid -
//this is usefull if you are
        //looking to do anything with the gridrow

        //declare a variable for the current gridrow

        var curRow = getCellIndex().itemIndex;
        listOwner.selectedIndex = curRow;
        
    
        
        //set up a msg
        var msg = 'You have selected the checkbox in row '+curRow+'. The current value is '+check.selected;
        
        //show a msg
        mx.controls.Alert.show(msg);
        
        //populate something in a text box
        _root.testText.text = _root.testGrid.selectedItem.dataCol;
        
        //call a function in the cfm page
        _root.test();
    }

}

You can view a live example here.

In my next post, I'll show how to modify this concept to create a custom renderer for a select in a grid.

Comments (1)

Barry Brunning's Gravatar Thank you. I've looked for this feature previously without success. Even now I had to go to the third page of my Google search to find it. Can't understand why there's not been more applause.