17 Replies Latest reply on Apr 27, 2009 4:38 AM by Cr99

    DataGrid Combobox dataprovider erasing items

    Cr99 Level 1


      I have a DataGrid that is linked to an array of custom data objects which I call a seriesList.  You are supposed to be able to choose the name of each series via a combobox in the datagrid.  It works fine except when the user selects the combobox and then clicks somewhere else in the interface, which closes the combobox and erases whichever item is previously selected!

       


      <!--  Definition in application  -->
      <!--  axis.seriesList is and ArrayCollection of actionscript objects called SeriesObjects which have a var name:String variable -->
      <mx:DataGrid id="seriesTable" color="black" fontSize="9" rowHeight="30" editable="true" resizeEffect="slow" rollOverColor="#CCCCCC"
          selectionColor="#999999" dataProvider="{axis.seriesList}" width="100%"
          rowCount="{axis.seriesList.length > 2 ? axis.seriesList.length : 2}" >
              <mx:columns>  
                   <mx:DataGridColumn dataField="name" headerText="Name" width="280" headerStyleName="centered" id="nameColumn"
                           rendererIsEditor="true"  editorDataField="result" itemRenderer="renderer.SeriesBoxRenderer"/>
              </mx:columns>
      </mx:DataGrid>

       


      <!--  SeriesBoxRenderer -->
      <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()" horizontalAlign="center">
         <mx:Script>
              <![CDATA[
                  import mx.collections.ArrayCollection;
                  // Define a property for returning the new value to the cell.
                  public var result:String="";
                 
                  [Bindable]
                  private var dpValue:ArrayCollection;
                 
                  private function init():void {
                      // list of possible names to choose from for this series
                      dpValue = mx.core.Application.application.seriesArray;
                  }
             
                  // Override the set method for the data property.
                  override public function set data(value:Object):void {
                      if (dpValue == null) init();
                      super.data = value;
                      if (value != null)     {
                          var currentValue:String = value.name;
                          var len:int = dpValue.length;
                          for (var i:int = 0; i < len; i++) {
                              if (dpValue[i].name == currentValue) {
                                  editor.selectedIndex = i;
                                  return;
                              }
                          }
                      }
                      editor.selectedIndex = 0;            }
                 
                  public function onChange():void {
                      var index:int = editor.selectedIndex;
                      result = dpValue[index].name;
                      data.name = dpValue[index].name;
                  }   
                       
              ]]>
          </mx:Script>
           <mx:ComboBox id="editor" textAlign="left" labelField="name" dataProvider="{dpValue}"  change="onChange()"/>
      </mx:VBox>

        • 1. Re: DataGrid Combobox dataprovider erasing items
          Flex harUI Adobe Employee

          It doesn't look like your onChange updates the result property

           

          Alex Harui

          Flex SDK Developer

          Adobe Systems Inc.

          Blog: http://blogs.adobe.com/aharui

          • 2. Re: DataGrid Combobox dataprovider erasing items
            Cr99 Level 1

            Thanks for the reply.  Does onChange even get called when the user clicks outside the combobox?  When I run it with trace statements, it never seems to get called.  But even if it does get called, why does

             

            result = dpValue[index].name

             

            not update properly?

            • 3. Re: DataGrid Combobox dataprovider erasing items
              Flex harUI Adobe Employee

              onChange will not get called when someone clicks on a cell, does not change the value and clicks away.  The result property must always reflect data.name

               

              Alex Harui

              Flex SDK Developer

              Adobe Systems Inc.

              Blog: http://blogs.adobe.com/aharui

              • 4. Re: DataGrid Combobox dataprovider erasing items
                Cr99 Level 1

                So I'm still wondering why not clicking on anything erases the item from the combobox.  Since onChange doesn't even get called, I don't think that's the issue.  It doesn't actually delete the item from the combobox by the way, it just sets the string to "" in other words it's blank.  There are still 7 or 8 or how ever many items there, just one blank one.  And if I do it again, I can eventually make the entire combobox blank this way.

                • 5. Re: DataGrid Combobox dataprovider erasing items
                  Gregory Lafrance Level 6

                  The onChange() method has nothing to do with the problem.

                   

                  If you remove  

                   

                  super.data = value;

                   

                  from your code, the problem goes away, though I don't know if you still have the desired functionality.

                  • 6. Re: DataGrid Combobox dataprovider erasing items
                    Cr99 Level 1

                    Yeah, removing super.data = value does fix the problem, but then the values never update at all for the underlying ActionScript object.  Data.name never gets changed.  I just wish I could figure out where the erasing happens.  I put in some break points, but I can never find out where it is getting erased.

                    • 7. Re: DataGrid Combobox dataprovider erasing items
                      Flex harUI Adobe Employee

                      The erasing probably happens in DataGrid's itemEditorItemEditEndHandler

                       

                      Alex Harui

                      Flex SDK Developer

                      Adobe Systems Inc.

                      Blog: http://blogs.adobe.com/aharui

                      • 8. Re: DataGrid Combobox dataprovider erasing items
                        Flex harUI Adobe Employee

                        Let me try to explain one more time:  When you don't click on anything and click on a new cell, the DG will dispatch an ITEM_EDIT_END.  The default handler reads the editorDataField property which is "result" which is set to "" because you haven't kept it in sync with the data.name, and stores "" in the data object's name property.

                         

                        Alex Harui

                        Flex SDK Developer

                        Adobe Systems Inc.

                        Blog: http://blogs.adobe.com/aharui

                        • 9. Re: DataGrid Combobox dataprovider erasing items
                          ntsiii Level 3

                          Typically, when you use a ComboBox as an item renderer, you want the combo's selected value to reflect the current value in its backing property.

                           

                          So i think you problem will be fixed, plus give a better user experience, if you have the renderer set the selectedIndex of the ComboBox.  this way, when the change handler gets called for anyreason and sets the backing value, it will have the correct value, instead of the empty string.

                          • 10. Re: DataGrid Combobox dataprovider erasing items
                            Cr99 Level 1

                            I'm not sure I follow what you're saying.  I thought I was doing this already with

                             

                            editor.selectedIndex = i;

                             

                            in the override public function set data method.

                             

                            As I said before, the code works as long as you actually select something from the combobox.  It's just that when you don't pick anything and click outside the combobox, it closes and writes and empty string into the dataprovider.  When I run the debugger, I can see that every other field in the series object which gets passed to the set data method is correct in this case except the name, which is blank.  And how it overwrites the combobox dataprovider is a further mystery.

                             

                            Perhaps you could be more specific and reference the functions or code which needs to be changed/added/removed from what I currently have?  Thanks.

                            • 11. Re: DataGrid Combobox dataprovider erasing items
                              Cr99 Level 1

                              I'm thinking the problem may be the dataprovider for the combobox.  This array is also shared with another List component in another tab on the interface.  The reason I am thinking this is because I have another item renderer which uses a combobox and does not erase itself when you click nothing.  Here is the code for that item, and the only difference I can see between this code and the code that doesn't work is the fact that the dataprovider is shared with another part of the code.  Still not sure how to fix this, however.

                               

                                        [Bindable]
                                          private var dpValue:ArrayCollection;
                                         
                                          private function init():void {
                                              dpValue = mx.core.Application.application.aquisitionOptions.lastResult.system.data;

                                              for ( var i:int=0; i<dpValue.length; i++ )  {  //loop over the items in the dataProvider
                                                 if (dpValue[i].id == data.aquisitionID)  {  //compare desired value to current item.data value
                                                      editor.selectedIndex = i;  //set the seletedIndex of the combo box
                                                      data.aquisitionDescr = dpValue[i].name;
                                                      break;
                                                 }
                                              }
                                          }

                               

                                        // Override the set method for the data property.
                                          override public function set data(value:Object):void {
                                              super.data = value;

                                              if (dpValue == null) init();

                                              if (value != null)     {        
                                                  var currentValue:String = value.aquisitionDescr;
                                                  trace ("\n current:  ", currentValue);
                                                  var len:int = dpValue.length;
                                                  for (var i:int = 0; i < len; i++) {
                                                      if (dpValue[i].name == currentValue) {
                                                          editor.selectedIndex = i;
                                                          return;
                                                      }
                                                  }
                                              }
                                              editor.selectedIndex = 0;
                                          }
                                         
                                          public function onChange():void {

                                              var index:int = editor.selectedIndex;
                                              result = dpValue[index].name;
                                              data.aquisitionDescr = dpValue[index].name;
                                              data.aquisitionID = editor.selectedItem.id as String;
                                          }  
                                                
                                      ]]>
                                  </mx:Script>
                                   <mx:ComboBox id="editor" labelField="name" dataProvider="{dpValue}" change="onChange()"/>

                               

                              <!-- definition in the datagrid -->

                              <mx:DataGridColumn dataField="aquisitionDescr" headerText="Data Aquisition" width="160" headerStyleName="centered" id="acquisitionColumn"
                                                   rendererIsEditor="true"  editorDataField="result" itemRenderer="renderer.AquisitionBoxRenderer"/>

                              • 12. Re: DataGrid Combobox dataprovider erasing items
                                ntsiii Level 3

                                Yes, sorry, I missed that.

                                 

                                I'll go back through your code to see if I can see anything else.

                                • 13. Re: DataGrid Combobox dataprovider erasing items
                                  ntsiii Level 3

                                  Perhaps there is some interaction between what your renderer is doing and what is happening in DGs own item editing process.

                                   

                                  Normally one would handle updating the dataProvider in the renderer itself as you are doing, or use the built in editing functionality, but not both.

                                   

                                  If yu remove the rendererIseditor="true" from tha column, does it change this behavior?

                                  Tracy

                                  • 14. Re: DataGrid Combobox dataprovider erasing items
                                    Cr99 Level 1

                                    Somehow I didn't see your post about setting result until just now.  That does seem to aleviate part of the problem, but it still does not fix it.  If I add the line:

                                     

                                    result = data.name;

                                     

                                    to the init method so that result gets a value on startup, then it does indeed cease to erase the name on a click outside the combobox.  However, now my selections of other items in the combobox cause the initial value for data.name to be overwritten with the new selection!

                                     

                                    One more thing that I did notice which may be a factor.  In the series object which is what makes up the serieslist for the datagrid, there is a default value for aquisitionDescr (the code that works) but none for name:


                                        public String name;
                                        public String aquisitionDescr="*DEFAULT";

                                     

                                    But this still doesn't explain why the combobox dataprovider for the series keeps getting overwritten.  It's so bizarre.

                                    • 15. Re: DataGrid Combobox dataprovider erasing items
                                      Cr99 Level 1

                                      changing renderIsEditor to false causes it to crash.

                                      • 16. Re: DataGrid Combobox dataprovider erasing items
                                        Flex harUI Adobe Employee

                                        I'm not sure I understand the remaining problem.  Can you explain again?

                                         

                                        Alex Harui

                                        Flex SDK Developer

                                        Adobe Systems Inc.

                                        Blog: http://blogs.adobe.com/aharui

                                        • 17. Re: DataGrid Combobox dataprovider erasing items
                                          Cr99 Level 1

                                          Thanks for all the helpful replies.  This was a very hard bug to track, but in the end I think the fault was in how I was setting up the dataproviders for the datagrid and the combobox.

                                           

                                          The problem is that all of the other renderers I was using for each column in the datagrid used a seperate array for their dataprovider.  For instance, one column allowed the user to pick what style they wanted for the series.  This list was generated at runtime from the database and placed into it's own array.  However the array for the problematic series renderer was a list of all the current series names.  To acces this, I simply used the same series list array as I was using for the entire Datagrid and accessed the .name field.  So somehow when it was trying to update this element, it was getting it's wires crossed with the combobox.  I'm not sure if that makes sense, but I think it would take me a long time to explain the details and that captures the gist of it.  To solve the problem, I simply had to copy the series List into a seperate array and use that for the data provider for this renderer.  Again, thanks for all the help!