
# column footer

It is simple to calculate and display the total for each column in RealGrid. You just need to specify an expression that displays statistical values in the column footer.**expression**. The types of values that can be used in the expression vary depending on the grid **summaryMode**.
If the total value calculated and provided by the grid is incorrect or the required summation expression does not exist, you can use valueCallback() to display it.
You can also get the total value of a field by calling the GridBase.**getSummary(field, summary)** function. field can be a field name or field index.
Types that can be displayed as summary values include `avg`, `sum`, `count`, `min`, and `max`. For more details, see [SummaryType](/refs/realgrid#summarytype) Check it out here.

#### Column Footer

```js
const fields = [
  { fieldName: 'KorName', dataType: 'text' },
  { fieldName: 'Gender', dataType: 'text' },
  { fieldName: 'Age', dataType: 'number' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductId', dataType: 'text' },
  { fieldName: 'KorCountry', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CardNumber', dataType: 'text' },
  { fieldName: 'Monetary', dataType: 'text' },
  { fieldName: 'StartDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'EndDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'ToMonth', dataType: 'number' },
  { fieldName: 'Month', dataType: 'number' },
  { fieldName: 'Year', dataType: 'number' },
  { fieldName: 'InterestRate', dataType: 'number' },
  { fieldName: 'SaveCost', dataType: 'number' },
  { fieldName: 'SaveMaturity', dataType: 'number' },
  { fieldName: 'CurrentSave', dataType: 'number' }
];

const columns = [
  { name: 'KorName', fieldName: 'KorName', width: '60', header: { text: 'Name' }, checked: 'true' },
  { name: 'Gender', fieldName: 'Gender', width: '40', header: { text: 'Gender' } },
  { name: 'Age', fieldName: 'Age', width: '40', header: { text: 'Age' }, styleName: 'right-column' },
  { name: 'Phone', fieldName: 'Phone', width: '100', header: { text: 'Phone' } },
  { name: 'ProductId', fieldName: 'ProductId', width: '120', header: { text: 'Product ID' } },
  { name: 'KorCountry', fieldName: 'KorCountry', width: '100', header: { text: 'Investment Country' } },
  { name: 'SaveCost', fieldName: 'SaveCost', width: '80', numberFormat: '#,##0', header: { text: 'Payment Amount' }, footer: { text: 'Total =>' }, styleName: 'right-column' },
  { name: 'SaveMaturity', fieldName: 'SaveMaturity', width: '80', numberFormat: '#,##0', header: { text: 'Maturity Amount' }, footer: { expression: 'sum', numberFormat: '#,##0', styleName: 'orange-column' }, styleName: 'right-column' },
  { name: 'OrderDate', fieldName: 'OrderDate', width: '100', header: { text: 'Order Date' } },
  { name: 'CardNumber', fieldName: 'CardNumber', width: '140', header: { text: 'Card Number' } },
  { name: 'Monetary', fieldName: 'Monetary', width: '40', header: { text: 'Currency' } },
  { name: 'StartDate', fieldName: 'StartDate', width: '100', header: { text: 'First Payment Date' } },
  { name: 'EndDate', fieldName: 'EndDate', width: '100', header: { text: 'End Date' } },
  { name: 'ToMonth', fieldName: 'ToMonth', width: '50', header: { text: 'Payment Count' }, styleName: 'right-column' },
  { name: 'Month', fieldName: 'Month', width: '50', header: { text: 'Remaining Count' }, styleName: 'right-column' },
  { name: 'InterestRate', fieldName: 'InterestRate', width: '50', numberFormat: '0.00', header: { text: 'Interest Rate' }, styleName: 'right-column' },
  { name: 'CurrentSave', fieldName: 'CurrentSave', width: '80', numberFormat: '#,##0', header: { text: 'Current Balance' }, styleName: 'right-column' }
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: 40
  },
  display: {
    rowHeight: 36,
    emptyMessage: 'No data to display.'
  },
  edit: {
    insertable: true,
    appendable: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/simple_data.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
      });
  }
}, {
  fields
});

window.gridView = gridView;
window.dataProvider = dataProvider;
```

- `footer.visible`: Displays the footer at the bottom of the grid.

```js
// Specify sum expression when setting column
gridView.setColumns([{
     ...
}, {
     name: "SaveCost",
     fieldName: "SaveCost",
     width: "80",
     numberFormat: "#,##0",
     header: {
       text: "Payment"
     },
     footer: {
       text: "Total =>"
     },
     styleName: "right-column"
   },
   {
     name: "SaveMaturity",
     fieldName: "SaveMaturity",
     width: "80",
     numberFormat: "#,##0",
     header: {
       text: "Maturity amount"
     },
     footer: {
       text: "Total",
       expression: "sum",
     },
     styleName: "right-column"
   }, {
     ...
}];
```

As in the footer, the summary mode must be set to **"statistical"** to display the variance and standard deviation values.

```js
gridView.setOptions({ summaryMode: "statistical" });
```

```js
gridView.setOptions({ summaryMode: "aggregate" });
```

It does not calculate the sum of the column.

```js
gridView.setOptions({ summaryMode: "none" });
```

Please refer to [summary Mode](/refs/realgrid#summarymode#summary) on the Help site.

#### Column footer dynamic calculation

The content to be displayed in the column footer can be processed in column.footer.valueCallback() to display the desired value.

```js
const fields = [
  { fieldName: 'KorName', dataType: 'text' },
  { fieldName: 'Gender', dataType: 'text' },
  { fieldName: 'Age', dataType: 'number' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductId', dataType: 'text' },
  { fieldName: 'KorCountry', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CardNumber', dataType: 'text' },
  { fieldName: 'Monetary', dataType: 'text' },
  { fieldName: 'StartDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'EndDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'ToMonth', dataType: 'number' },
  { fieldName: 'Month', dataType: 'number' },
  { fieldName: 'Year', dataType: 'number' },
  { fieldName: 'InterestRate', dataType: 'number' },
  { fieldName: 'SaveCost', dataType: 'number' },
  { fieldName: 'SaveMaturity', dataType: 'number' },
  { fieldName: 'CurrentSave', dataType: 'number' }
];

const columns = [
  { name: 'KorName', fieldName: 'KorName', width: '60', header: { text: 'Name' }, checked: 'true' },
  { name: 'Gender', fieldName: 'Gender', width: '40', header: { text: 'Gender' } },
  { name: 'Age', fieldName: 'Age', width: '40', header: { text: 'Age' }, styleName: 'right-column' },
  { name: 'Phone', fieldName: 'Phone', width: '100', header: { text: 'Phone' } },
  { name: 'ProductId', fieldName: 'ProductId', width: '120', header: { text: 'Product ID' } },
  { name: 'KorCountry', fieldName: 'KorCountry', width: '100', header: { text: 'Investment Country' } },
  {
    name: 'SaveCost',
    fieldName: 'SaveCost',
    width: '80',
    numberFormat: '#,##0',
    header: { text: 'Payment Amount' },
    footer: { text: 'Average =>' },
    styleName: 'right-column'
  },
  {
    name: 'SaveMaturity',
    fieldName: 'SaveMaturity',
    width: '80',
    numberFormat: '#,##0',
    header: { text: 'Maturity Amount' },
    footer: {
      numberFormat: '#,##0',
      styleName: 'orange-column',
      valueCallback: function (grid, column, footerIndex, columnFooter, value) {
        const sum = grid.getSummary('SaveMaturity', 'sum');
        const cnt = grid.getDataSource().getRowCount();
        return sum / cnt;
      }
    },
    styleName: 'right-column'
  },
  { name: 'OrderDate', fieldName: 'OrderDate', width: '100', header: { text: 'Order Date' } },
  { name: 'CardNumber', fieldName: 'CardNumber', width: '140', header: { text: 'Card Number' } },
  { name: 'Monetary', fieldName: 'Monetary', width: '40', header: { text: 'Currency' } },
  { name: 'StartDate', fieldName: 'StartDate', width: '100', header: { text: 'First Payment Date' } },
  { name: 'EndDate', fieldName: 'EndDate', width: '100', header: { text: 'End Date' } },
  { name: 'ToMonth', fieldName: 'ToMonth', width: '50', header: { text: 'Payment Count' }, styleName: 'right-column' },
  { name: 'Month', fieldName: 'Month', width: '50', header: { text: 'Remaining Count' }, styleName: 'right-column' },
  { name: 'InterestRate', fieldName: 'InterestRate', width: '50', numberFormat: '0.00', header: { text: 'Interest Rate' }, styleName: 'right-column' },
  { name: 'CurrentSave', fieldName: 'CurrentSave', width: '80', numberFormat: '#,##0', header: { text: 'Current Balance' }, styleName: 'right-column' }
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: 40
  },
  display: {
    rowHeight: 36,
    emptyMessage: 'No data to display.'
  },
  edit: {
    insertable: true,
    appendable: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/simple_data.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
      });
  }
}, {
  fields
});

window.gridView = gridView;
window.dataProvider = dataProvider;
```

```js
// Specify sum expression when setting column
gridView.setColumns([{
     ...
}, {
     name: "SaveMaturity",
     fieldName: "SaveMaturity",
     width: "80",
     numberFormat: "#,##0",
     header: {
       text: "Maturity amount"
     },
     footer: {
       numberFormat: "#,##0",
       styleName:"orange-column",
       valueCallback: function (grid, column, footerIndex, columnFooter, value){
         //You can easily find the average value with the code below
         //var avg = grid.getSummary("SaveMaturity", "avg");
         //If calculated separately, process as follows
         var sum = 0;
         var prod = grid.getDataSource();
         var cnt = prod.getRowCount();

         for (var i=0 ; i<cnt ; i++) {
           sum += prod.getValue(i, 'SaveMaturity');
         }

         return sum / cnt;
       }
     },
     styleName: "right-column"
   }, {
     ...
}];
```

#### Column footer display multiple rows

The footer summary can be displayed in multiple rows.
Just create {} as many footers as you need for your items.

```js
const fields = [
  { fieldName: 'OrderID', dataType: 'text' },
  { fieldName: 'CustomerID', dataType: 'text' },
  { fieldName: 'EmployeeID', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CompanyName', dataType: 'text' },
  { fieldName: 'Country', dataType: 'text' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductName', dataType: 'text' },
  { fieldName: 'QuantityPerUnit', dataType: 'text' },
  { fieldName: 'Quantity', dataType: 'number' },
  { fieldName: 'UnitPrice', dataType: 'number' }
];

const columns = [
  { name: 'Country', fieldName: 'Country', width: '100', header: { text: 'Country' } },
  { name: 'CompanyName', fieldName: 'CompanyName', width: '120', header: { text: 'Company Name' } },
  {
    name: 'QuantityPerUnit',
    fieldName: 'QuantityPerUnit',
    width: '100',
    header: { text: 'Quantity / Unit', styleName: 'orange-column' },
    footers: [
      { text: 'Total ==>  ', styleName: 'orange-column' },
      { text: 'Average ==>  ', styleName: 'orange-column' }
    ]
  },
  {
    name: 'Quantity',
    fieldName: 'Quantity',
    width: '100',
    header: { text: 'Quantity', styleName: 'orange-column' },
    footers: [
      { expression: 'sum', numberFormat: '#,##0.00', styleName: 'orange-column' },
      { expression: 'avg', numberFormat: '#,##0.00', styleName: 'orange-column' }
    ]
  },
  { name: 'OrderID', fieldName: 'OrderID', width: '80', header: { text: 'Order ID' } },
  { name: 'CustomerID', fieldName: 'CustomerID', width: '90', header: { text: 'Customer ID' } },
  { name: 'EmployeeID', fieldName: 'EmployeeID', width: '90', header: { text: 'Employee ID' } },
  { name: 'OrderDate', fieldName: 'OrderDate', width: '130', header: { text: 'Order Date' } },
  { name: 'Phone', fieldName: 'Phone', width: '90', renderer: { type: 'button' }, header: { text: 'Phone' } },
  { name: 'ProductName', fieldName: 'ProductName', width: '200', header: { text: 'Product Name' } },
  { name: 'UnitPrice', fieldName: 'UnitPrice', width: '100', header: { text: 'Unit Price' } }
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: 40
  },
  display: {
    rowHeight: 36,
    emptyMessage: 'No data to display.'
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/editor_demoData.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
        grid.setFooters({
          visible: true,
          items: [{ height: 40 }, { height: 40 }]
        });
      });
  }
}, {
  fields
});

window.gridView = gridView;
window.dataProvider = dataProvider;
```

* options
  
```js
gridView.setFooters({
   visible:true,
   items:[
     {
       //styleName: "orange-column", //If individual CSS style application is required
       height: 40
     },
     {
       height: 40
     }
   ]
});
```

* columns
  
```js
var columns = [{
     ...
}, {
   "name": "QuantityPerUnit",
   "fieldName": "QuantityPerUnit",
   "width": "100",
   "header": {
       "text": "Quantity / Unit",
       "styleName": "orange-column"
   },
   "footers": [{
     "text": "Total ==> ",
     "styleName": "orange-column"
   }, {
     "text": "Average ==> ",
     "styleName": "orange-column"
   }]
}, {
   "name": "Quantity",
   "fieldName": "Quantity",
   "width": "100",
   "header": {
       "text": "Quantity",
       "styleName": "orange-column"
     },
   "footers": [{
     "expression": "sum",
     "numberFormat": "#,##0.00",
     "styleName": "orange-column"
   }, {
     "expression": "avg",
     "numberFormat": "#,##0.00",
     "styleName": "orange-column"
   }]
}, {
     ...
}];
```