9 Replies Latest reply on Aug 26, 2010 3:29 PM by Devtron

    How to fix a DataGrid headercolumn's headerText causing sizing problems

    Devtron Level 3

      Hello,

       

      I have a datagrid with filter textboxes underneath the header columns.

       

      My problem is that some of the headerText is rather large (in 2 of my columns), and causes it to wrap and stretch the header's height, which ultimately causes the columns to match up strangely and not in uniform.

       

      Here is a screenshot of the problem:
      http://img685.imageshack.us/img685/2283/gridcolumnsizeproblem.png

       

      How can I make all column headings uniform in size, with my filtering text boxes? I do not see a height property. I have tried to add extra spaces in the smaller column headings but that does nothing as I think FLEX parses that out. Can I specifically size these so they match the longer ones?

       

      Keep in mind, this DataGrid uses a custom renderer.

       

      Here is my grid definition/MXML:
                  <dataGridFilters:FilterDatagrid id="dg" width="100%" height="100%" rowCount="5" dataProvider="{deviceDataColl}" click="dg_clickHandler(event)" >
                      <dataGridFilters:columns>
                          <dataGridFilters:DataGridFilterColumn dataField="name" headerText="Name" width="150"/>
                          <!--<dataGridFilters:DataGridFilterColumn dataField="deviceType" headerText="Device Type" textAlign="right"/>-->
                          <dataGridFilters:DataGridFilterColumn dataField="tHeat"   headerText="Heat Point" width="75" textAlign="right"/>
                          <dataGridFilters:DataGridFilterColumn dataField="tCool" headerText="Cool Point" width="75" textAlign="right"/>
                          <dataGridFilters:DataGridFilterColumn dataField="tIndoor" headerText="Indoor Temp" width="80" textAlign="right"/>
                          <dataGridFilters:DataGridFilterColumn dataField="tOutdoor" headerText="Outdoor Temp" width="90" textAlign="right"/>
                          <dataGridFilters:DataGridFilterColumn dataField="insideHumidity" headerText="Indoor Humidity" width="100"  textAlign="right"/>
                          <dataGridFilters:DataGridFilterColumn dataField="currentFState" headerText="Fan State" width="75" textAlign="right"/>
                          <dataGridFilters:DataGridFilterColumn dataField="currentFMode" headerText="Fan Mode"  width="75" textAlign="right"/>
                          <dataGridFilters:DataGridFilterColumn dataField="currentTState" headerText="State" width="75" textAlign="right"/>
                          <dataGridFilters:DataGridFilterColumn dataField="currentTMode" headerText="Mode" width="75" textAlign="right"/>
                          <dataGridFilters:DataGridFilterColumn dataField="nextSchedCPTDate" headerWordWrap="false" headerText="Next Scheduled Control Point Transition Date" width="100" textAlign="right"/>
                          <!--<dataGridFilters:DataGridFilterColumn dataField="nextSchedCPTTime" headerText="Next Scheduled Control Point Transition Time" width="100" textAlign="right"/>-->
                          <dataGridFilters:DataGridFilterColumn dataField="nextSchedCPTTemp" headerWordWrap="false" headerText="Next Scheduled Control Point Transition Temp" width="100" textAlign="right"/>
                          <dataGridFilters:DataGridFilterColumn dataField="groupOne" headerText="Group 1" width="75" textAlign="right"/>
                          <dataGridFilters:DataGridFilterColumn dataField="groupTwo" headerText="Group 2" width="75" textAlign="right"/>                   
                      </dataGridFilters:columns>
                  </dataGridFilters:FilterDatagrid>

       

       

       

      Any help is greatly appreciated!

       

      Thank you,
      Devtron

        • 1. Re: How to fix a DataGrid headercolumn's headerText causing sizing problems
          rootsounds Level 4

          The code that you've provide probably isn't relevent. I'm more interested in your headerRenderer which is where the problem is found. Try to set the height of the headerRenderer container to 100% and place a Spacer before the Text field with height="100%".

          • 2. Re: How to fix a DataGrid headercolumn's headerText causing sizing problems
            Phoenix_Guru Level 1

            The datagrids do have a property to set the header height. Look for the

            headerHeight Property. Set it to max value

            you are expecting.


            • 3. Re: How to fix a DataGrid headercolumn's headerText causing sizing problems
              Devtron Level 3

              Rootsounds,

               

              Here is my headerRenderer class:

               

              package filters.header
              {
                  import mx.controls.dataGridClasses.DataGridHeader;
                 
                  import mx.core.mx_internal;
                 
                  use namespace mx_internal;
                  public class DataGridFilterHeader extends DataGridHeader
                  {
                      public function DataGridFilterHeader()
                      {
                          super();
                      }
                     
                     
                      /**
                       *re-position the sort icon
                       *
                       */       
                      override protected function placeSortArrow():void
                      {
                          super.placeSortArrow();
                          if(sortArrow)
                          {
                              var hh:Number = cachedHeaderHeight;
                              sortArrow.y = (hh - sortArrow.measuredHeight - 8) > 0 ? 10: 0;
                              if(sortArrow.visible)
                              {
                                  var n:int = headerItems.length;
                                  for (var i:int = 0; i < n; i++)
                                  {
                                      if(visibleColumns[i].colNum == dataGrid.sortIndex)
                                      {
                                          headerItems[i].setActualSize(visibleColumns[i].width - sortArrow.measuredWidth + 5, headerItems[i].height);
                                      }
                                  }
                               }
                          }
                      }
                  }
              }

               

               

               

               

               

               

               

               

              Here is my dataGrid extender:

               

              package filters
              {
                 
                 
                  import filters.header.DataGridFilterHeader;
                 
                  import flash.events.Event;
                 
                  import mx.collections.ICollectionView;
                  import mx.controls.DataGrid;
                  import mx.controls.dataGridClasses.DataGridColumn;
                  import mx.core.mx_internal;
                 
                  use namespace mx_internal;
                 
                  public class FilterDatagrid extends DataGrid
                  {
                      public function FilterDatagrid()
                      {
                          super();
                          headerClass = DataGridFilterHeader;
                          addEventListener("filterEvent",onFilterChange);
                      }
                     
                      override public function set dataProvider(value:Object):void
                      {
                          if(dataProvider)
                              resetFiltres();
                          super.dataProvider = value;
                          resetFiltres(filterFunction);
                      }
                     
                     
                      private function  onFilterChange(event:Event):void
                      {
                          if(dataProvider)
                              (dataProvider as ICollectionView).refresh();
                          selectedIndex = 0;
                      }
                     
                      private function resetFiltres(inFilterFunction:Function = null):void
                      {
                          if(dataProvider)
                          {
                              (dataProvider as ICollectionView).filterFunction = inFilterFunction;
                              (dataProvider as ICollectionView).refresh();
                          }
                          if(inFilterFunction == null)
                          {
                              var iLen:int= columnCount;
                              for(var i:int=0;i<iLen;i++)
                              {
                                  var dgc:DataGridColumn = columns[i] as DataGridColumn;
                                  if(dgc is DataGridFilterColumn)
                                  {
                                      DataGridFilterColumn(dgc).filterText = "";
                                  }   
                              }
                            }
                          selectedIndex = 0;
                      }
                     
                      private function filterFunction(inObject:Object):Boolean
                      {
                          var iLen:int= columnCount;
                          for(var i:int=0;i<iLen;i++)
                          {
                              var dgc:DataGridColumn = columns[i] as DataGridColumn;
                              var dField:String = dgc.dataField;
                              if(dgc is DataGridFilterColumn == false)
                                  continue;
                              var srchStr:String =  DataGridFilterColumn(dgc).filterText;
                              if(srchStr == "")
                                  continue;
                              var dataStr:String = dgc.itemToLabel(inObject);
                              var regex:RegExp = new RegExp("^"+srchStr, "i");
                              // if search string exists and
                              // does not match the data in the row
                              if(regex.exec(dataStr)==null)
                              {
                                  return false;
                              }
                          }
                          return true;
                      }
                     
                  }
              }

               

               

               

               

               

               

              If all this wrapper class stuff "Extends" the DataGrid, why wouldnt "headerHeight" be available as an attribute in my MXML/grid? When I try to set it explicitly in my dataGrid MXML, the compiler says "Cannot resolve attribute 'headerHeight'". I guess this doesnt really "extend" it? Im confused.

              • 4. Re: How to fix a DataGrid headercolumn's headerText causing sizing problems
                =VA=FyreHeart Level 2

                You have to set headerHeight on the <mx:DataGrid> tag itself, not one of the columns. You can't specify a different height for each column - it applies to all of them.

                1 person found this helpful
                • 5. Re: How to fix a DataGrid headercolumn's headerText causing sizing problems
                  Devtron Level 3

                  ^ wow thank you, that was dumb of me. I did set the headerHeight in the grid, but I still have the same problem with my textInput/filtering being out of uniform with the rest.

                   

                   

                  Here is my TextInputRenderer code:

                   

                  package filters.renderers
                  {
                      import filters.DataGridFilterColumn;
                     
                      import flash.events.Event;
                      import flash.events.MouseEvent;
                     
                      import mx.binding.utils.BindingUtils;
                      import mx.containers.VBox;
                      import mx.controls.DataGrid;
                      import mx.controls.Text;
                      import mx.controls.TextInput;
                      import mx.controls.listClasses.BaseListData;
                      import mx.controls.listClasses.IDropInListItemRenderer;
                      import mx.core.ScrollPolicy;
                      import mx.utils.StringUtil;

                   

                      public class TextInputRenderer extends VBox implements IDropInListItemRenderer
                      {
                          private var _listData:BaseListData;
                         
                          [Bindable]private var filterComp:TextInput;
                         
                          private var headerText:Text;
                         
                          private var _data:DataGridFilterColumn;
                         
                          public function TextInputRenderer()
                          {
                              super();
                              horizontalScrollPolicy = ScrollPolicy.OFF;
                              verticalScrollPolicy = ScrollPolicy.OFF;
                              super.setStyle("verticalGap", "1");
                              super.setStyle("horizontalAlign","center");
                          }
                         
                          override public function set width(value:Number):void
                          {
                              super.width = value;
                          }
                         
                          override public function set percentWidth(value:Number):void
                          {
                              super.percentWidth = value;
                          }
                         
                         
                          override protected function createChildren():void
                          {
                              super.createChildren();
                              if(!headerText)
                              {
                                  headerText = new Text;
                                  headerText.percentWidth = 100;
                                  headerText.setStyle("textAlign", "center");
                                  headerText.setStyle("verticalAlign", "middle");
                                  headerText.selectable = false;       
                                  addChild(headerText);
                              }
                              if(!filterComp)
                              {
                                  filterComp = new TextInput();
                                  filterComp.percentWidth = 99.5;
                                  filterComp.addEventListener(Event.CHANGE,onFilterChange);
                                  addEventListener(MouseEvent.MOUSE_UP,onClickHandler);
                                  addChild(filterComp);
                              }
                          }
                         
                          private function onClickHandler(event:MouseEvent):void
                          {
                              if(event.target.parent == filterComp)
                              {
                                  event.stopImmediatePropagation();
                              }
                          }
                         
                          private function onFilterChange(event:Event):void
                          {
                              _data.filterText = StringUtil.trim(filterComp.text);
                              DataGrid(listData.owner).dispatchEvent(new Event("filterEvent"));
                          }
                         
                          //--------------------------------------------------------------------------
                          //
                          //  Properties
                          //
                          //--------------------------------------------------------------------------

                   

                          //----------------------------------
                          //  listData
                          //----------------------------------

                   

                          /**
                           *  Implements the <code>listData</code> property
                           *  using setter and getter methods.
                           */
                          public function get listData():BaseListData
                          {
                              return _listData;
                          }

                   

                          /**
                           *  @private
                           */
                          public function set listData(value:BaseListData):void
                          {
                              _listData = value;
                          }
                         
                          override public function set data(value:Object):void
                          {
                              _data = value as DataGridFilterColumn;
                              headerText.text = _data.headerText;
                              BindingUtils.bindProperty(filterComp,"text",_data,"filterText");
                          }
                         
                          override public function get data():Object
                          {
                              return _data;
                          }

                   

                      }
                  }

                   

                   

                   

                   

                  I believe in the constructor I need to setStyles or change them. I have no idea. Whare all the the styles I can use with setStyles? I cant find that in Adobe's documentation

                  • 6. Re: How to fix a DataGrid headercolumn's headerText causing sizing problems
                    rootsounds Level 4

                    Your headerRenderer would be a lot easier if you used MXML, which would be perfectly acceptable since it's almost all a matter of layout for a view element. Code-behind that if there is more than a small amount of view logic.

                     

                    As I said earlier, a Spacer should do the trick.

                    • 7. Re: How to fix a DataGrid headercolumn's headerText causing sizing problems
                      =VA=FyreHeart Level 2

                      There are a handful of options:

                      1. I'm guessing you don't want to do this, but you could truncate the header string to no more than X characters
                      2. You can set headerWordWrap to false in the DataGrid tag, which would cause overruns and/or truncating.
                      3. You can dynamically change the width of your text input field based on the width of the column (creationComplete event). This is the kind of thing I've done in the past.
                      4. You can dynamically set your headerHeight to the largest value based on the length of the longest string.
                      5. You could dynamically shrink the font size for extra-long header labels.

                       

                      I don't know if there's a "perfect" solution for this situation.

                      1 person found this helpful
                      • 8. Re: How to fix a DataGrid headercolumn's headerText causing sizing problems
                        Devtron Level 3

                        Rootsounds,

                         

                        Where would the spacer go? Would I need to write the renderer as MXML to change the layout??

                         

                         

                         

                        FyreHeart,

                         

                        Those are good options. The requirement (which just changed) for this dataGrid is that the column headers should all be the same height (a fixed height). The text should always be centered, both vertically and horizontally.

                         

                        There is nothing dynamic about my column headers (praise jeebus!).

                         

                        Now, if I set the headerHeight to, say, "100", it works but it does not reposition my textinput control.

                         

                        here is a screenshot of the current problem, with headerHeight="100":
                        http://img843.imageshack.us/img843/2283/gridcolumnsizeproblem.png

                         

                         

                         

                        My first guess is the constructor for the TextInputRenderer:

                         

                                 super.setStyle("verticalGap", "1");
                                 super.setStyle("horizontalAlign","center");

                         


                        ^ I am guessing this positions it? I am unsure what other "setStyle" attributes there are for me to use....

                        • 9. Re: How to fix a DataGrid headercolumn's headerText causing sizing problems
                          Devtron Level 3

                          I ended up solving this problem by hacking it, using the newline character:

                           

                          &#13;

                           

                           

                          not what I was hoping for, but for the meantime, this works for me the best and is easiest to implement.

                           

                          oh, and I ended up setting header height to 85.

                           

                           

                           

                                      <dataGridFilters:FilterDatagrid headerHeight="85" id="dg" draggableColumns="false" sortableColumns="false" width="100%" height="100%" rowCount="5" dataProvider="{deviceDataColl}" click="dg_clickHandler(event)" borderStyle="solid" resizableColumns="false" editable="false" >
                                          <dataGridFilters:columns>
                                             
                                              <dataGridFilters:DataGridFilterColumn dataField="groupOne" headerText="&#13;Group 1&#13;&#13;" width="75" textAlign="center"/>
                                              <dataGridFilters:DataGridFilterColumn dataField="groupTwo" headerText="&#13;Group 2&#13;&#13;" width="75" textAlign="center"/>                   
                                              <dataGridFilters:DataGridFilterColumn dataField="name" headerText="&#13;Name&#13;&#13;" width="150" textAlign="center"/>
                                              <dataGridFilters:DataGridFilterColumn dataField="tHeat"   headerText="&#13;Heat Point&#13;&#13;" width="75" textAlign="center"/>
                                              <dataGridFilters:DataGridFilterColumn dataField="tCool" headerText="&#13;Cool Point&#13;&#13;" width="75" textAlign="center"/>
                                              <dataGridFilters:DataGridFilterColumn dataField="tIndoor" headerText="&#13;Indoor Temp&#13;&#13;" width="80" textAlign="center"/>
                                              <dataGridFilters:DataGridFilterColumn dataField="tOutdoor" headerText="&#13;Outdoor Temp&#13;&#13;" width="90" textAlign="center"/>
                                              <dataGridFilters:DataGridFilterColumn dataField="insideHumidity" headerText="&#13;Indoor Humidity&#13;&#13;" width="100"  textAlign="center"/>
                                              <dataGridFilters:DataGridFilterColumn dataField="currentFState" headerText="&#13;Fan State&#13;&#13;" width="75" textAlign="center"/>
                                              <dataGridFilters:DataGridFilterColumn dataField="currentFMode" headerText="&#13;Fan Mode&#13;&#13;"  width="75" textAlign="center"/>
                                              <dataGridFilters:DataGridFilterColumn dataField="currentTState" headerText="&#13;Thermostat State&#13;&#13;" width="75" textAlign="center"/>
                                              <dataGridFilters:DataGridFilterColumn dataField="currentTMode" headerText="&#13;Thermostat Mode&#13;&#13;" width="75" textAlign="center"/>
                                              <dataGridFilters:DataGridFilterColumn dataField="nextSchedCPTDate" headerWordWrap="false" headerText="&#13;Next Scheduled Control Point Transition Date&#13;" width="100" textAlign="center"/>
                                              <dataGridFilters:DataGridFilterColumn dataField="nextSchedCPTTemp" headerWordWrap="false" headerText="&#13;Next Scheduled Control Point Transition Temp&#13;" width="100" textAlign="center"/>
                                             
                                          </dataGridFilters:columns>
                                      </dataGridFilters:FilterDatagrid>