Hello,
I have multi-column combo in my project. Filtering works but only on one column. I want to be able filter on any column. My relevant code blocks are shown below.
<SfComboBox @bind-Value="@sal.ProductId"
AllowFiltering="true"
TValue="int?"
TItem="ProductLookupForSales"
DebounceDelay="300"
EnableVirtualization="true"
Query="@RemoteProductDataQuery"
FilterType="Syncfusion.Blazor.DropDowns.FilterType.Contains"
PopupWidth="560px"
Width="130px"
CssClass="radius-0 e-small shadow-none e-multi-column"
Placeholder="Select any product">
<SfDataManager Url="@ProductLookupUri"
Offline="true"
CrossDomain="true"
Adaptor="Syncfusion.Blazor.Adaptors.WebApiAdaptor"></SfDataManager>
<ComboBoxTemplates TItem="ProductLookupForSales">
<HeaderTemplate>
<table><tr><th class="text-start">Ref</th><th class="text-start" width="250px">Product Name</th><th class="text-end">Price</th><th class="text-end">Qty</th></tr></table>
</HeaderTemplate>
<ItemTemplate>
<table><tbody><tr><td class="e-text-start">@((context as ProductLookupForSales).ProductCode)</td><td width="220px">@((context as ProductLookupForSales).ProductName)</td><td class="text-end">@((context as ProductLookupForSales).SalesPrice.ToString("n2"))</td><td class="text-end">@((context as ProductLookupForSales).InStock.ToString("n2"))</td></tr> </tbody></table>
</ItemTemplate>
</ComboBoxTemplates>
<ComboBoxFieldSettings
Text="ProductCode"
Value="Id"></ComboBoxFieldSettings>
<ComboBoxEvents
TValue="int?"
TItem="ProductLookupForSales"
OnValueSelect="@OnValueSelecthandler" ></ComboBoxEvents>
</SfComboBox>
Model:
{
public class ProductLookupForSales
{
public int Id { get; set; }
public string ProductCode { get; set; } = string.Empty;
public string ProductName { get; set; } = string.Empty;
public decimal SalesPrice { get; set; }
public double InStock { get; set; }
)
Query:
public Query RemoteProductDataQuery = new Query().Select(new List<string> { "ProductCode", "ProductName", "SalesPrice", "Barcode", "InStock" }).Take(6).RequiresCount();
Thank you in advance for your usual coperation
Paul
Hi Paul,
Thank you for reaching out to us. You can achieve multiple column(field) filtering by passing the List of predicates to the And or Or methods of WhereFilters. Please find the code snippet and sample attached below for your reference.
<SfComboBox @ref="comboObj" AllowFiltering="true" TValue="Moc" TItem="Moc" DataSource="@data" CssClass="e-multi-column"> <ComboBoxFieldSettings Text="Text" Value="ID"></ComboBoxFieldSettings> <ComboBoxEvents Filtering="OnFiltering" TValue="Moc" TItem="Moc"></ComboBoxEvents> <ComboBoxTemplates TItem="Moc"> <HeaderTemplate> <table><tr><th>ID</th><th>Text</th></tr></table> </HeaderTemplate> <ItemTemplate Context="itemContext"> <table> <tbody> <tr> @if (!string.IsNullOrEmpty((itemContext as Moc).ID)) { <td><span>@((itemContext as Moc).ID)</span></td> <td><span>@((itemContext as Moc).Text)</span></td> } </tr> </tbody> </table> </ItemTemplate> </ComboBoxTemplates> </SfComboBox>
@code { SfComboBox<Moc, Moc> comboObj;
public Query query { get; set; } public class Moc { public string ID { get; set; } public string Text { get; set; } } List<Moc> data = new List<Moc> { new Moc() { ID= "12H", Text= "American Football" }, new Moc() { ID= "14G", Text= "Badminton" }, new Moc() { ID= "17F", Text= "Basketball" } }; public async Task OnFiltering(Syncfusion.Blazor.DropDowns.FilteringEventArgs args) { args.PreventDefaultAction = true; var orWhere = WhereFilter.Or(new List<WhereFilter> { new WhereFilter() { Field = "Text", Operator = "contains", value = args.Text, IgnoreCase = true }, new WhereFilter() { Field = "ID", Operator = "contains", value = args.Text, IgnoreCase = true } }); var query = new Query().Where(orWhere); query = !string.IsNullOrEmpty(args.Text) ? query : new Query(); await comboObj.FilterAsync(data, query); } } |
Documentation Reference: https://blazor.syncfusion.com/documentation/combobox/filtering#multi-column-filtering
Regards,
Priyanka K
Thank you very much for the response.
I thought multi-column filtering is supported when using SfDataManager.
Regards,
Paul Aziz
Hi Paul,
Yes, multi-column filtering using predicates within the Filtering event is supported with both local and remote datasource.
Here’s an example implementation based on your code snippet:
public async Task OnFiltering(Syncfusion.Blazor.DropDowns.FilteringEventArgs args)
{
args.PreventDefaultAction = true;
var orWhere = WhereFilter.Or(new List<WhereFilter> {
new WhereFilter() { Field = "ProductCode", Operator = "contains", value = args.Text, IgnoreCase = true },
new WhereFilter() { Field = "ProductName", Operator = "contains", value = args.Text, IgnoreCase = true },
new WhereFilter() { Field = "SalesPrice", Operator = "contains", value = args.Text, IgnoreCase = true },
new WhereFilter() { Field = "InStock", Operator = "contains", value = args.Text, IgnoreCase = true }
});
var query = new Query().Where(orWhere);
query = !string.IsNullOrEmpty(args.Text) ? query : new Query();
await comboObj.FilterAsync(data, query);
}Regards,
Priyanka K
Thanks so much for the assistance. I am most grateful
Regards,
Paul
Hi Paul,
You are welcome. Please feel free to contact us if you have any further questions.
Regards,
Priyanka K
Hi Priyanka,
I cannot figure how set datasource for FilterAsync() which takes two parameters because in sfDataManger, Url is passed for data retrieval.
Regards,
Paul A
Hi Paul,
Thank you for your query!
To use FilterAsync() with ComboBox when your data is retrieved via DataManager, you can still pass the ComboBox instance reference and the query object to the method. The key is to ensure that the DataSource property of the ComboBox is correctly set to the DataManager instance.
Here’s a simplified example:
<SfComboBox @ref="comboObj" AllowFiltering="true" TValue="Moc" TItem="Moc" DataSource="@data" CssClass="e-multi-column">
<ComboBoxFieldSettings Text="Text" Value="ID"></ComboBoxFieldSettings>
<ComboBoxEvents Filtering="OnFiltering" TValue="Moc" TItem="Moc"></ComboBoxEvents>
<ComboBoxTemplates TItem="Moc">
<HeaderTemplate>
<table><tr><th>ID</th><th>Text</th></tr></table>
</HeaderTemplate>
<ItemTemplate Context="itemContext">
<table>
<tbody>
<tr>
@if (!string.IsNullOrEmpty((itemContext as Moc).ID))
{
<td><span>@((itemContext as Moc).ID)</span></td>
<td><span>@((itemContext as Moc).Text)</span></td>
}
</tr>
</tbody>
</table>
</ItemTemplate>
</ComboBoxTemplates>
</SfComboBox>
@code {
SfComboBox<Moc, Moc> comboObj;
public Query query { get; set; }
public class Moc
{
public string ID { get; set; }
public string Text { get; set; }
}
List<Moc> data = new List<Moc>
{
new Moc() { ID= "12H", Text= "American Football" },
new Moc() { ID= "14G", Text= "Badminton" },
new Moc() { ID= "17F", Text= "Basketball" }
};
public async Task OnFiltering(Syncfusion.Blazor.DropDowns.FilteringEventArgs args)
{
args.PreventDefaultAction = true;
var orWhere = WhereFilter.Or(new List<WhereFilter> {
new WhereFilter() { Field = "Text", Operator = "contains", value = args.Text, IgnoreCase = true },
new WhereFilter() { Field = "ID", Operator = "contains", value = args.Text, IgnoreCase = true }
});
var query = new Query().Where(orWhere);
query = !string.IsNullOrEmpty(args.Text) ? query : new Query();
await comboObj.FilterAsync(comboObj.DataSource, query);
}
} |
This approach works for both local data and remote data via DataManager. Let us know if you need help adapting this to your specific API or data structure!
Regards,
Priyanka K
Hi Priyanka,
Thanks for the reply. I am indeed grateful the assistance
Regards,
Paul Aziz
Hi Paul
Glad to know that the provided solution helped. Please get back to us for assistance in the future.
Regards,
Shereen
thanks for help!
Hi,
I followed your guidance to implement multi-column filtering. But it does not seem to work. It throws error in
OnActionFailure event handler which logs error in browser console as show below.
The error is:
Beging data fetching: Syncfusion.Blazor.Data.Query
blazor.webassembly.js:1 System.ArgumentNullException: Value cannot be null. (Parameter 'source')
blazor.webassembly.js:1 at System.Linq.ThrowHelper.ThrowArgumentNullException(ExceptionArgument argument)
blazor.webassembly.js:1 at System.Linq.Enumerable.Cast[ProductLookupForSales](IEnumerable source)
blazor.webassembly.js:1 at Syncfusion.Blazor.Data.BlazorAdaptor.<ProcessResponse>d__8`1[[SmartAccounts.Lookups.ProductLookupForSales, SmartAccounts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
blazor.webassembly.js:1 at Syncfusion.Blazor.DataManager.<ExecuteQuery>d__156`1[[SmartAccounts.Lookups.ProductLookupForSales, SmartAccounts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
blazor.webassembly.js:1 at Syncfusion.Blazor.DataManager.<ExecuteQuery>d__154`1[[SmartAccounts.Lookups.ProductLookupForSales, SmartAccounts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
blazor.webassembly.js:1 at Syncfusion.Blazor.MultiColumnComboBox.SfMultiColumnComboBox`2.<SetGridDataAsync>d__247[[System.Nullable`1[[System.Int32, System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], System.Private.CoreLib, Version=9.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[SmartAccounts.Lookups.ProductLookupForSales, SmartAccounts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]].MoveNext()
My relevant code snippets are show below. The blazor component:
<SfMultiColumnComboBox @bind-Value="@sal.ProductId"
@ref="sal.ProductComboRef"
AllowFiltering="true"
TValue="int?"
FilterType="Syncfusion.Blazor.MultiColumnComboBox.FilterType.Contains"
TItem="ProductLookupForSales"
Query="@ProductDataQuery"
EnableVirtualization="true"
DebounceDelay="300"
PopupWidth="575px"
PopupHeight="300px"
CssClass="radius-0 shadow-none e-small"
Width="100%"
Filtering="@onFiltering1"
EnableAltRow="true"
ValueField="Id"
TextField="ProductCode"
ValueChange="OnValueChange"
OnActionBegin="@OnActionBeginhandler"
OnActionFailure="@OnActionFailurehandler"
Placeholder="Please select">
<SfDataManager
Url="@ProductLookupUri"
Offline="true"
Adaptor="Syncfusion.Blazor.Adaptors.WebApiAdaptor">
</SfDataManager>
<MultiColumnComboboxColumns>
<MultiColumnComboboxColumn Field="ProductCode" Header="Product Ref" Width="105"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="ProductName" Header="Product Name" Width="250"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="SalesPrice" Format="n2" Header="Unit Price" Width="100" TextAlign="TextAlign.Right"></MultiColumnComboboxColumn>
<MultiColumnComboboxColumn Field="InStock" Header="In Stock" Format="n2" TextAlign="TextAlign.Right" Width="100"></MultiColumnComboboxColumn>
</MultiColumnComboboxColumns>
</SfMultiColumnComboBox>
Code behind:
public async Task onFiltering1(Syncfusion.Blazor.MultiColumnComboBox.FilteringEventArgs args)
{
args.PreventDefaultAction = true;
var orWhere = WhereFilter.Or(new List<WhereFilter>
{
new WhereFilter() { Field = "ProductCode", Operator = "contains", value = args.Text, IgnoreCase = true },
new WhereFilter() { Field = "ProductName", Operator = "contains", value = args.Text, IgnoreCase = true },
new WhereFilter() { Field = "Barcode", Operator = "contains", value = args.Text, IgnoreCase = true },
new WhereFilter() { Field = "SalesPrice", Operator = "contains", value = args.Text, IgnoreCase = true }
});
var query = new Query().Where(orWhere);
query = !string.IsNullOrEmpty(args.Text) ? query : new Query();
await currentDatailedOrderItem.ProductComboRef.FilterAsync(currentDatailedOrderItem.ProductComboRef.DataSource, query);
}
public Query ProductDataQuery = new Query().Select(new List<string> { "ProductCode", "ProductName", "SalesPrice", "Barcode", "InStock" }).Take(6).RequiresCount();
public void OnActionBeginhandler(Syncfusion.Blazor.MultiColumnComboBox.ActionBeginEventArgs args)
{
// Here, you can customize your code.
Console.WriteLine($"Beging data fetching: {args.Query}");
}
Thanks in advance for the assistance.
Regards,
Paul Aziz
Hi Paul,
Thank you for your patience. We have investigated the multicolumn ComboBox filtering issue and identified that the RequiresCount parameter was missing in the sample code. This omission is causing an exception at the source level within the SetGridDataSource method. To resolve this, please ensure that the query is correctly passed inside the CustomFiltering method. Kindly refer to the updated code snippet and sample provided below for your reference:
async Task CustomFiltering(Syncfusion.Blazor.MultiColumnComboBox.FilteringEventArgs args)
{
args.PreventDefaultAction = true;
if (string.IsNullOrEmpty(args.Text))
{
await MultiColumnObj.FilterAsync(new List<Orders>());
return;
}
var predicate = new List<WhereFilter>
{
new WhereFilter { Condition = "or", Field = "CustomerID", value = args.Text, Operator = "contains", IgnoreAccent = true, IgnoreCase = true },
new WhereFilter { Condition = "or", Field = "ShipCountry", value = args.Text, Operator = "contains", IgnoreAccent = true, IgnoreCase = true }
};
var query = new Query().Where(WhereFilter.Or(predicate)).RequiresCount();
await MultiColumnObj.FilterAsync(MultiColumnObj.DataSource, query);
}
Please let us know if you need any further assistance or clarification.
Regards,
Priyanka K
Hi Paul,
Please find the sample attached below for your reference.
https://www.syncfusion.com/downloads/support/directtrac/general/ze/MultiColumnComboBox
Regards,
Priyanka K
Hello Priyanka,
Thanks for assistance.
I will apply your solution and get back to you with the feedback as soon as possible.
I am very grateful for your help
Regards,
Paul Aziz
Hi Paul,
Thank you for the update. Please get back to us for assistance in the future.
Regards,
Shereen
Hi Priyanka,
Your solution worked like magic.
I am eternally grateful for assistance. In fact, words cannot express my appreciation.
Thanks so much.
Best regards,
Paul Aziz
Hi Paul,
Thank you for the update. We are glad to hear that the issue has been resolved on your end. Please feel free to reach out to us if you need any further assistance.
Regards,
Priyanka K