Use MultiSelect as Filter in Grids
Environment
Product | Progress® Telerik® UI MultiSelect for UI for ASP.NET Core |
Description
How can I use a Telerik UI for ASP.NET Core MultiSelect as a filter in the Telerik UI for ASP.NET Core Grid?
Solution
- Configure the
Grid Column Filterable UI API
and pass themultiselectFilter()
JavaScript function as a parameter. - Implement the JavaScript function to disable the built-in filtration, define the MultiSelect
dataSource
, and extend the Grid’sdataSource filter()
method. - Define the
removeFiltersForField()
script to establish custom filtering logic. - n the Controller, implement the filtering logic with the
GetMultiSelectFilter()
method and update theRead
Action to support the MultiSelect filtering.
@(Html.Kendo().Grid<ViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(e => e.ID);
columns.Bound(e => e.Tags).Filterable(filterable => filterable.Extra(false)
.Messages(m=> m.Info("Show items with value that contains"))
.UI("multiselectFilter")
)
.ClientTemplate("#:Tags.join(',')#");
})
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("Read", "Home"))
)
)
@addTagHelper *, Kendo.Mvc
<kendo-grid name="grid" >
<datasource type="DataSourceTagHelperType.Ajax">
<transport>
<read url="@Url.Action("Read", "Home")" />
</transport>
</datasource>
<columns>
<column field="ID" title="Id" />
<column field="Tags" title="Tags" template="#:Tags.join(',')#" >
<filterable extra="false" filter-ui-handler="multiselectFilter">
<messages info="Show items with value that contains" />
</filterable>
</column>
</columns>
<filterable enabled="true" />
</kendo-grid>
<script>
function multiselectFilter(element) {
element.removeAttr("data-bind");
var dataSource = $("#grid").data("kendoGrid").dataSource;
var multiselect = element.kendoMultiSelect({
dataSource: ["Tag1", "Tag2", "Tag3"]
}).data("kendoMultiSelect");
var form = element.closest("form");
var popup = form.data("kendoPopup");
form.find("[data-role=dropdownlist]").remove();
form.find("[type='submit']").click(function (e) {
e.preventDefault();
e.stopPropagation();
var filter = dataSource.filter() || { logic: "and", filters: [] };
var tags = multiselect.value();
removeFiltersForField(filter, "Tags");
if (tags.length) {
filter.filters = filter.filters.concat($.map(tags, function (value) {
return {
operator: "eq",
value: value,
field: "Tags"
}
}));
}
dataSource.filter(filter);
popup.close();
}).end()
.find("[type='reset']").click(function () {
multiselect.value([]);
});
}
function removeFiltersForField(expression, field) {
if (expression.filters) {
expression.filters = $.grep(expression.filters, function (filter) {
removeFiltersForField(filter, field);
if (filter.filters) {
return filter.filters.length;
} else {
return filter.field != field;
}
});
}
}
</script>
static List<ViewModel> data;
static HomeController()
{
data = new List<ViewModel>()
{
new ViewModel
{
ID = 1,
Tags = new List<string>(){"Tag1", "Tag2"}
},
new ViewModel
{
ID = 2,
Tags = new List<string>(){"Tag2", "Tag3"}
},
new ViewModel
{
ID = 3,
Tags = new List<string>(){"Tag3"}
}
};
}
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
private void GetMultiSelectFilter(IList<IFilterDescriptor> filters, List<object> result, String member)
{
for (int i = filters.Count - 1; i >= 0; i--)
{
var filter = filters[i];
if (filter is CompositeFilterDescriptor)
{
GetMultiSelectFilter(((CompositeFilterDescriptor)filter).FilterDescriptors, result, member);
}
else if (((Kendo.Mvc.FilterDescriptor)filter).Member == member)
{
filters.Remove(filter);
result.Add(((Kendo.Mvc.FilterDescriptor)filter).Value);
}
}
}
public ActionResult Read([DataSourceRequest] DataSourceRequest request)
{
List<object> tagFilters = new List<object>();
GetMultiSelectFilter(request.Filters, tagFilters, "Tags");
IQueryable<ViewModel> result = data.AsQueryable();
if (tagFilters.Any())
{
result = result.Where(d => d.Tags.Any(t => tagFilters.Contains(t)));
}
return Json(result.ToDataSourceResult(request));
}
For the complete implementation on how to use a Telerik UI for ASP.NET Core MultiSelect as a filter in the Telerik UI for ASP.NET Core Grid, refer to this GitHub project.
More ASP.NET Core Grid Resources
More ASP.NET Core MultiSelect Resources
See Also
- Client-Side API Reference of the Grid for ASP.NET Core
- Server-Side API Reference of the Grid for ASP.NET Core
- Client-Side API Reference of the MultiSelect for ASP.NET Core
- Server-Side API Reference of the MultiSelect for ASP.NET Core
- Telerik UI for ASP.NET Core Breaking Changes
- Telerik UI for ASP.NET Core Knowledge Base