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
SIGN IN To post a reply.
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,
Attachment: grid_68feb500.zip
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 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
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?
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 { DataManager, WebApiAdaptor,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: [Sort, Group, Aggregate, Page, Toolbar]
}
});
</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.
SIGN IN To post a reply.
- 5 Replies
- 3 Participants
-
MM Masoud Moghaddari
- Jan 13, 2020 01:07 PM UTC
- Jan 27, 2020 12:22 PM UTC