DataTablesで合計値を表示する

# はじめに
業務系のシステムでは表組みで情報を表示することがよくありますが、そんな時に便利なのがDataTablesです。
ページングやソートといった、よくあるけど自前で用意すると地味に手間な機能が用意されているのでとても助かります。
https://datatables.net

そんなDataTablesを利用して集計を行った場合に、合計値をDataTablesの外で表示するための備忘録です。（合計値以外でも可能ですね）

# Footer callback
まずはDataTables内で表示するパターンです。
公式サイトの実装例通り、footerCallback関数を利用します。
https://datatables.net/examples/advanced_init/footer_callback.html

```javascript:sample.html
$(document).ready(function() {
    $('#example').DataTable( {
        "footerCallback": function ( row, data, start, end, display ) {
            var api = this.api(), data;
 
            // Remove the formatting to get integer data for summation
            var intVal = function ( i ) {
                return typeof i === 'string' ?
                    i.replace(/[\$,]/g, '')*1 :
                    typeof i === 'number' ?
                        i : 0;
            };
 
            // Money delimiter
            var moneyVal = function (i) {
                var valAry
                valAry = String(i).split('.')
                valAry[0] = valAry[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')
                return valAry.join('.')
            };

            // Total over all pages
            total = api
                .column( 4 )
                .data()
                .reduce( function (a, b) {
                    return intVal(a) + intVal(b);
                }, 0 );
 
            // Total over this page
            pageTotal = api
                .column( 4, { page: 'current'} )
                .data()
                .reduce( function (a, b) {
                    return intVal(a) + intVal(b);
                }, 0 );
 
            // Update footer
            $( api.column( 4 ).footer() ).html(
                '$'+ moneyVal(pageTotal) +' ( $'+ moneyVal(total) +' total)'
            );
        }
    } );
} );
```

# Draw callback
次に本題のDataTables外で表示するパターンですが…こちらも公式サイトのReferenceに載っています。
drawCallback関数を利用し、DOM操作で結果を反映します。
https://datatables.net/reference/option/drawCallback

例えば`<p id="total"></p>`という合計値の表示領域があったとすると、下記のようになります。

```javascript:sample.html
$(document).ready(function() {
    $('#example').DataTable( {
        "drawCallback": function( settings ) {
            var api = this.api();
 
            // Remove the formatting to get integer data for summation
            var intVal = function ( i ) {
                return typeof i === 'string' ?
                    i.replace(/[\$,]/g, '')*1 :
                    typeof i === 'number' ?
                        i : 0;
            };
 
            // Money delimiter
            var moneyVal = function (i) {
                var valAry
                valAry = String(i).split('.')
                valAry[0] = valAry[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1,')
                return valAry.join('.')
            };

            // Total over all pages
            total = api
                .column( 4 )
                .data()
                .reduce( function (a, b) {
                    return intVal(a) + intVal(b);
                }, 0 );
 
            // Total over this page
            pageTotal = api
                .column( 4, { page: 'current'} )
                .data()
                .reduce( function (a, b) {
                    return intVal(a) + intVal(b);
                }, 0 );
 
            // Update value
            window.$('#total').html('$'+moneyVal(pageTotal) +' ( $'+ moneyVal(total) +' total)');
        }
    } );
} );
```

footerCallback関数とほとんど同じですね。

# おわりに
DataTables、便利です。