20 Replies Latest reply on Apr 10, 2007 8:34 AM by Vyshak

    Changing the color of a particular cell after editing in a datagrid

    Vyshak Level 1
      Hi all, I tried this with custom item renderer but its either changing the entire Grid or the entire column. Is there any way to solve this by applying item renderer to a particular field? Help needed plz..


      Thanks in advance
        • 1. Re: Changing the color of a particular cell after editing in a datagrid
          michael_ramirez44
          Apply an ItemRenderer at the DataGridColumn level. In your ItemRenderer will need some logic to determine what the background color should be and if the condition is not met then use default background color.
          • 2. Re: Changing the color of a particular cell after editing in a datagrid
            Vyshak Level 1
            I even tried that, but i cudn't dispatch an edited event to the renderer and identify the edited field. please help me out in this.
            • 3. Re: Changing the color of a particular cell after editing in a datagrid
              peterent Level 2
              In your itemRenderer override the set data function. Be sure to call super.data = value as that is critical. In that function look at the data and determine what color it should be. Then set a member variable to the color. In your itemRenderer override the updateDisplayList function and use the member variable to set the color. If you don't want to override updateDisplayList, then use data binding.
              • 4. Re: Changing the color of a particular cell after editing in a datagrid
                Vyshak Level 1
                Thanks for that answer peter. I did the same and i can able to change the color of a particular column. But how can i identify a particular cell that is just edited, and apply this renderer only to that particular cell? Am trying with itemEditEnd event trying to pass the old and new values to the itemrenderer, compare it there and if they are different apply the itemrenderer to the currentTarget.itemRenderer or to the column itemRenderer. how can i apply this itemRenderer to a particular field? now i can able to set the itemRenderer property of the entire grid, or a column, using ClassFactory typecasting of my IR as file. Please help me out in this.
                thanks in Advance :)
                • 5. Re: Changing the color of a particular cell after editing in a datagrid
                  Vyshak Level 1
                  Hello.. anybody out ter to help me out? TIA
                  • 6. Re: Changing the color of a particular cell after editing in a datagrid
                    peterent Level 2
                    You should never try to force an itemRenderer to do anything. The itemRenderer should do its job based on the data in the DataGrid.

                    First, make sure your itemRenderer implements IDropInListItemRenderer. Most controls already implement it, most Containers do not. You need to get at the listData provided to the itemRenderer which gives you the rowIndex and columnIndex of the itemRenderer at that instant. Remember that itemRenderers are recycled so always be prepared to deal with changing data.

                    When you finish editing a cell you should record its row and column position someplace. One place might be in the dataProvider's record for that row as an extra field. For example, add the field "editedCells", which could be an Array of {row:Number, column:Number} objects.

                    In the itemRenderer's updateDisplayList function you can look at the listData.rowIndex & listData.columnIndex and compare them with the data.editedCells Array to see if the cell has been edited. If yes, change its color to the 'has been edited color', if not change its color to the default.
                    • 7. Re: Changing the color of a particular cell after editing in a datagrid
                      Vyshak Level 1
                      Peter thanks a lot for your reply... but i cudn't solve it out hereby am attaching the code, i know this wont work out but i badly need your help....

                      **************Datagrid Application*************************


                      <?xml version="1.0"?>
                      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml">

                      <mx:Script>
                      <![CDATA[
                      import mx.controls.listClasses.ListData;
                      import mx.controls.dataGridClasses.DataGridItemRenderer;
                      import mx.controls.Alert;
                      import mx.controls.TextInput;
                      import mx.events.DataGridEvent;
                      import mx.events.DataGridEventReason;
                      import mx.formatters.NumberFormatter;

                      [Bindable]
                      public var editedCells:Array=[{row:Number,column:Number}];
                      [Bindable]
                      public var initDG:Array = [
                      {Artist:'Pavement1', Album:'Slanted and Enchanted', Price:11.99,editedCells:editedCells},
                      {Artist:'Pavement2', Album:'Brighten the Corners', Price:85.99,editedCells:editedCells}
                      ];
                      public var flag:Boolean=false;


                      public function formatData(event:DataGridEvent):void {



                      var newData:String= TextInput(myGrid.itemEditorInstance).text;
                      var oldVal:String = event.currentTarget.editedItemRenderer.data[event.dataField];

                      data.editedCells.row=event.rowIndex;
                      data.editedCells.column=event.columnIndex;

                      return;

                      }
                      ]]>
                      </mx:Script>

                      <mx:DataGrid id="myGrid" dataProvider="{initDG}" editable="true" itemEditEnd="formatData(event);">
                      <mx:columns>
                      <mx:DataGridColumn dataField="Artist" itemRenderer="ColoredBackgroundItemRenderer"/>
                      <mx:DataGridColumn dataField="Album" itemRenderer="ColoredBackgroundItemRenderer"/>
                      <mx:DataGridColumn dataField="Price" itemRenderer="ColoredBackgroundItemRenderer"/>
                      </mx:columns>
                      </mx:DataGrid>
                      </mx:Application>

                      ****************************************************************************************** *********************

                      *****************************Item Renderer******************************************************************
                      <?xml version="1.0" encoding="utf-8"?>
                      <mx:Label xmlns:mx=" http://www.adobe.com/2006/mxml" initialize="init()">

                      <mx:Script>
                      <![CDATA[
                      import mx.controls.listClasses.ListData;


                      import flash.display.GradientType;
                      import flash.display.Graphics;


                      override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
                      {
                      super.updateDisplayList(unscaledWidth,unscaledHeight);
                      var g:Graphics = graphics;
                      var color:uint = (data.Artist>1 ? 0x0000CC : 0xdfeaca);
                      g.clear();
                      g.beginFill(color,1.0);
                      g.drawRect(0, -2, unscaledWidth, unscaledHeight+4 );
                      g.endFill();
                      }
                      ]]>
                      </mx:Script>
                      </mx:Label>
                      ****************************************************************************************** ***************************

                      i know this code is all a mess.. but please do update me am struck with it




                      • 8. Re: Changing the color of a particular cell after editing in a datagrid
                        Vyshak Level 1
                        please help me out.. stuck here :(
                        • 9. Re: Changing the color of a particular cell after editing in a datagrid
                          Vyshak Level 1
                          hi all,
                          Please gimme an update on this.. TIA
                          • 10. Re: Changing the color of a particular cell after editing in a datagrid
                            Vyshak Level 1
                            Also, i cudn't find the colIndex property in listData, when i used under item renderer wat may be the problem? flex newbie confused here....
                            • 11. Re: Changing the color of a particular cell after editing in a datagrid
                              peterent Level 2
                              I strongly urge you to read the documentation on any class that you have questions about. The property is columnIndex, not colIndex, for listData.

                              Since it is possible to have different cells being edited on different rows (eg, Artist on row 3, Album on row 5) you should use a different array for every row. You can create that array on the fly when you edit the cell.
                              • 12. Re: Changing the color of a particular cell after editing in a datagrid
                                Vyshak Level 1
                                I have tried with custom datagrid column.

                                ***************data grid column***********************
                                package
                                {
                                import mx.controls.dataGridClasses.DataGridColumn;

                                public class ChangingColorColumn extends DataGridColumn
                                {

                                public function ChangingColorColumn()
                                {
                                super();
                                }

                                public var backColor:uint = 0xFF0000;

                                }

                                }
                                ****************** Item renderer ************************************


                                package
                                {
                                import flash.events.Event;
                                import mx.controls.DataGrid;
                                import mx.controls.dataGridClasses.DataGridItemRenderer;
                                import mx.controls.dataGridClasses.DataGridListData;

                                public class ColorChangingRenderer extends DataGridItemRenderer
                                {

                                public function ColorChangingRenderer()
                                {
                                super();
                                }

                                private var lastText:String = null;
                                private var lastUID:String = null;


                                override public function validateNow():void
                                {
                                var needColorChange:Boolean = false;

                                super.validateNow();

                                if (!listData)
                                {
                                background = false;
                                return;
                                }

                                var dgListData:DataGridListData = listData as DataGridListData;
                                var dataGrid:DataGrid = dgListData.owner as DataGrid;


                                var column:ChangingColorColumn = dataGrid.columns[dgListData.columnIndex];
                                if (dgListData.uid == lastUID)
                                {
                                if (lastText != dgListData.label)
                                {
                                needColorChange = true;
                                }
                                }
                                lastUID = dgListData.uid;
                                lastText = dgListData.label;

                                if (needColorChange)
                                {
                                background = true;
                                backgroundColor = column.backColor;

                                }
                                }

                                }

                                }


                                ****************************Data Grid *******************************

                                <local:ChangingColorColumn headerText="Error Code" dataField="erclass" itemRenderer="ColorChangingRenderer" />

                                **********************************************************************

                                Everything works fine till i use the scroll bar. Once i scroll horizontally, All the colors are getting messed up? can anyone help me on this?

                                thanks in advance.
                                • 13. Re: Changing the color of a particular cell after editing in a datagrid
                                  peterent Level 2
                                  You don't need a custom DataGridColumn. All you need to do is have the cell being edited remembered (you don't have to do it in the dataProvider if it is confusing - us a public static var of the itemRenderer class) and have the itemRenderer verify it is the cell that was edited.
                                  • 14. Re: Changing the color of a particular cell after editing in a datagrid
                                    Vyshak Level 1
                                    thanks for ur reply Peter....

                                    Can u take a look at this item renderer? Can i modify this so that scroll bar color messing problem wont come in this renderer?

                                    Thanks in Advance
                                    • 15. Re: Changing the color of a particular cell after editing in a datagrid
                                      Vyshak Level 1
                                      ***************Item Renderer*********************
                                      package
                                      {
                                      import flash.events.Event;
                                      import mx.controls.DataGrid;
                                      import mx.controls.dataGridClasses.DataGridItemRenderer;
                                      import mx.controls.dataGridClasses.DataGridListData;
                                      import mx.controls.dataGridClasses.DataGridColumn;

                                      public class ColorChangingRenderer extends DataGridItemRenderer
                                      {

                                      public function ColorChangingRenderer()
                                      {
                                      super();
                                      }

                                      private var lastText:String = null;
                                      private var lastUID:String = null;


                                      override public function validateNow():void
                                      {
                                      var needColorChange:Boolean = false;

                                      super.validateNow();

                                      if (!listData)
                                      {
                                      background = false;
                                      return;
                                      }

                                      var dgListData:DataGridListData = listData as DataGridListData;
                                      var dataGrid:DataGrid = dgListData.owner as DataGrid;
                                      var column:DataGridColumn = dataGrid.columns[dgListData.columnIndex];
                                      if (dgListData.uid == lastUID)
                                      {
                                      if (lastText != dgListData.label)
                                      {
                                      needColorChange = true;
                                      }
                                      }
                                      lastUID = dgListData.uid;
                                      lastText = dgListData.label;

                                      if (needColorChange)
                                      {
                                      background = true;
                                      backgroundColor = 0xF50987;
                                      }
                                      }

                                      }

                                      }
                                      • 16. Re: Changing the color of a particular cell after editing in a datagrid
                                        peterent Level 2
                                        The itemRenderer should not override validateNow. You should at least override the set data function and determine then what the color should be. The override should also call invalidateDisplayList(). Override updateDisplayList and use the color to make the color change.
                                        • 17. Re: Changing the color of a particular cell after editing in a datagrid
                                          peterent Level 2
                                          I did a little bit of work on this and discovered some things that make doing this a little hard.

                                          Let's start with the application and DataGrid. You'll need to know if the value of the currently edited cell has changed or not. To do this, I created a variable called oldValue. I then added two event handlers to the DataGrid:

                                          itemEditBeginning="rememberValue(event)"
                                          itemEditEnd="markCell(event)"

                                          In the rememberValue function I copied the value of the cell to the oldValue:

                                          private function rememberValue( event:DataGridEvent ) : void
                                          {
                                          oldValue = dp[event.rowIndex][event.dataField];
                                          }

                                          In markCell I determined if the value had changed. If so, I placed its row/column index onto a list or I removed it from the list:

                                          private function markCell( event:DataGridEvent ) : void
                                          {
                                          if( event.reason == DataGridEventReason.CANCELLED ) {
                                          return;
                                          }

                                          var newValue:String =
                                          TextInput(event.currentTarget.itemEditorInstance).text;

                                          if( oldValue != Number(newValue) ) {
                                          HilightEditedCellRenderer.addCell(event.rowIndex, event.columnIndex);
                                          } else {
                                          HilightEditedCellRenderer.removeCell(event.rowIndex, event.columnIndex);
                                          }
                                          }

                                          HilightEditedCellRenderer is the itemRenderer for my cells. The addCell and removeCell functions are static members of the cell.

                                          <mx:DataGridColumn itemRenderer="renderers.HilightEditedCellRenderer" />

                                          In the HilightEditedCellRenderer I created an ArrayCollection to hold the list of cells and the following functions:

                                          public static var editedCells:ArrayCollection = new ArrayCollection();

                                          // isEditedCell determines if the row/column is in the editedCells collection.

                                          public static function isEditedCell( rowIndex:Number, columnIndex:Number ) : int
                                          {
                                          for(var j:int=0; j < editedCells.length; j++)
                                          {
                                          if( rowIndex == editedCells[j].rowIndex && columnIndex == editedCells[j].columnIndex )
                                          {
                                          return j;
                                          }
                                          }

                                          return -1;
                                          }

                                          // removeCell removes the row/column index pair from the editedCells collection
                                          public static function removeCell( rowIndex:Number, columnIndex:Number ) : void
                                          {
                                          // determine if the cell is already on the list and if so, remove it
                                          var index:int = isEditedCell(rowIndex, columnIndex);
                                          if( index >= 0 ) {
                                          editedCells.removeItemAt(index);
                                          }
                                          }

                                          // add cell places the row/column pair in the Collection if they are not already there:
                                          public static function addCell( rowIndex:Number, columnIndex:Number ) : void
                                          {
                                          // make sure the cell doesn't already exist - don't want to add it twice
                                          if( isEditedCell(rowIndex, columnIndex) < 0 ) {
                                          editedCells.addItem( {rowIndex:rowIndex, columnIndex:columnIndex} );
                                          }
                                          }
                                          Finally, I override the data set function to change the color:

                                          override public function set data(value:Object):void
                                          {
                                          super.data = value;

                                          if( listData )
                                          {
                                          // Determine the first visible row and visible column

                                          var firstRow:Number = (listData.owner as DataGrid).verticalScrollPosition;
                                          var firstCol:Number = (listData.owner as DataGrid).horizontalScrollPosition;

                                          // the listData.rowIndex is 1 based (not zero) and is based on the visible row. So if
                                          // the first visible row is 12 and the second row on the screen has changed, then
                                          // listData.rowIndex will be 2. To correct this, 1 is subtracted and firstRow is added.
                                          // A similar thing is done for the columnIndex (which is zero based).

                                          var index:int = isEditedCell(listData.rowIndex-1+firstRow, listData.columnIndex+firstCol);

                                          // Determine the color of the cell

                                          if( index >= 0 )
                                          {
                                          setStyle("color", 0xff0000);
                                          }
                                          else {
                                          setStyle("color", 0x000000);
                                          }
                                          }
                                          }

                                          Hope this helps.
                                          • 18. Re: Changing the color of a particular cell after editing in a datagrid
                                            Vyshak Level 1
                                            Hi Peter,
                                            Thanks a million for the detailed description. I tried it out and it worked out. But in my case, I have a bigger data grid with 10+columns, so a horizontal scroll bar appears in the data grid. Once i use this scroll bar, all the color that got changed get messed up. Can you provide any assistance on this? Once again I would like to thank u for helping me out despite of your busy schedule.


                                            • 19. Re: Changing the color of a particular cell after editing in a datagrid
                                              peterent Level 2
                                              I made a mistake in one of the lines. Change:
                                              var index:int = isEditedCell(listData.rowIndex-1+firstRow, listData.columnIndex+firstCol);

                                              to:
                                              var index:int = isEditedCell(listData.rowIndex - 1 + firstRow, listData.columnIndex);

                                              and it should work fine now.
                                              • 20. Re: Changing the color of a particular cell after editing in a datagrid
                                                Vyshak Level 1
                                                Thanks Peter, now it is working fine :) Once again thanking you for your immense help... :)