Hi, i'm using the autocomplete with an odata endpoint, and I need to a custom filter before send the request to the odata endpoint,
I have the following:
<SfAutoComplete @ref="@autoObj" TValue="string" TItem="GenericAutocompleteResult" cssClass="template" AllowCustom="true"
Placeholder="Ingrese el valor a buscar"
Query="@RemoteDataQuery">
<SfDataManager Headers=@HeaderData Url="@Url" CrossDomain="true" Adaptor="Adaptors.ODataV4Adaptor"></SfDataManager>
<AutoCompleteTemplates TItem="GenericAutocompleteResult">
<ItemTemplate>
<div class="autocomplete-container">
<div class="autocomplete-container-name">@context.Name </div>
<div class="autocomplete-container-email">@(context.Email) </div>
</div>
</ItemTemplate>
</AutoCompleteTemplates>
<AutoCompleteFieldSettings Value="Name"></AutoCompleteFieldSettings>
<AutoCompleteEvents TItem="GenericAutocompleteResult" OnValueSelect="OnItemSelect" ValueChange="OnItemChange" TValue="string"></AutoCompleteEvents>
</SfAutoComplete>
This implementation works fine and send the filter using the name field, I need to add an OR filter using the same value typed by the user but in this case associated to the email field, so the odata endpoint will look using something like: name like 'something' or email like ''
Hi Julito,
Greetings from Syncfusion support.
We are currently working on your requirement , We will update the details in two business days(May 18th, 2022).
Thanks,
Deepak R.
You can achieve your requirement by custom filtering using a filtering events.
Find the code example here:
|
<SfAutoComplete TValue="string" @ref="autoObj" TItem="Country" Placeholder="e.g. Australia" AllowFiltering="true"> <AutoCompleteFieldSettings Text="Name" Value="Code"></AutoCompleteFieldSettings> <AutoCompleteTemplates TItem="Country"> <ItemTemplate> <div class="autocomplete-container"> <div class="autocomplete-container-name">@context.Name </div> <div class="autocomplete-container-email">@(context.Code) </div> </div> </ItemTemplate> </AutoCompleteTemplates> <AutoCompleteEvents TValue="string" TItem="Country" Filtering="OnFilter"></AutoCompleteEvents> </SfAutoComplete>
@code {
SfAutoComplete<string, Country> autoObj { get; set; } public Query query;
public class Country { public string Name { get; set; }
public string Code { get; set; } }
List<Country> CountryData = new List<Country> { new Country() { Name = "Australia", Code = "AU" }, new Country() { Name = "Bermuda", Code = "BM" }, new Country() { Name = "Canada", Code = "CA" }, new Country() { Name = "Cameroon", Code = "CM" }, new Country() { Name = "Denmark", Code = "DK" } };
private async Task OnFilter(FilteringEventArgs args) { args.PreventDefaultAction = true;
WhereFilter nameFilter = new WhereFilter() { Field = "Name", value = args.Text, Operator = "startswith", IgnoreCase = true }; WhereFilter codeFilter = new WhereFilter() { Field = "Code", value = args.Text, Operator = "startswith", IgnoreCase = true }; query = new Query().Where(nameFilter.Or(codeFilter)); query = !string.IsNullOrEmpty(args.Text) ? query : new Query();
await autoObj.FilterAsync(CountryData, query); } } |
To know more about custom filtering. Please refer to the below documentation link: https://blazor.syncfusion.com/documentation/autocomplete/filtering#custom-filtering
We have created the sample and attached the attachment.
Hi all, thanks for the answer, however I have a odata endpoint, and your example uses a local list, how I can use this with the odata endpoint?
await
autoObj.FilterAsync(CountryData, query);
the above line uses the CountryData (local data)
Thanks,
You can use the DataSource instead of the local data variable in the FilterAsync method call.
Find the code example here:
|
private async Task OnFilter(FilteringEventArgs args) { args.PreventDefaultAction = true;
WhereFilter nameFilter = new WhereFilter() { Field = "Name", value = args.Text, Operator = "startswith", IgnoreCase = true }; WhereFilter codeFilter = new WhereFilter() { Field = "Code", value = args.Text, Operator = "startswith", IgnoreCase = true }; query = new Query().Where(nameFilter.Or(codeFilter)); query = !string.IsNullOrEmpty(args.Text) ? query : new Query(); await autoObj.FilterAsync(this.autoObj.DataSource, query); } |
Thanks for the answer, now it sends the two filters, but with this I'm getting the following error:
System.TypeInitializationException: The type initializer for 'Microsoft.AspNetCore.OData.Query.Expressions.ExpressionBinderBase' threw an exception. System.InvalidOperationException: Sequence contains more than one matching element
The odata request is: https://localhost:44386/odata/Users?$count=true&$filter=(contains(tolower(Name),%27testing%27))%20or%20(contains(tolower(Email),%27testing%27))&$select=Id,Name,Email&$skip=0&$top=30
The odata configuration is:
services
.AddOData(opt => opt.AddModel("odata", GetEdmModel())
.Filter()
.Count()
.Select()
.SetMaxTop(100));
Regards,
We suspect that the sample level multiple queries replicate the reported issue in your application. We suggest you use the predicate to resolve the issue.
Please find the modified filtering code
|
private async Task OnFilter(FilteringEventArgs args) { args.PreventDefaultAction = true; var Col1Pre = new WhereFilter(); var predicate = new List<WhereFilter>(); predicate.Add(new WhereFilter() { Condition = "or", Field = "Name", value = args.Text, Operator = "startswith", IgnoreCase = true }); predicate.Add(new WhereFilter() { Condition = "or", Field = "Code", value = args.Text, Operator = "startswith", IgnoreCase = true }); Col1Pre = WhereFilter.Or(predicate); var query = new Query().Where(Col1Pre); await autoObj.FilterAsync(this.autoObj.DataSource, query); } |
If you still have faced the same issue, please provide detailed information with the sample to replicate the issue from our end to update an exact solution as early as possible.
Also, please provide mentioned sends the two filters: is $filter query present two times in a single request or request sent two times.
Hello, thanks it works.
Thanks for letting us know that the given solution works. Please get back to us if you need any further assistance.
Regards,
Ranjani