Hi,
I'd like to implement custom filtering based on rows of child grid.
The attached image shows the layout of my grid.
My questions are as follows:
Q1. How to filter the 'company' rows based on the 'customers' who sold more than 100 items?
For eg: After I click 'Customers Selling > 100 Items 4 months' button, I only should show 'Company1' row with 'Customer12' row in its child grid.
Q2. If I want to clear the filter, I should be able to do so as well. (How do I do that in a button? Maybe show active button when used? I'd like your opinion on that.)
Q3. To fetch these data, the server needs to do some expensive calculations, so how can I reuse the dataSource when the customer navigates through different pages instead of doing full fetch from controller while navigating to different pages?
My code looks like this:
The data models:
public class CompanyData{ public string CompanyId { get; set; } public int CustomersCount { get; set; } public List<CompanyCustomer> Customers { get; set; }}public class CompanyCustomer{ public string CustomerId { get; set; } public string CustomerName { get; set; } public int TotalSoldItems { get; set; }}
The grid containing the child grid as well:
@(Html.Kendo() .Grid<ProjectName.Models.CompanyData>() .Name("CompanyDataSummary") .Columns(columns => { columns.Bound(e => e.CompanyId).Title("Company Name").Width(60); columns.Bound(e => e.CustomersCount).Title("Customers Count").Width(50); }) .Sortable() .Pageable() .Scrollable() .Filterable() .ClientDetailTemplateId("CustomerDetails") .HtmlAttributes(new { style = "height:450px;" }) .AutoBind(false) // Don't load the data yet because I'll need to supply parameters for the fetch .ToolBar(toolbar => toolbar.ClientTemplateId("CustomerDetailsToolBarTemplate")) .DataSource(dataSource => dataSource .Ajax() .ServerOperation(true) .PageSize(10) .Model(model => { model.Id("CompanyId"); model.Field("CustomerCount", typeof(int)); }) .Read(read => read.Action("GetCompanyDataAsync", "Reporting").Data("passArguments")) ) .Events(events => events.DataBound("dataBound").DetailExpand("onExpand")))<script id="CustomerDetails" type="text/kendo-tmpl"> @(Html.Kendo() .Grid<ProjectName.Models.CompanyCustomer>() .Name("CustomerDetails_#=CompanyId#") .Columns(columns => { columns.Bound(o => o.CustomerName).Title("Customer Id").Width(60); columns.Bound(o => o.TotalSoldItems).Title("Total Sold Items").Width(60); }) .DataSource(dataSource => dataSource .Ajax() .PageSize(10) .Model(model => { model.Id("CustomerId"); model.Field("CustomerName", typeof(string)); model.Field("TotalSoldItems", typeof(int)); }) .ServerOperation(false) ) .AutoBind(false) .Pageable() .Sortable() .ToClientTemplate() )</script>
The toolbar template:
<script id="CustomerDetailsToolBarTemplate" type="text/kendo-tmpl"> <div class="inlineBtn"> @(Html.Kendo().Button() .Name("allYTDCustomers") .HtmlAttributes(new { type = "button", @class = "k-button" }) .Content("All Customers YTD") .Events(e => e.Click("allYTDCustomersFetch")) .ToClientTemplate() ) </div> <div class="inlineBtn"> @(Html.Kendo().Button() .Name("CustomersGT100ItemsYTD") .HtmlAttributes(new { type = "button", @class = "k-button" }) .Content("Customer selling > 100 items YTD") .Events(e=>e.Click("CustomersGT100ItemsYTDFetch")) .ToClientTemplate() ) </div> <div class="inlineBtn"> @(Html.Kendo().Button() .Name("allCustomersLast4Mths") .HtmlAttributes(new { type = "button", @class = "k-button" }) .Content("Customers selling > 100 items last 4 months") .Events(e => e.Click("allCustomersLast4MthsFetch")) .ToClientTemplate() ) </div></script>
The script that loads the child grid and the handler for toolbar button:
<script> function onExpand(e) { var companyId = e.sender.dataItem(e.masterRow).CompanyId; var customerData = e.sender.dataItem(e.masterRow).Customers; //Initialize the child grid as well var childGridName = "#" + "CustomerDetails_" + companyId; var childGrid = $(childGridName).data("kendoGrid"); if (childGrid !== undefined) { childGrid.dataSource.data(customerData); } } //Example function: function CustomersGT100ItemsYTDFetch() { // How to filter the company rows based on the customers who sold more than 100 items? // For eg: After I click that button, I only should show Company1 row with Customer12 in its child grid. }</script>
The controller action method:
public async Task<ActionResult> GetCompanyDataAsync([DataSourceRequest] DataSourceRequest request, DateTime start, DateTime end){ IEnumerable<CompanyData> companySummary = await _reporting.GetCompanyReportInformationAsync(start, end); return Json(companySummary.ToDataSourceResult(request));}