We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

All-rows aggregate in server side grid

Hello there,

I would like to show an aggregate of all rows, but because I'm using server side model grid, I can only have the aggregate of loaded data.
Would you please kindly tell me what should I do to have the aggregate of all data?

Thanks
Masoud Moghaddari

5 Replies

PK Prasanna Kumar Viswanathan Syncfusion Team January 14, 2020 08:55 AM UTC

Hi Masoud, 
 
Thanks for contacting Syncfusion support. 
 
For remote data in Grid, we need to handle the aggregate action in server side else the Grid will take only the current page records to calculate the aggregate.  
 
For DataManager the grid will request an AJAX POST for data. It will be sent to the specified data service for every grid actions with the needed parameters the details of aggregates. The DataManager request contains the details of aggregates, we need to handle it from server side and pass along with result and count.  
 
Please refer the example code to handle the aggregate action in server side(For URL Adaptor), 
 
public IActionResult UrlDatasource(DataManagerRequest dm) 
        { 
 
            IEnumerable DataSource = order; 
            DataOperations operation = new DataOperations(); 
 
. . . 
            List<string> str = new List<string>(); 
            if (dm.Aggregates != null) 
            { 
                for (var i = 0; i < dm.Aggregates.Count; i++) 
                    str.Add(dm.Aggregates[i].Field); 
            } 
            IEnumerable aggregate = operation.PerformSelect(DataSource, str); 
            int count = DataSource.Cast<Orders>().Count(); 
            if (dm.Skip != 0) 
            { 
                DataSource = operation.PerformSkip(DataSource, dm.Skip);   //Paging 
            } 
            if (dm.Take != 0) 
            { 
                DataSource = operation.PerformTake(DataSource, dm.Take); 
            } 
            return dm.RequiresCounts ? Json(new { result = DataSource, count = count, aggregate = aggregate }) : Json(DataSource); 
        } 
 
Please get back to us, if you need further assistance. 
 
Regards, 
Prasanna Kumar N.S.V 



MM Masoud Moghaddari January 23, 2020 11:20 AM UTC

Hi Prasanna,

Thanks for your efforts.
I've managed to show a custom aggregate which is calculated on the server. I've sen't the aggregate value with DataManager alongside "Items" & "Count" and everything works great when grid is initialized.
I used "executeQuery" on "DataManager" which allowed me to retrieve my custom aggregate value from server.
My only problem is that when I do filtering or search in the grid (they all are server-side), the aggregate won't be updated in the grid.
So far I have found that the "DataManager" won't be updated and when "
executeQuery" is executed again after search or filter, it performs it's related operation on the initial "DataManager" object, not the updated on after search and filter.
I've attached a simplified version of my code so you might be able to know what is going on.
Hope my description was enough for your understanding.

Thank you again.
Masoud Moghaddari


Attachment: grid_68feb500.zip


BS Balaji Sekar Syncfusion Team January 24, 2020 12:35 PM UTC

Hi Masoud, 
 
Thanks for contacting us. 
 
While using remote data we need to handle the aggregate action in server side. Otherwise the Grid will take only the current page records to calculate the aggregate. While grid requesting server data from server the request contains the details of aggregates. We need to handle it from server side and pass along with result and count. Please refer the example code to handle the aggregate action in server side(For URL Adaptor), 
 
public IActionResult UrlDatasource(DataManagerRequest dm) 
        { 
 
            IEnumerable DataSource = order; 
            DataOperations operation = new DataOperations(); 
 
. . . 
            List<string> str = new List<string>(); 
            if (dm.Aggregates != null) 
            { 
                for (var i = 0; i < dm.Aggregates.Count; i++) 
                    str.Add(dm.Aggregates[i].Field); 
            } 
            IEnumerable aggregate = operation.PerformSelect(DataSource, str); 
            int count = DataSource.Cast<Orders>().Count(); 
            if (dm.Skip != 0) 
            { 
                DataSource = operation.PerformSkip(DataSource, dm.Skip);   //Paging 
            } 
            if (dm.Take != 0) 
            { 
                DataSource = operation.PerformTake(DataSource, dm.Take); 
            } 
            return dm.RequiresCounts ? Json(new { result = DataSource, count = count, aggregate = aggregate }) : Json(DataSource); 
        } 
 
Please get back to us, if you need further assistance. 
 
Regards, 
Balaji Sekar. 



MM Masoud Moghaddari January 25, 2020 05:13 AM UTC

