KoolReport's Forum

Official Support Area, Q&As, Discussions, Suggestions and Bug reports.
Forum's Guidelines

DataGrid sums do not change after using search #631

Closed Ant Klad opened this topic on on Jan 29, 2019 - 16 comments

Ant Klad commented on Jan 29, 2019

I'm using DataGrid with search option. However, although search shows the correct items it does not recalculate the sums.

KoolReport commented on Jan 29, 2019

That's feature is not available now. Basically the sum is at server-side however the search at client-side. Although it is totally possible to write script at client-side to recalculate the sum.

Ant Klad commented on Jan 29, 2019

How would a script like that be? Is there an example?

KoolReport commented on Jan 29, 2019

There will be something mention in the stackoverflow Jquery Datatable Calculate Sum in footer while Searching

Ant Klad commented on Jan 29, 2019

That seems complicated. Where should I place this javascript code?

KoolReport commented on Jan 29, 2019

It should be on the report view. For the solution, I just google to find similar issue. The DataTables has a onReady function which will be called after the DataTables initiated.

DataTables::create(array(
    "onReady"=>"function(table){
        console.log(table);
    }"
));
Ant Klad commented on Jan 29, 2019

It is not so obvious to see what needs to be done, probably because I'm not so fluent with javascript.

I have tried the following but it does not work :

"onReady"=>"function(table){
        try {

        var intVal = function (i) {
            return typeof i === 'string' ?
                    i.replace(/[\$,]/g, '') * 1 :
                    typeof i === 'number' ?
                        i : 0;
        };

        var api = table;
        api.columns(\".sum\").eq(0).each(function (index) {
            var column = api.column(index,{page:'current'});

            var sum = column
               .data()
               .reduce(function (a, b) {
                   //return parseInt(a, 10) + parseInt(b, 10);
                   return intVal(a) + intVal(b);
               }, 0);


console.log(sum);

            if ($(column.footer()).hasClass(\"Int\")) {
                $(column.footer()).html('' + sum.toFixed(0));
            } else {
                $(column.footer()).html('' + sum.toFixed(2));
            }

        });
    } catch (e) {
        console.log('Error in CalculateTableSummary');
        console.log(e)
    }
    }",
Ant Klad commented on Jan 30, 2019

After adding a breakpoint in the js debuger the I found that the code for onReady is never executed. Probably it would be easier to fix the bug in the js code that is used to filter the data.

KoolReport commented on Jan 30, 2019

Do you use any clientEvents of DataTables?

Ant Klad commented on Jan 31, 2019

I have made more test with "onReady" event. It is called only when the table initialises and thus the footer is only updated initialy. After filtering it is no called. Actually, in the DataTables doc I found that footerCallback is called after filtering but I can't find how to use this with KoolReport with DataGrid.

Ant Klad commented on Jan 31, 2019

I found that the problem is that "onReady" event is only called after table initialisation. In order to calculate the sum after filtering I need to use the footerCallback event. However I can't find how to attach to this event. Any sugestions on this would be realy helpfull. I have tried to add an event handler when onReady is called like this :

"onReady"=>"function(table) {
    var api = table;
	api.on(\"footerCallback\", function ( tfoot, data, start, end, display )
	{
		var api = this.api();
		$( api.column( 4 ).footer() ).html(
        api.column( 4 ).data().reduce( function ( a, b ) {
			var v1 = parseInt(a);
			var v2 = parseInt(b);
            return v1+v2;
        }, 0 )
    );
	});
  }"

but it does not work.

KoolReport commented on Jan 31, 2019

Please aware that your column value may be formatted so the parseInt may not work

Ant Klad commented on Jan 31, 2019

The column that I am using has integer values. The problem is that the event is not called after search. How can I attach to the footerCallback event?

KoolReport commented on Jan 31, 2019

If you add this, does it console log the string:

"onReady"=>"function(table) {
    console.log('Run on ready');
...
}
"

please let me know.

Ant Klad commented on Jan 31, 2019

Yes. But only once. Not after search.

KoolReport commented on Jan 31, 2019

I've check the doc of footerCallback, let do this:

DataTables::ceate(array(
    "options"=>array(
        "footerCallback"=>"function(tfoot, data, start, end, display){
               //Your javascript code here.
        }"
    )
));
Ant Klad commented on Jan 31, 2019

OK. I have it working now like this :

"options"=>array(
        "searching"=>true,
		"footerCallback"=>"function(tfoot, data, start, end, display)
		{
              
			   var api = this.api(), data;
						
			CalcColumnSum(4);
			CalcColumnSum(5);
			
			function CalcColumnSum( ColumnIdx)
			{
				$( api.column( ColumnIdx ).footer() ).html(
				api.column( ColumnIdx, {\"filter\": \"applied\"} ).data().reduce( function ( a, b ) 
				{
					var strf1 = String(a).replace(\".\", \"\");
					var strf2 = String(b).replace(\".\", \"\");					
					strf1 = strf1.replace(\",\",\".\");
					strf2 = strf2.replace(\",\",\".\");					
					var v1 = parseFloat(strf1);
					var v2 = parseFloat(strf2);
					//console.log( 'a, b '+v1+' '+v2);
					var v = v1+v2;
					var ret = v.toFixed(2);
					ret = ret.replace(\".\",\",\");
					return ret;
				}, 0 )
				);
			}
        }		
		",
    ),	
	"showFooter"=>true,

Build Your Excellent Data Report

Let KoolReport help you to make great reports. It's free & open-source released under MIT license.

Download KoolReport View demo
bug
help needed

DataGrid