20 Replies Latest reply on Apr 13, 2011 1:58 AM by dinko_ivanov

    Editable Spark DataGrid

    Zolotoj Level 3

      1. How can I get rid of a TextInput editor border that appears when I click on a cell before I start typing in?

      2. When I finish typing and move to another cell the text being just typed disappears. What do I need to do to fix that?

       

      Thanks

        • 1. Re: Editable Spark DataGrid
          Darrell Loverin Level 4

          1. Create a subclass of the DefaultGridItemEditor. Override the prepare() method and customize the editor however you wish.

          2. Put a break point on GridItemEditor.save() and see what happens.

           

           

           

          -Darrell

          • 2. Re: Editable Spark DataGrid
            Zolotoj Level 3

            That's what I am doing. I am having a strange behavior though. First, I have to click twice on the cell to initiate an editing session. Second, when I leave the cell the entered text disappears, clicking back on the cell will show the text. Any ideas?

             

            Thanks

            • 3. Re: Editable Spark DataGrid
              Zolotoj Level 3

              does not work

              here is a custom editor:

              package
              {
                   import spark.components.gridClasses.DefaultGridItemEditor;
                   import spark.components.gridClasses.IGridItemEditor;
                   
                   public class testEditor extends DefaultGridItemEditor implements IGridItemEditor
                   {
                        public function testEditor()
                        {
                             //TODO: implement function
                             super();
                        }
                        override public function prepare():void
                        {
                             setStyle("borderVisible", false);
                             trace(value);
                        }
                        override public function save():Boolean
                        {
                             trace(value);
                             return false;
                        }
                   }
              }
              here is datagrid:
              <s:DataGrid requestedRowCount="2" fontSize="11" sortableColumns="false"
                                            id="cars" rowHeight="22" resizableColumns="false" editable="true">
                                  <s:columns>
                                       <s:ArrayList>
                                            <s:GridColumn dataField="initial" headerText="Initial">
                                                 <s:itemRenderer>
                                                      <fx:Component>
                                                           <s:GridItemRenderer>
                                                                <s:layout>
                                                                     <s:VerticalLayout paddingLeft="1" 
                                                                                           verticalAlign="middle"/>
                                                                </s:layout>
                                                                <local:gridTextInput id="txtCarInitial" restrict="a-zA-Z" width="50" 
                                                                                bindPropertyName="initial"/>
                                                           </s:GridItemRenderer>
                                                      </fx:Component>     
                                                 </s:itemRenderer>
                                                 <s:itemEditor>
                                                      <fx:Component>
                                                           <s:GridItemEditor>
                                                                <local:testEditor id="valueDisplay" width="50"/>                                                  
                                                           </s:GridItemEditor>
                                                      </fx:Component>
                                                 </s:itemEditor>
                                            </s:GridColumn>
              .....
              
              
              

               

              Problems.

              1. Have to click twice on the cell to start editing

              2. when leave text disappears

              3. save does not fire

              4. prepare does not fire

              • 4. Re: Editable Spark DataGrid
                Darrell Loverin Level 4

                >> First, I have to click twice on the cell to initiate an editing session.

                An editing session is only initiated on a previously selected cell. If you would like to have an option to start an edit session on any click in a cell then please write a bug and post a link to it here. You can get the single click behavior by adding event listeners to the data grid that look like this:

                 

                            private var mouseDownRowIndex:int;

                            private var mouseDownColumnIndex:int;

                             

                            protected function dataGrid_gridMouseDownHandler(event:GridEvent):void

                            {

                                    mouseDownRowIndex = event.rowIndex;

                                    mouseDownColumnIndex = event.columnIndex;

                            }

                             

                            protected function dataGrid_gridMouseUpHandler(event:GridEvent):void

                            {

                                if (event.rowIndex == mouseDownRowIndex &&

                                    event.columnIndex == mouseDownColumnIndex &&

                                    event.column.editable &&

                                    !event.grid.dataGrid.itemEditorInstance)

                                {

                                    trace("start item editor on single click");

                                    event.grid.dataGrid.startItemEditorSession(event.rowIndex, event.columnIndex);

                                }

                            }

                             

                 

                             

                >> Second, when I leave the cell the entered text disappears, clicking back on the cell will show the text.

                Sounds like the dataprovider is not being updated. The itemUpdated() method is called on the dataprovider in the GridItemEditor.save() method. See if you are getting there.

                 

                 

                -Darrell

                • 5. Re: Editable Spark DataGrid
                  Darrell Loverin Level 4

                  Type changing this:

                   

                                                    <s:itemEditor>
                                                          <fx:Component>
                                                               <s:GridItemEditor>
                                                                    <local:testEditor id="valueDisplay" width="50"/>                                                 
                                                               </s:GridItemEditor>
                                                          </fx:Component>
                                                     </s:itemEditor>

                   

                  to this:

                   

                                                    <s:itemEditor>
                                                          <fx:Component>
                                                              <local:testEditor id="valueDisplay" width="50"/>                                                 
                                                          </fx:Component>
                                                     </s:itemEditor>

                   

                   

                  -Darrell

                  • 6. Re: Editable Spark DataGrid
                    Zolotoj Level 3

                    Error:

                    id attribute is not allowed on the root tag of a component

                    • 7. Re: Editable Spark DataGrid
                      Darrell Loverin Level 4

                      remove the id attribute.


                      • 8. Re: Editable Spark DataGrid
                        Zolotoj Level 3

                        Yes, I did it. Here is my code:

                        Item Editor

                        package
                        {
                             import spark.components.gridClasses.DefaultGridItemEditor;
                             import spark.components.gridClasses.IGridItemEditor;
                             
                             public class testEditor extends DefaultGridItemEditor implements IGridItemEditor 
                             {
                                  public function testEditor()
                                  {
                                       //TODO: implement function
                                       super();
                                  }
                                  /*override public function prepare():void
                                  {               
                                       //trace(value);
                                  }*/
                                  override public function save():Boolean
                                  {
                                       data[column.dataField]
                                       trace(value);
                                       trace(data[column.dataField]);
                                       return false;
                                  }
                             }
                        }
                        

                        Prepare is commented out because it will fail at run-time.

                        Save will show new data, but data[column.dataField] is empty -  cannot update dataProvider.

                        A little bit more help, please?

                        • 9. Re: Editable Spark DataGrid
                          Zolotoj Level 3

                          I wasn't exactly correct.

                          after data[column.dataField] = value; trace(data) will show data with new value but the cell still looses its text.

                          • 10. Re: Editable Spark DataGrid
                            Zolotoj Level 3

                            <See if you are getting there

                            How would I do that?

                            • 11. Re: Editable Spark DataGrid
                              Darrell Loverin Level 4

                              I don't understand why you are overriding the save() method. Your save() doesn't call itemUpdated() on the dataProvider. Why are you returning  "false" from saved()? Is the data in your cell editor saved if you comment out your save() method?

                               

                               

                               

                              -Darrell

                              • 12. Re: Editable Spark DataGrid
                                Darrell Loverin Level 4

                                <See if you are getting there

                                >>How would I do that?

                                 

                                Set a break point in GridItemEditor.save().  Step thru the code to see what happens.

                                 

                                 

                                 

                                -Darrell

                                • 13. Re: Editable Spark DataGrid
                                  Zolotoj Level 3

                                  The save method has to return something.

                                  I am using Save according to this while the method's signature is different:

                                  <s:itemEditor>
                                      <fx:Component>
                                       <s:DefaultGridItemEditor>
                                           <fx:Script>
                                            <![CDATA[
                                                override public function save():void
                                                {
                                                    data.dataField = myValueConverter(value);
                                                }
                                            ]]>
                                           </fx:Script>
                                       </s:DefaultGridItemEditor>
                                      </fx:Component>
                                  </s:itemEditor> 

                                  from Spark DataGrid Editing - Functional and Design Specification.
                                  • 14. Re: Editable Spark DataGrid
                                    Zolotoj Level 3

                                    Ok, here is my Save method:

                                    override public function save():Boolean
                                            {
                                               data[column.dataField] = value;
                                                return true;
                                            }

                                     

                                    I see that trace(dataProvider) is showing entered data, but the cell loses its text on losing focus.

                                    • 15. Re: Editable Spark DataGrid
                                      Zolotoj Level 3

                                      Ok, here is my column definition which would work if I remove custom item renderer:

                                       

                                      <s:GridColumn dataField="initial" headerText="Initial">
                                                                  <!--<s:itemRenderer>
                                                                      <fx:Component>
                                                                          <s:GridItemRenderer>
                                                                              <s:layout>
                                                                                  <s:VerticalLayout paddingLeft="1"
                                                                                                    verticalAlign="middle"/>
                                                                              </s:layout>
                                                                              <s:TextInput id="txtCarInitial" restrict="a-zA-Z" width="50"/>
                                                                          </s:GridItemRenderer>
                                                                      </fx:Component>   
                                                                  </s:itemRenderer>-->
                                                                  <s:itemEditor>
                                                                      <fx:Component>
                                                                              <local:testEditor width="50"/>
                                                                      </fx:Component>
                                                                  </s:itemEditor>
                                                              </s:GridColumn>

                                       

                                      Do I need a custom renderer? Will a custom editor show my data as well?

                                      • 16. Re: Editable Spark DataGrid
                                        Darrell Loverin Level 4

                                        I modified your GridItemRenderer in a couple of ways:

                                         

                                        1. First, the GridItemRenderer does not know which component to put the data in. So I added a labelDisplay property.

                                         

                                         

                                         

                                                        <s:GridColumn dataField="initial" headerText="Initial">
                                                           <s:itemRenderer>
                                                                <fx:Component>
                                                                    <s:GridItemRenderer labelDisplay="{txtCarInitial}" >
                                                                        <s:layout>
                                                                            <s:VerticalLayout paddingLeft="1"
                                                                            verticalAlign="middle"/>
                                                                        </s:layout>
                                                                        <s:Label id="txtCarInitial" width="50"/>
                                                                    </s:GridItemRenderer>
                                                                </fx:Component>   
                                                            </s:itemRenderer>

                                         

                                        2. The component in the labelDisplay must be of type TextBase so I change the TextInput component to a Label.

                                         

                                         

                                        Hope that helps,

                                         

                                         

                                        -Darrell

                                        • 17. Re: Editable Spark DataGrid
                                          Zolotoj Level 3

                                          I think I am going to have no item renderer at all.

                                          <s:GridColumn dataField="initial" headerText="Initial" width="50">
                                                   <s:itemEditor>
                                                          <fx:Component>
                                                               <local:gridTextItemEditor/>
                                                           </fx:Component>
                                                     </s:itemEditor>
                                          < /s:GridColumn>

                                           

                                          package
                                          {
                                               import flash.events.KeyboardEvent;
                                               
                                               import spark.components.DataGrid;
                                               import spark.components.TextArea;
                                               import spark.components.gridClasses.GridColumn;
                                               import spark.components.gridClasses.IGridItemEditor;
                                               
                                               public class gridTextItemEditor extends TextArea implements IGridItemEditor
                                               {
                                                    private var _column:GridColumn;
                                                    private var _data:Object;
                                                    public function gridTextItemEditor()
                                                    {
                                                         super();
                                                    }
                                                    
                                                    public function get dataGrid():DataGrid
                                                    {
                                                         return null;
                                                    }
                                                    
                                                    public function get column():GridColumn
                                                    {
                                                         return _column;
                                                    }
                                                    
                                                    public function set column(value:GridColumn):void
                                                    {
                                                         _column = value;
                                                    }
                                                    
                                                    public function get columnIndex():int
                                                    {
                                                         return 0;
                                                    }
                                                    
                                                    public function get rowIndex():int
                                                    {
                                                         return 0;
                                                    }
                                                    
                                                    public function set rowIndex(value:int):void
                                                    {
                                                    }
                                                    
                                                    public function prepare():void
                                                    {
                                                         addEventListener("keyDown", onEnter);
                                                         height = DataGrid(owner).rowHeight;
                                                         setStyle("borderVisible", false);
                                                         text = data[column.dataField];
                                                         x += 2;
                                                         y += 2;
                                                         selectRange(0, 0);
                                                    }
                                                    
                                                    public function discard():void
                                                    {
                                                    }
                                                    
                                                    public function save():Boolean
                                                    {
                                                         data[column.dataField] = text;               
                                                         DataGrid(owner).validateNow();
                                                         return true;
                                                    }
                                                    
                                                    public function get data():Object
                                                    {
                                                         return _data;
                                                    }
                                                    
                                                    public function set data(value:Object):void
                                                    {
                                                         _data = value;
                                                    }
                                                    private function onEnter(event:KeyboardEvent):void
                                                    {
                                                         trace(event.keyCode);
                                                         if (event.charCode == 13)
                                                         {     
                                                              event.preventDefault();
                                                         }     
                                                    }     
                                               }
                                          }
                                          

                                          There are a few very, very annoying things are happening. When I select a cell for editing, the whole text is getting highlighted. Additional clicking will not cancel highlighting, so I had to implement selectRange(0, 0);. Why data in the cell has to be selected at all? For easy deletion? By the way, I am using TextArea because selectRange(0, 0) will not work for TextInput. And that creates another problem: pressing Enter with TextInput will stop editing session and move a cursor to the next tab stop, but not with TextArea. After pressing the Enter it will create a new line inside of the control.Unfortunately, my code onEnter does not work because when I press on Enter it's not getting into the event listener. All I am trying to do is to create a robust editable DataGrid with a minimum of code. It looks like the new DataGrid is not meant to be too easy.

                                          • 18. Re: Editable Spark DataGrid
                                            dinko_ivanov

                                            Hello guys,

                                            Today I installed Flex SDK 4.5 and I see that Spark DataGrid control is available there. I cannot find though IGridItemEditor or DefaultGridItemEditor classes. I also get an error when I use the s:itemEditor tag: -Could not resolve <s:itemEditor> to a component implementation.

                                             

                                            Could you help please?

                                             

                                            Kind Regards,

                                            Dinko

                                            • 19. Re: Editable Spark DataGrid
                                              Darrell Loverin Level 4

                                              There are no IGridDataEditor or DefaultGridData classes. I think you mean IGridItemEditor and DefaultGridItemEditor.

                                               

                                              <s:itemEditor> is not a component, it is a property on DataGrid and GridColumn.

                                               

                                              Below is a simple example that shows how to use declare item editors. Declaring <s:DefaultGridItemEditor> in the third column is not necessary since it is the default editor. I just put it in for demonstration purposes.

                                               

                                              <?xml version="1.0" encoding="utf-8"?>

                                               

                                              <!--

                                              This is a simple cell editor to demonstrate how to use cell editors.

                                               

                                              -->

                                              <s:Application

                                                  xmlns:fx="http://ns.adobe.com/mxml/2009"

                                                  xmlns:s="library://ns.adobe.com/flex/spark">

                                                   

                                                  <s:DataGrid id="dataGrid"  left="10" right="10" editable="true">

                                                      <s:columns>

                                                          <s:ArrayList>

                                                              <s:GridColumn dataField="key" headerText="Key" editable="true"/>

                                                              <s:GridColumn dataField="name" headerText="Name" />

                                                              <s:GridColumn dataField="price" headerText="Price">

                                                                  <s:itemEditor>

                                                                      <fx:Component>

                                                                          <s:DefaultGridItemEditor/>                           

                                                                      </fx:Component>

                                                                  </s:itemEditor>

                                                                   

                                                              </s:GridColumn>

                                                              <s:GridColumn dataField="call" headerText="Rating" editable="true">

                                                                  <s:itemEditor>

                                                                      <fx:Component>

                                                                          <s:ComboBoxGridItemEditor>

                                                                              <s:dataProvider>

                                                                                  <s:ArrayList>

                                                                                      <fx:int>1</fx:int>

                                                                                      <fx:int>2</fx:int>

                                                                                      <fx:int>3</fx:int>

                                                                                      <fx:int>4</fx:int>

                                                                                      <fx:int>5</fx:int>

                                                                                  </s:ArrayList>

                                                                              </s:dataProvider>

                                                                          </s:ComboBoxGridItemEditor>

                                                                      </fx:Component>

                                                                  </s:itemEditor>

                                                              </s:GridColumn>

                                                          </s:ArrayList>

                                                      </s:columns>

                                                       

                                                      <s:ArrayCollection>

                                                          <s:DataItem key="1000" name="Abrasive" price="100.11" call="4"/>

                                                          <s:DataItem key="1001" name="Brush" price="110.01" call="3"/>

                                                          <s:DataItem key="1002" name="Clamp" price="120.02" call="4"/>

                                                          <s:DataItem key="1003" name="Drill" price="130.03" call="4"/>

                                                          <s:DataItem key="1004" name="Epoxy" price="140.04" call="5"/>

                                                          <s:DataItem key="1005" name="File" price="150.05" call="1"/>

                                                          <s:DataItem key="1006" name="Gouge" price="160.06" call="2"/>

                                                          <s:DataItem key="1007" name="Hook" price="170.07" call="4"/>

                                                          <s:DataItem key="1008" name="Ink" price="180.08" call="5"/>

                                                          <s:DataItem key="1009" name="Jack" price="190.09" call="4"/>            

                                                      </s:ArrayCollection>

                                                  </s:DataGrid>   

                                                   

                                              </s:Application>

                                               

                                               

                                              -Darrell

                                              • 20. Re: Editable Spark DataGrid
                                                dinko_ivanov Level 1

                                                Hello Darrell,

                                                 

                                                Thanks for the hint!

                                                 

                                                I did what you proposed. Initially I got "Could not resolve <s:ComboBoxGridItemEditor> to a component implementation." error. The problem was that I was using the Flex Hero 4.5 Milestone build from Oct 2010. I installed the latest Flex Hero Build from Thu Feb 3, 2011 and the class is resolved. I had to fix some compilation compatibility problems with some missing skin states (normalWithPrompt and disabledWithPrompt).

                                                 

                                                Then I stuck to a problem that I could not launch the application from within the Flash Builder (I'm using FB 4). I found some usefull info here http://forums.adobe.com/thread/787400. I had to change the <flex sdk location>/frameworks/flex-config.xml to use swfVersion 10 instead of 11: (<swf-version>10</swf-version>). I also installed the latest 2.6 AIR runtime, and changed the NS to <application xmlns="http://ns.adobe.com/air/application/2.5"> in my flex application XML descriptor (2.6 is not officially released, so use 2.5). Finally I had to add an additional <versionNumber>2.5</versionNumber> and now I'm able to start my AIR application with the latest flex SDK build using Flash Builder 4.

                                                 

                                                Thanks again and regards!

                                                 

                                                Dinko