Hi there,

You've just repeated the code you sent before!
I have successfully added aggregate from server, my problem is that the aggregate does not change when grid's data is updated. 
For example when I do a search or filter data, I receive grid's data again from server and update grid according to the updated data. But the aggregate won't be updated.
How can I update the aggregate every time I update grid's data?


BS Balaji Sekar Syncfusion Team January 27, 2020 12:22 PM UTC

Hi Masoud, 
 
Thanks for your update. 
 
Based on the received records only WebApi adaptor summarizes the aggregates and displays them in Grid. If we return whole records to the client-end, concept of the load on demand will be declined. Henceforth, based on the current page records the summary were displayed. 
 
However, we can overcome this behavior using the custom adaptors and custom headers of the DataManager. Using the custom headers, required aggregate fields were shared to the server-end. Based on that selective fields with their records were returned to the client as aggregates along with the Items/count which will display the summary for total records. 
 
Please refer the below code example for information. 
 
[Vue] 
<template> 
  <div class="col-lg-12 control-section"> 
    <div> 
      <ejs-grid :dataSource="data" ref="grid" :load="load" :allowPaging="true"> 
        <e-columns> 
. . . 
              <e-column type="Custom" field="Freight" format="C2" :customAggregate="customAggregateFn"  :footerTemplate="sumTemplate"></e-column> 
            </e-columns> 
          </e-aggregate> 
        </e-aggregates> 
      </ejs-grid> 
    </div> 
  </div> 
</template> 
<script> 
import Vue from "vue"; 
import { 
  GridPlugin, 
  Sort, 
  Group, 
  Page, 
  Toolbar, 
  Aggregate 
from "@syncfusion/ej2-vue-grids"; 
import { DataManagerWebApiAdaptor,DataUtil } from "@syncfusion/ej2-data"; 
 
Vue.use(GridPlugin); 
class extendedApiAdaptor extends WebApiAdaptor { 
 
  processResponse( 
        data, ds, query, xhr, request, changes) { 
        var original = super.processResponse.apply(this, arguments); 
            var aggregateData = data.Aggregate; 
            return DataUtil.isNull(original.count) ? original.result : { result: original.result, count: original.count, aggregates: aggregateData }; 
    } 
} 
export default Vue.extend({ 
  data() { 
    return { 
      data: new DataManager({ 
        url: "api/Orders", 
        adaptor: new extendedApiAdaptor(), 
        crossDomain: true 
      }), 
      sumTemplate: function() { 
        return { 
          template: Vue.component("sumTemplate", { 
            template: `<span>Custom: {{data.Custom}}</span>`, 
            data: function() { 
              return { data: { data: {} } }; 
            } 
          }) 
        }; 
      } 
    }; 
  }, 
  methods: { 
    load : function (e) { 
       var aggregatesField = ['Freight'] 
this.$refs.grid.ej2Instances.dataSource.dataSource.headers = []; 
// add the required aggregates value to the header 
this.$refs.grid.ej2Instances.dataSource.dataSource.headers.push({ aggregates: JSON.stringify(aggregatesField) });  
    }, 
         customAggregateFn : function (data) { 
          console.log(data.aggregates); 
// here you will get all the data for the aggregate  
field and calculate your own aggregation 
           return  calculated value 
      } 
  }, 
  provide: { 
    grid: [SortGroupAggregatePageToolbar] 
  } 
}); 
</script> 
<style> 
</style> 

[Controller side] 
   public class OrderController : ApiController 
    { 
        // GET: api/Order 
        public object Get() 
        { 
             
            var queryString = System.Web.HttpContext.Current.Request.QueryString; 
           // get the values passed through request header 
            string agg = Request.Headers.GetValues("aggregates").ToList()[0]; 
            DataOperations ds = new DataOperations(); 
            object aggregate = null; 
            var data = OrdersDetails.GetAllRecords(); 
            if (agg != null) 
            { 
 
                List<string> aggregates = (List<string>)JsonConvert.DeserializeObject(agg, typeof(List<string>)); 
                aggregate = ds.PerformSelect(data, aggregates); 
            } 
             . . . 
           } 
            return new 
            { 
           //return the Aggregates along with result and count 
                Items = data.Skip(skip).Take(take), 
                Count = data.Count(), 
                Aggregate = aggregate 
                 }; 
        } 
 
Please get back to us, If you need further assistance. 
 
Regards, 
Balaji Sekar. 


Loader.
Up arrow icon