Skip to content

Instantly share code, notes, and snippets.

@geistchevalier
Last active January 17, 2025 07:48
Show Gist options
  • Save geistchevalier/f1120f05111472175d8b2be9130517be to your computer and use it in GitHub Desktop.
Save geistchevalier/f1120f05111472175d8b2be9130517be to your computer and use it in GitHub Desktop.
Extract individual DataSourceRequest.Filters in Kendo.Mvc on server side, and rearrange the filter logic
using Kendo.Mvc;
///
/// I needed to modify my incoming kendoGrid dataSourceRequest filters to append additional columns that is not bounded on the kendoGrid,
/// to do that I needed to extract all the [FilterDescriptor] for the columns,
/// this is to correct the arrangement of the [CompositeFilterDescriptor] as I needed it
///
/// for some reason when adding it via JS on the client side, logically I got:
/// {
/// | // Group A | | // Group B |
/// (ColumnAACondition) AND (ColumnBACondition) AND (ColumnBBCondition)
/// }
///
/// and I wanted it to be like the following instead:
///
/// {
/// | // Group A | | // Group B |
/// (ColumnAACondition) AND {(ColumnBACondition) OR (ColumnBBCondition)}
/// }
///
/// the encompasing curly braces for BA & BB and the curly brace on line 16 & 19, is a [CompositeFilterDescriptor],
/// it has the property of LogicalOperator to determine if the descriptors within it operate as an OR or AND logic gate.
///
/// The following method extracts the nested [CompositeFilterDescriptor] & [FilterDescriptor] into a single List of filters
///
public List<FilterDescriptor> filterSeparator(IEnumerable<IFilterDescriptor> filters)
{
List<FilterDescriptor> _descriptors = new List<FilterDescriptor>();
if (filters.Any())
{
foreach (var filter in filters)
{
var descriptor = filter as FilterDescriptor;
if (descriptor != null)
{
_descriptors.Add(descriptor);
}
else if (filter is CompositeFilterDescriptor)
{
var _r = filterSeparator(((CompositeFilterDescriptor)filter).FilterDescriptors);
if (_r.Any())
{
_descriptors.AddRange(_r);
}
}
}
}
return _descriptors;
}
/// I then used another method to sort via FilterDescriptor.Member property to get the column name for said filter.
/// I then group them as I wanted them into a [CompositeFilterDescriptor] for each group
/// And then I placed all those [CompositeFilterDescriptor] into a final [CompositeFilterDescriptor] like the following
///
/// {
/// (columnAACondition) AND {(columnBAcondition) OR (columnBBcondition)} AND {( {(columnCAcondition) OR (columnCBcondition)} AND columnCCcondition)}
/// }
///
/// And finally it's simple to replace the [DataSourceRequest] filters as following
public IActionResult DummyAction([DataSourceRequest]DataSourceRequest dsr)
{
var newFilters = filterSeparator(dsr.Filters); // output result: List<FilterDescriptor>
var rearrangedFilters = filterRearranger(newFilters); // output result: CompositeFilterDescriptor
dsr.Filters.Clear();
dsr.Filters.Add(rearrangedFilters);
// ...
var table = callDataSource();
var data = table.ToDataSourceResultAsync(dsr);
// ...
return Json(data);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment