14 Replies Latest reply on Apr 22, 2011 1:22 PM by Flex harUI

    labelfunction in a datagrid

    BosDog Level 1

      maybe someone can help me out with this... i am able to get a labelfunction to work fine (it sums the totals of the dataprovider) like so:

       

      in my datagridcolumn with id = "grid1" i have labelFunction="sumFunction"

       

      my sumFunction looks like this:


              public function sumFunction(col:DataGridColumn):String
              {
                  var n:int = grid1.dataProvider.length;
                  var sum:Number = 0;
                  for (var i:int = 0; i < n; i++)
                  {
                      sum += grid1.dataProvider[i][col.dataField];
                  }
                  return parentApplication.currencyFormatter.format(sum);//.toFixed(2);
              }

       

      but i find i need to create a sumFunction for every datagrid with a different ID and i'm going to have many. i want to be able to reuse code (best practice) and reuse the same function for all grids. the problem is i dont know which grid to loop over the dataprovider for and return the result to. so i started doing something like this:


              public function sumFunction(dgName:String,col:DataGridColumn):String
              {
                  var n:int = this[dgName]dataProvider.length;
                  var sum:Number = 0;
                  for (var i:int = 0; i < n; i++)
                  {
                      sum += int(this[dgName]dataProvider[i][col.dataField]);
                  }
                  return parentApplication.currencyFormatter.format(sum);
              }

       

      but then my labelfunction needs another argument/parameter passed to it. oddly enough why doesn't the labelFunction work without passing in the col:DataGridColumn in the first example but now it doesnt once i add another argument/parameter to the function?

       

      i was expecting this to then work if i changed the labelfunction on each datagrid to pass the id of the datagrid to let the sumFunction know which one to use:

      labelFunction="sumFunction('grid2')"

       

      this throws an error that i need another argument/parameter but i dont know what to pass in. i'm also getting errors about a string... anyone know how i can accomplish this?

        • 1. Re: labelfunction in a datagrid
          EvyatarBH Level 3

          I would look for the DataGridColumn parent (maybe automationParent), which should be the relevant DataGrid...

          • 2. Re: labelfunction in a datagrid
            Flex harUI Adobe Employee

            The column should have an owner property.

             

            You can also subclass DataGridColumn.

            • 3. Re: labelfunction in a datagrid
              BosDog Level 1

              i'm getting an error when i try to reference the owner of col in the example code above:

               

              i want to access col.owner.id how can i do that? the error i get is "Access of undefined property owner through a reference with static type mx.controls.dataGridClasses:DataGridColumn

               

              in flex debugging i can see the values and i can see col has an inherited owner and id is the name of the id of my datagrid i want to use.

              • 4. Re: labelfunction in a datagrid
                BosDog Level 1

                also when i tried to subclass datagrid like this:

                 

                var a:Object = DataGridColumn(col);

                 

                i still cannot access a.owner as i get a run-time error of "Property owner not found on com.packages.FooterDataGridColumn" so how can i access owner?

                • 5. Re: labelfunction in a datagrid
                  BosDog Level 1

                  Flex harUI i think the problem is my owner property is protected. in flex debugging it shows a yellow diamond next to it... how can i access this and make it unprotected (if that is indeed the problem)?

                   

                  i believe i am actuallly using your footerdatagrid code (this is the .AS packages you created that extend the datagridcolumn to show totals at the bottom of a datagrid)

                  • 6. Re: labelfunction in a datagrid
                    Flex harUI Adobe Employee

                    I think you should subclass DataGridColumn.

                    • 7. Re: labelfunction in a datagrid
                      BosDog Level 1

                      i've tried to do that... would this code subclass datagridcolumn? if not how do i do that?

                       

                      var a:Object = DataGridColumn(col);

                      • 8. Re: labelfunction in a datagrid
                        Flex harUI Adobe Employee

                        Subclassing is not the same as casting or coercion.

                         

                        There are a few examples of subclassed DataGridColumns on my blog.  I

                        believe they are in the two oldest item renderer posts.

                         

                        --

                        Alex Harui

                        Flex SDK Team

                        Adobe System, Inc.

                        http://blogs.adobe.com/aharui

                        • 9. Re: labelfunction in a datagrid
                          BosDog Level 1

                          i think i've done this by these 2 packages:

                           

                          package com.packages
                          {
                          import flash.display.DisplayObject;
                          import mx.controls.DataGrid;
                          import mx.core.IUIComponent;
                          import mx.core.EdgeMetrics;
                          import mx.styles.ISimpleStyleClient;

                           

                          public class FooterDataGrid extends DataGrid
                          {

                           

                              public function FooterDataGrid()
                              {
                                  super();
                              }

                           

                              protected var footer:DataGridFooter;

                           

                              protected var footerHeight:int = 22;

                           

                              override protected function createChildren():void
                              {
                                  super.createChildren();

                           

                                  if (!footer)
                                  {
                                      footer = new DataGridFooter();
                                      footer.styleName = this;
                                      addChild(footer);
                                  }
                              }

                           

                              override protected function adjustListContent(unscaledWidth:Number = -1,
                                                                 unscaledHeight:Number = -1):void
                              {
                                  super.adjustListContent(unscaledWidth, unscaledHeight);

                           

                                  listContent.setActualSize(listContent.width, listContent.height - footerHeight);
                                  footer.setActualSize(listContent.width, footerHeight);
                                  footer.move(listContent.x, listContent.y + listContent.height + 1);
                              }

                           

                              override public function invalidateDisplayList():void
                              {
                                  super.invalidateDisplayList();
                                  if (footer)
                                      footer.invalidateDisplayList();
                              }
                          }

                           

                          }

                           

                          and this one:

                           

                          package com.packages
                          {
                          import mx.controls.dataGridClasses.DataGridColumn;

                           


                          [DefaultProperty("footerColumn")]

                           

                          public class FooterDataGridColumn extends DataGridColumn
                          {

                           

                              public function FooterDataGridColumn()
                              {
                                  super();
                              }

                           

                              public var footerColumn:DataGridColumn;

                           

                          }

                           

                          }

                           

                          is this subclassing them? however the owner property seems to be protected and i cannot access it.

                          • 10. Re: labelfunction in a datagrid
                            Flex harUI Adobe Employee

                            The FooterDataGridColumn is a subclass.  The logic you add to that file

                            should be able to use the owner property.

                            • 11. Re: labelfunction in a datagrid
                              BosDog Level 1

                              but i'm not within that packaged AS file... i'm in an MXML file that uses it like this:

                               

                                  <local:FooterDataGrid id="ptqGrid" x="10" y="487" width="940" itemClick="itemClickEvent('ptqGrid',event);" dataProvider="{parentApplication.Service.perfToQuota.lastResult}" rowCount="5">
                                      <local:columns>
                                          <local:FooterDataGridColumn headerText="Quota Description" width="180" dataField="quota_desc">
                                              <mx:DataGridColumn headerText="Totals:" width="180" textAlign="right"/>
                                          </local:FooterDataGridColumn>

                               

                                          <local:FooterDataGridColumn headerText="Quota" dataField="quota" labelFunction="{parentApplication.price_labelFunc}" textAlign="right" >
                                              <mx:DataGridColumn labelFunction="sumFunction" dataField="quota" textAlign="right" />
                                          </local:FooterDataGridColumn>
                                         
                                          <local:FooterDataGridColumn headerText="Total Revenue" labelFunction="{parentApplication.price_labelFunc}" textAlign="right" dataField="tot_rev">
                                              <local:itemRenderer>
                                              <mx:Component>
                                              <mx:Label text="{parentApplication.currencyFormatter.format(data.tot_rev)}" textAlign="right" color="#0000FF"
                                              styleName="lblNoUnderline" buttonMode="true" useHandCursor="true"
                                              mouseOver="styleName='lblUnderline';" mouseChildren="false"
                                              mouseOut="styleName='lblNoUnderline';"/>
                                              </mx:Component>
                                              </local:itemRenderer>
                                              <mx:DataGridColumn labelFunction="sumFunction" dataField="tot_rev" textAlign="right" />
                                          </local:FooterDataGridColumn>
                                          <local:FooterDataGridColumn headerText="Target Earnings" textAlign="right" labelFunction="{parentApplication.price_labelFunc}" dataField="trgt_earn">
                                              <mx:DataGridColumn labelFunction="sumFunction" dataField="trgt_earn" textAlign="right" />                   
                                          </local:FooterDataGridColumn>
                                          <local:FooterDataGridColumn headerText="Total Earnings" textAlign="right" labelFunction="{parentApplication.price_labelFunc}" dataField="tot_earn">
                                              <local:itemRenderer>
                                              <mx:Component>
                                              <mx:Label text="{parentApplication.currencyFormatter.format(data.tot_earn)}" textAlign="right" color="#0000FF"
                                              styleName="lblNoUnderline" buttonMode="true" useHandCursor="true"
                                              mouseOver="styleName='lblUnderline';" mouseChildren="false"
                                              mouseOut="styleName='lblNoUnderline';"/>
                                              </mx:Component>
                                              </local:itemRenderer>   
                                              <mx:DataGridColumn labelFunction="sumFunction" dataField="tot_earn" textAlign="right" />
                                          </local:FooterDataGridColumn>
                                          <local:FooterDataGridColumn headerText="Achievement" textAlign="right" dataField="ach">
                                              <mx:DataGridColumn labelFunction="averageFunction" dataField="ach" textAlign="right" />                   
                                          </local:FooterDataGridColumn>
                                      </local:columns>
                                  </local:FooterDataGrid>

                               

                               

                              and here is my sumFunction that is giving me the problem and does not have access to the owner property:

                               

                                      public function sumFunction(col:FooterDataGridColumn):String
                                      {
                                          var n:int = ptqGrid.dataProvider.length;
                                          var sum:Number = 0;
                                          for (var i:int = 0; i < n; i++)
                                          {
                                              sum += int(ptqGrid.dataProvider[i][col.dataField]);
                                          }
                                          return parentApplication.currencyFormatter.format(sum);//.toFixed(2);
                                      }

                              • 12. Re: labelfunction in a datagrid
                                Flex harUI Adobe Employee

                                You should create yet another subclass of DataGridColumn that has

                                sumFunction in it.  Then sumFunction will have the scope of the

                                DataGridColumn

                                • 13. Re: labelfunction in a datagrid
                                  BosDog Level 1

                                  yikes... seems more trouble than its worth. although what would creating yet another subclass do since the owner property is protected... so it wouldnt solve this problem as i'd still be unable to access it.

                                   

                                  what if i wanted to pass the name of the datagrid i'm on to the function how would i do that? like in my first post i mentioned something like that... but once i add another argument it doesnt like running that function

                                   

                                  so if my datagrid id was "foo" I'd do something like this:

                                   

                                  sumFunction('foo')

                                  • 14. Re: labelfunction in a datagrid
                                    Flex harUI Adobe Employee

                                    Subclasses can access protected methods and properties.  The functions on

                                    the subclass are bound to the subclass so they can reference the protected

                                    stuff.