달력

12

« 2024/12 »

  • 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
  • 31
2015. 3. 2. 23:32

그리드 헤더 체크박스 Enjoy/FLEX2015. 3. 2. 23:32

3 state checkbox for headerrenderer in datagrid




출처 : https://srinichekuri.wordpress.com/2011/05/20/3-state-checkbox-for-headerrenderer-in-datagrid/


Today I made by first contribution to Adobe Cook by posting about this topic. The idea on this topic started by showing my earlier post on gmail header to my colleague who also happens to be the owner of post in adobe cookbook that talks about 3State checkbox for TreeRenderer. He pointed out that the checkbox in the header can be threeState. Well thats a common problem but suprisingly this was not addressed in the online opensource community for Datagrid. I saw an opportunity and coded it.

Note:
There is a bug in my colleague’s post that it doesn’t take care of the initial state, I have taken care of that bug in my code.My code itself is inspired by my colleagues post.

The checkbox in headerRenderer will have three states:

  • All the rows in the datagrid are selected (‘select’ State).
  • None of the rows in the datagrid are selected(‘unselected’ State)
  • One or more rows (but not all) are selected(‘undecided’ State).

ScreenShots:
Change of state from ‘unselect’ state to ‘select’ state:

Change of state from ‘select’ state to ‘undecided’ state:

Code:

Here is the code for Main.mxml:

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                xmlns:s="library://ns.adobe.com/flex/spark"
                xmlns:mx="library://ns.adobe.com/flex/mx"
                creationComplete="creationCompleteHandler(event)">
 
    <fx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.controls.Alert;
            import mx.events.FlexEvent;
 
            private var _dataProvider:ArrayCollection;
            [Bindable]
            public function set dataProvider(value:Object):void{
                _dataProvider=value as ArrayCollection
            }
            public function get dataProvider():Object{
                return _dataProvider;
            }
 
            protected function creationCompleteHandler(event:FlexEvent):void
            {
                dataProvider = new ArrayCollection([
                    {checked:true, name:'Jim Smith'},
                    {checked:false, name:'Yancy Williams'}]);
            }
 
        ]]>
    </fx:Script>
 
    <mx:DataGrid id="myDataGrid" left="10" top="10" dataProvider="@{dataProvider}">
        <mx:columns>
            <mx:DataGridColumn textAlign="center" dataField="checked"
                                       width="90"
                                       rendererIsEditor="true"
                                       sortable="false"
                                       itemRenderer="renderer.CheckboxItemRenderer"
                                       headerRenderer="renderer.ThreeStateCheckBoxHeaderRenderer"
                                       />
            <mx:DataGridColumn headerText="Name" dataField="name" width="110"/>
        </mx:columns>
    </mx:DataGrid>
 
</s:Application>

