8 Replies Latest reply on Jan 27, 2010 3:51 AM by archemedia

    Displaying Datagrid total in a label

    KevMull Level 1

      MI'm trying to display a total of a dg column in a label but it's not working., the label is showing nothing and no errors are shown.

       

      Here is my code...

       

      [Bindable] public var sumUnitPrice:String ;

       

      private function getTotalStockValue():String
                          {                      

       

                              var sum : Number = 0;
                              var count : Number = 0;
                             
                              var length : int = storeProductsDataGrid.dataProvider.length;
                              for( var i : int = 0; i < length; i++ )
                              {
                              var item : Object = storeProductsDataGrid.dataProvider.getItemAt( i );
                              var value : Number = item(i).unitPrice;
                                  if( ! isNaN( value ))
                                  {
                                  sum += value;
                                  //count += 1;
                                  }
                              }
                            //  totalCount = count.toString();
                              sumUnitPrice = sum.toString();
                             
                              return sumUnitPrice ;
                             
                          }

       

      And my label which should show teh total of unitPrice in my XML...

       

      <mx:Label id="totalUnitPriceLabel" text="{getTotalStockValue()}" />

       

      Many Thanks

        • 1. Re: Displaying Datagrid total in a label
          archemedia Level 4

          Have you tried:

           

          return String(sumUnitPrice) ;

           

          Also, your function will be called on startup, but afterwards it won't work.

          A better approach is to define a variable total:Number and bind this to your label:

           

          <mx:Label text="{String(total)}"/>

           

          Then trigger your calculate function each time a value changes in your grid.

          In the function itself, don't return a value, just calculate total again.

           

          Dany

          • 2. Re: Displaying Datagrid total in a label
            KevMull Level 1

            Thanks for the quick reply

             

            OK, i've removed the return and set the value to a variable and bound my label to this as per your last suggestion.

             

            Now it works when I execute via a button (which I don't want) but doesn't fire on my datagrid dataChange or change events or creationComplete.

            What and where is the correct event proceure for the dg?

             

            Amended code...

             

            [Bindable] public var sumUnitPrice:String ;

             

            private function getTotalStockValue():void
                                {                               
                                    
                                    var grid:mx.controls.DataGrid = storeProductsDataGrid;
                                    var sum :Number = 0;
                                    var count :Number = 0;
                                    var rows:Number = grid.dataProvider.length;
                                    var strTotalUnitPrice:String ;
                                   
                                    for (count = 0; count < rows ; count++)   
                                    {
                                    var value :Number = grid.dataProvider.getItemAt(count).unitPrice*grid.dataProvider.getItemAt(count).unitsInSt ock;
                                        if( ! isNaN( value ))
                                        {
                                        sum += value;
                                        //count += 1;
                                        }
                                    }
                                    totalCount = count.toString();
                                    sumUnitPrice = sum.toString();                       
                          
                                }

             

            <mx:Label id="totalUnitPriceLabel" text="{sumUnitPrice}" />

            • 3. Re: Displaying Datagrid total in a label
              KevMull Level 1

              OK, i've fixed it.  I need to add an event listener on my app creationcomplete...

               

              storeProductsDataGrid.addEventListener(CollectionEvent.COLLECTION_CHANGE, handleChangeEvent);

               

              and..

               

              //function for handling the data change event on datagrid
                                  public function handleChangeEvent(event:CollectionEvent):void
                                  {
                                      getTotalStockValue() ;
                                   //Alert.show("Data provider has been changed");
                                                      
                                  }

               

              No need to add anything on the actual dg properties.

               

              many Thanks for all your help

              • 4. Re: Displaying Datagrid total in a label
                archemedia Level 4

                you have to use the itemEditEnd event on your dataGrid. The editable property must be set to true:

                 

                <mx:DataGrid editable="true" itemEditEnd="getTotalStockValue"/>

                 

                There is a small trap here though! The itemEditEnd event is dispatched just before the dataProvider is updated. So the sum will be 'one step behind' your editing actions. You can solve this by postponing the call to your function to the next screen update, using the callLater method:

                 

                <mx:DataGrid editable="true" itemEditEnd="callLater(getTotalStockValue)"/>

                 

                TIP: In your function you loop through the dataProvider property of your dataGrid. It's better to bind the dataProvider to an arrayCollection and then loop through your arrayCollection for calculating the sum:

                 

                [Bindable]

                private var dp:ArrayCollection;

                 

                ...

                 

                 

                private function getTotalStockValue():void
                            {
                                var sum :Number = 0;
                                for each (var n:Object in dp)
                                {
                                    sum += n.unitPrice * n.unitsInStock;
                                }
                               
                                sumUnitPrice = String(sum);
                            }

                 

                 

                Dany

                • 5. Re: Displaying Datagrid total in a label
                  archemedia Level 4

                  Your solution is good too

                  • 6. Re: Displaying Datagrid total in a label
                    archemedia Level 4

                    Still one remark: you should add the event listener to the dataprovider and not to the datagrid itself!

                     

                    Dany

                    • 7. Re: Displaying Datagrid total in a label
                      KevMull Level 1

                      You mean like this?......

                       

                      storeProductsDataGrid.dataProvider.addEventListener(CollectionEvent.COLLECTION_CHANGE, handleChangeEvent);

                       

                      Which gave me a runtime error..'TypeError: Error #1009: Cannot access a property or method of a null object reference.'

                       

                      Thanks

                      • 8. Re: Displaying Datagrid total in a label
                        archemedia Level 4

                        No, attach the eventListener to the arrayCollection iteself:

                         

                        [Bindable]
                        private var dp:ArrayCollection;

                         

                        private function init():void

                        {

                             var arr:Array = [{...}, {...}];

                             dp = new ArrayCollection();

                             dp.source = arr;

                             dp.addEventListener(CollectionEvent.COLLECTION_CHANGE, handleChange);

                        }

                         

                        private function handleChange(evt:CollectionEvent):void

                        {

                         

                        }

                         

                         

                        ...

                         

                         

                        <mx:DataGrid id="dg" dataProvider="{dp}">

                         

                        Dany