3 Replies Latest reply on Aug 23, 2010 9:46 AM by bon_t

    How to add ComboBox to dynamically created DataGridColumn

    bon_t

      I can create my datagrid in mxml code with no issues. There are six columns, but I'm showing the code only for the column in question (the one with the ComboBox):
      [Code]
      <mx:DataGrid x="82" y="189" width="100%" height="100%" editable="true" id="samplesDataGrid" dataProvider="{samplesData}">
          <mx:columns>
              <mx:DataGridColumn headerText="Tag" dataField="sem_tag" width="200" rendererIsEditor="true">
                  <mx:itemRenderer>
                      <fx:Component>
                          <mx:ComboBox width="190" prompt="{data.sem_tag}" dataProvider="{outerDocument.tagsAsStringsList}"/>
                      </fx:Component>
                  </mx:itemRenderer>
              </mx:DataGridColumn>
          </mx:columns>
      </mx:DataGrid>
      [/Code]

       

      The dataProvider for the datagrid, samplesData, is an ArrayCollection populated by a method in the java backend that loads data from a file of samples. Each sample has a tag value.
      The dataProvider for the ComboBox, tagsAsStringsList, is an ArrayCollection populated by a method in the java backend that loads data from a file of tags.
      The ComboBox's prompt value is set to the tag value from the samplesData.

       

      Now I need to create the DataGridColumns dynamically.
      I have the following code (without adding the ComboBox to the column) which works:
      [Code]
      public var columns:Array = ["index", "sem_tag", "count", "fake", "raw_transcription", "path"];

       

      private function addDataGridColumn(dataField:String):void
      {
          var dgc:DataGridColumn = new DataGridColumn(dataField);
          var cols:Array = samplesDataGrid.columns;
          cols.push(dgc);
          if ( dataField == "sem_tag" )
          {
              dgc.headerText = "Tag"; dgc.width = 200;
          }
          samplesDataGrid.columns = cols;
      }
      [/Code]

       

      I've tried two ways to add the ComboBox with no luck.

       

      ATTEMPT #1
      I created a tagComboBox.as file:
      [Code]
      package components
      {
          import mx.controls.ComboBox;

       

          public class tagComboBox extends ComboBox
          {
              public function tagComboBox()
              {
                  super();
                  width=190;
                  prompt=data.sem_tag;dataProvider=outerDocument.tag  sAsStringsList;
              }
          }
      }
      [/Code]

       

      The setting of the dataProvider gives me an error:
      Access to undefined property outerDocument

       

      I removed the dataProvider setting and added the following settings (in bold) in the addDataGridColumn method:
      [Code]
      if ( dataField == "sem_tag" )
      {
           dgc.headerText = "Tag"; dgc.width = 200; dgc.rendererIsEditor = true; dgc.itemRenderer = components.tagComboBox;
      }
      [/Code]

       

      When I run my application, I get the error:
      TypeError: Error #1009: Cannot access a property or method of a null object reference.
      caused by my prompt=data.sem_tag setting in the tagComboBox.as file.

       

      [u]ATTEMPT #2[/u]
      I created the comboBox in the addDataGridColum method:
      [Code]
      if ( dataField == "sem_tag" )
      {
          var tagComboBox:mx.controls.ComboBox = new mx.controls.ComboBox();
          tagComboBox.dataProvider = tagsAsStringsList;
          dgc.headerText = "Tag"; dgc.width = 200; dgc.rendererIsEditor = true; dgc.itemRenderer = tagComboBox;
      }
      [/Code]

       

      The setting of the itemRenderer gives me the following error:
      Implicit coercion of a value of type mx.controls:ComboBox to an unrelated type mx.core:IFactory

       

      I can’t even set
      tagComboBox.prompt = samplesData.sem_tag
      I get this error:
      Access of possibly undefined property sem_tag through a reference with static type mx.collections:ArrayCollection.

       

      Thanks in advance for your help!

        • 1. Re: How to add ComboBox to dynamically created DataGridColumn
          betheflexcoder Level 2

          Your second way of adding the item renderer dynamically should work if it is done using the

          ClassFactory. The flex item renderer can be added dynamically using the ClassFactory, so that you will

          not get the Implicit coecion error for IFactory.

           

          Below is a link for reference.

           

          http://cookbooks.adobe.com/post_Change_Flex_itemRenderer_at_runtime-9063.html

          • 2. Re: How to add ComboBox to dynamically created DataGridColumn
            Vackar Level 2

            To demonstrate the principle of how to wire it up try this:

             

            if ( dataField == "sem_tag" )
            {
                dgc.headerText = "Tag";
                dgc.width = 200;
                dgc.rendererIsEditor = true;
                dgc.itemRenderer = ClassFactory(mx.controls.ComboBox);
            }
            
            

             

             

                public class tagComboBox extends ComboBox
                {
                    public function tagComboBox()
                    {
                        super();
                        width=190;
                        prompt='Pick One';
                        dataProvider=Application.application.tagsAsStringsList;
                    }
                }
            

             

            Make  sure that tagsAsStringsList is public.

             

            To pre-select a value use the

            this.data 

            property to access the current 'row' of data, and then dow some logic to select the correct item from tagsAsStringsList

             

            Hope this helps,

            Vackar

            • 3. Re: How to add ComboBox to dynamically created DataGridColumn
              bon_t Level 1

              Thanks to those who quickly replied.  I solved my issue last Friday as follows:

               

              [Code]

              var cf_tagComboBox:ClassFactory = new ClassFactory(mx.controls.ComboBox);

               

              if ( dataField == "sem_tag" )
              {
                 dgc.headerText = "Tag"; dgc.width = 200; dgc.rendererIsEditor = true; dgc.itemRenderer = cf_tagComboBox;
              }

               

              // When the dataProvider for the combo box gets populated.

              protected function loadTagsAsStringsArray( event:ResultEvent ):void
              {
                 tagsAsStringsList = loadTagsAsStringsResult.lastResult as ArrayCollection;
                 cf_tagComboBox.properties = { width:190, dataProvider:tagsAsStringsList };
              }

              [/Code]