Code for headerRenderer

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
package renderer
{
    import flash.events.MouseEvent;
 
    import mx.collections.ArrayCollection;
    import mx.controls.DataGrid;
    import mx.controls.Image;
    import mx.controls.dataGridClasses.DataGridListData;
    import mx.controls.dataGridClasses.MXDataGridItemRenderer;
 
    import spark.components.CheckBox;
 
    /**
     * HeaderRender with a Three State Checkbox.
     * <p>Functionality:<br>
     *    <li>Selecting the checkbox will select all the rows in the datagrid</li>
     *    <li>Unselecting the checkbox will unselect all the rows in the datagrid</li>
     *
     * <p>The checkbox can be three states at any point:<br>
     *    <li>select: This would mean that all the rows are selected</li>
     *    <li>unselect: This would mean that none of the rows are selected</li>
     *    <li>undecided: This would mean that one or more (but not all) of the rows are selected</li>
     *
     * @author Srinivas Chekuri
     *
     */
    public class ThreeStateCheckBoxHeaderRenderer extends MXDataGridItemRenderer
    {
        protected var myCheckBox:CheckBox;
        protected var myImage:Image;
        private var imageWidth:Number   = 9.5;
        private var imageHeight:Number  = 9.5;
        private var inner:String    = "assets/inner.png";
 
        private const SELECT_STATE:String="select";
        private const UNSELECT_STATE:String="unselect";
        private const UNDECIDED_STATE:String="undecided";
 
        private var STATE:String = UNSELECT_STATE;
 
        /**
         * Constuctor
         *
         */
        public function ThreeStateCheckBoxHeaderRenderer()
        {
            super();
        }
 
        /**
         * overides the function <code>createChildren</code> in the component lifecyle. This instantiates
         * <code>myCheckBox</code> and <code>myImage</code>.
         *
         */
        override protected function createChildren():void{
            super.createChildren();
            myCheckBox = new CheckBox();
            myCheckBox.setStyle("horizontalCenter", "0");
            myCheckBox.setStyle("verticalCenter", "0");
            myCheckBox.addEventListener( MouseEvent.CLICK, checkBoxClickHandler );
            addElement(myCheckBox);
            myImage = new Image();
            myImage.source = inner;
            myImage.addEventListener( MouseEvent.CLICK, imageClickHandler );
            myImage.visible=false;
            addElement(myImage);
        }
 
        /**
         * overides the function <code>updateDisplayList</code> in the component lifecyle. This sets the
         * display settings of <code>myCheckBox</code> and <code>myImage</code>. This also updates the state
         * according to the selections made in the datagrid.
         *
         * @param unscaledWidth
         * @param unscaledHeight
         *
         */
        override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void{
            super.updateDisplayList(unscaledWidth,unscaledHeight);
 
            myImage.x=myCheckBox.x+1.5;
            myImage.y=myCheckBox.y+5.5;
 
            myImage.width=imageWidth;
            myImage.height=imageHeight;
 
            if(areAllSelected()){
                STATE=SELECT_STATE;
            }else if(isAnyColumnSelected()){
                STATE=UNDECIDED_STATE;
            }else if(!isAnyColumnSelected()){
                STATE=UNSELECT_STATE;
            }
            checkState();
        }
 
        /**
         * Makes adjustments to the <code>visible</code> property of <code>myImage</code> and
         * <code>selected</code> of <code>myCheckBox</code> according to the state.
         *
         * @private
         *
         */
        private function checkState():void{
            if(STATE==SELECT_STATE){
                myImage.visible=false;
                myCheckBox.selected=true;
            }else if(STATE==UNSELECT_STATE){
                myImage.visible=false;
                myCheckBox.selected=false;
            }else{
                myImage.visible=true;
                myCheckBox.selected=false;
            }
        }
 
        /**
         * Handler method for <code>MouseEvent.CLICK</code> event on <code>myImage</code>.
         *
         * @param event
         *
         */
        protected function imageClickHandler(event:MouseEvent):void{
            STATE=SELECT_STATE;
            checkState();
            selectAll();
        }
 
        /**
         * Handler method for <code>MouseEvent.CLICK</code> event on <code>myCheckBox</code>.
         *
         * @param event
         *
         */
        protected function checkBoxClickHandler(event:MouseEvent):void{
            selectAll();
        }
 
        /**
         * Selects all the rows in the datagrid.
         *
         */
        private function selectAll():void{
            var ac:ArrayCollection = DataGrid(DataGridListData(listData).owner).dataProvider as ArrayCollection;
            for each (var o:Object in ac){
                o.checked=myCheckBox.selected;
            }
            DataGrid(DataGridListData(listData).owner).dataProvider = ac;
        }
 
        /**
         * Checks if all the rows are selected in the datagrid.
         *
         * @return Boolean: returns <code>true</code> if all rows are selected else returns
         * <code>false</code>.
         *
         */
        private function areAllSelected():Boolean{
            var ac:ArrayCollection = DataGrid(DataGridListData(listData).owner).dataProvider as ArrayCollection;
            var b:Boolean=true;
            for each (var o:Object in ac){
                if(!o.checked){
                    b=false;
                    break;
                }
            }
            return b;
        }
 
        /**
         * Checks to see if any one of the rows are selected.
         *
         * @return Boolean: return <code>true</code> if any one the rows are selected.
         *
         */
        private function isAnyColumnSelected():Boolean{
            var ac:ArrayCollection = DataGrid(DataGridListData(listData).owner).dataProvider as ArrayCollection;
            var b:Boolean=false;
            for each (var o:Object in ac){
                if(o.checked){
                    b=true;
                    break;
                }
            }
            return b;
        }
    }
}

Code for itemRenderer:

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
31
32
33
<!--?xml version="1.0" encoding="utf-8"?-->
 
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.controls.DataGrid;
            import mx.controls.dataGridClasses.DataGridListData;
            import mx.events.FlexEvent;
 
            /**
             * Handler function for <code>MouseEvent.CLICK</code> on checkbox.
             *
             * @param event MouseEvent
             *
             */
            public function clickHandler(event:MouseEvent):void{
                var o:Object = DataGrid(DataGridListData(listData).owner).selectedItem;
                o.checked=cb.selected;
                ArrayCollection(DataGrid(DataGridListData(listData).owner).dataProvider).setItemAt(o,DataGrid(DataGridListData(listData).owner).selectedIndex);
            }
 
            /**
             * Overides <code>data</code> parameter to set the <code>selected</code> parameter of the
             * checkbox.
             *
             * @param value Object
             */
            override public function set data(value:Object):void{
                if(value!=null){
                    super.data=value;
                    cb.selected=value.checked;
                }
            }
        ]]>

You can download the code from my post in Adobe cook book.

:
Posted by 라면스프