@ngdoc overview
@name Tutorial: 105 Footer
@description

### Grid Footer
The grid supports a grid footer row, which can be displayed if showGridFooter option is set to true (default=false). This footer displays
Total rows in the grid and the number of filtered rows.  Selected rows will be shown if using ui-grid-selection feature.
<br/>
### Column Footer
The grid also has column footer, which can be displayed if showColumnFooter option is set to true (default=false).
You can set an aggregation function for each column or use a custom footer template to display
what ever aggregation you wish.
Aggregation functions supported are: sum, avg, row count, min, max.
You need to inject the uiGridConstants in order to use aggregationTypes enum.
You can also pass in a function in order to create your own aggregation logic.
If you set the `aggregationHideLabel` option on the columnDef to true, then the column will
show the aggregation but without a label.  Refer the third column in the example below.

Note that aggregation works across the visible rows - e.g. it would show the sum of the visible
ages.  For this reason it doesn't combine well with features that alter the visible rows - in particular pagination
and grouping.  In the case of pagination, you'll find that it gives you the total for the currently displayed page,
which isn't intuitively what users would expect.  With grouping it will give the total of the currently expanded
data rows, which again may not be what users intuitively expect.

In the case of grouping the solution is to use the aggregation provided with grouping.

<br/>
You can override the default grid footer template with gridOptions.footerTemplate.  Copy the default ui-grid-footer.html from the source as your starting point.  <i>This is not demonstrated in this tutorial.</i>

@example
<example module="app">
  <file name="app.js">
    var app = angular.module('app', ['ngTouch', 'ui.grid']);

    app.controller('MainCtrl', ['$scope','uiGridConstants', '$http', function ($scope, uiGridConstants, $http) {
    var data = [];

    $scope.gridOptions = {
        showGridFooter: true,
        showColumnFooter: true,
        enableFiltering: true,
        columnDefs: [
            { field: 'name', width: '13%' },
            { field: 'address.street',aggregationType: uiGridConstants.aggregationTypes.sum, width: '13%' },
            { field: 'age', aggregationType: uiGridConstants.aggregationTypes.avg, aggregationHideLabel: true, width: '13%' },
            { name: 'ageMin', field: 'age', aggregationType: uiGridConstants.aggregationTypes.min, width: '13%', displayName: 'Age for min' },
            { name: 'ageMax', field: 'age', aggregationType: uiGridConstants.aggregationTypes.max, width: '13%', displayName: 'Age for max' },
            { name: 'customCellTemplate', field: 'age', width: '14%', footerCellTemplate: '<div class="ui-grid-cell-contents" style="background-color: Red;color: White">custom template</div>' },
            { name: 'registered', field: 'registered', width: '20%', cellFilter: 'date', footerCellFilter: 'date', aggregationType: uiGridConstants.aggregationTypes.max }
        ],
        data: data,
        onRegisterApi: function(gridApi) {
                $scope.gridApi = gridApi;
        }
    };

    $scope.toggleFooter = function() {
      $scope.gridOptions.showGridFooter = !$scope.gridOptions.showGridFooter;
      $scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.OPTIONS);
    };

    $scope.toggleColumnFooter = function() {
      $scope.gridOptions.showColumnFooter = !$scope.gridOptions.showColumnFooter;
      $scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.OPTIONS);
    };

    $http.get('/data/500_complex.json')
      .success(function(data) {
        data.forEach( function(row) {
          row.registered = Date.parse(row.registered);
        });
        $scope.gridOptions.data = data;
      });
    }]);
  </file>
  <file name="index.html">
    <div ng-controller="MainCtrl">
      <button id="footerButton" class="btn btn-success" ng-click="toggleFooter()">Toggle Grid Footer</button>
      <button class="btn btn-success" ng-click="toggleColumnFooter()">Toggle Column Footer</button>
      <div id="grid1" ui-grid="gridOptions" class="grid"></div>
    </div>
  </file>
  <file name="main.css">
    .grid {
      width: 100%;
      height: 250px;
    }
  </file>

  <file name="scenario.js">
    var gridTestUtils = require('../../test/e2e/gridTestUtils.spec.js');
    describe( '105 footer', function() {
      /*
      var $filter = angular.module('[app]').injector().get('$filter');

      function getMaxDateString() {
        // Get the bound value for the max date
        var maxFooterCell = gridTestUtils.footerCell( 'grid1', 6 );
        var maxDate =  maxFooterCell.evaluate('col.getAggregationValue()');
        var maxDateFormattedString = $filter('date')(maxDate, 'MMM d, yyyy');

        return maxDateFormattedString;
      }
      */

      it('grid should have six visible columns', function () {
        gridTestUtils.expectHeaderColumnCount( 'grid1', 7 );
      });

      it('grid should have six visible columns in footer', function () {
        gridTestUtils.expectFooterColumnCount( 'grid1', 7 );
      });

      it('grid should have footers with specific values', function () {
        gridTestUtils.expectFooterCellValueMatch( 'grid1', 0, '' );
        gridTestUtils.expectFooterCellValueMatch( 'grid1', 1, 'total: 281568' );
        gridTestUtils.expectFooterCellValueMatch( 'grid1', 2, '30.248' );
        gridTestUtils.expectFooterCellValueMatch( 'grid1', 3, 'min: 20' );
        gridTestUtils.expectFooterCellValueMatch( 'grid1', 4, 'max: 49' );
        gridTestUtils.expectFooterCellValueMatch( 'grid1', 5, 'custom template' );
        // gridTestUtils.expectFooterCellValueMatch( 'grid1', 6, 'max: ' + getMaxDateString() );
        // TODO: need to check item count, not done
      });

      it('filter and expect recalculate', function () {
        gridTestUtils.enterFilterInColumn( 'grid1', 1, '3' )
          .then(function () {
            gridTestUtils.expectFooterCellValueMatch( 'grid1', 0, '' );
            gridTestUtils.expectFooterCellValueMatch( 'grid1', 1, 'total: 68974' );
            gridTestUtils.expectFooterCellValueMatch( 'grid1', 2, '29.8978102189781' );
            gridTestUtils.expectFooterCellValueMatch( 'grid1', 3, 'min: 20' );
            gridTestUtils.expectFooterCellValueMatch( 'grid1', 4, 'max: 40' );
            gridTestUtils.expectFooterCellValueMatch( 'grid1', 5, 'custom template' );
            // gridTestUtils.expectFooterCellValueMatch( 'grid1', 6, 'max: ' + getMaxDateString() );
            // TODO: need to check item count, not done
          });
      });
    });
  </file>
</example>
