<EjsAutoComplete TValue="string" @bind-Value="model.TestProperty" Placeholder="Select a customer" Query="@Query" MinLength="2">
<EjsDataManager Url="https://services.odata.org/V4/Northwind/Northwind.svc/" Adaptor="Adaptors.ODataV4Adaptor" CrossDomain=true></EjsDataManager>
<AutoCompleteFieldSettings Value="ContactName"></AutoCompleteFieldSettings>
</EjsAutoComplete> |
<EditForm EditContext="@editContext">
<DataAnnotationsValidator />
<div class="form-group">
<EjsAutoComplete TValue="string" @bind-Value="model.TestProperty" Placeholder="Select a customer" Query="@Query" MinLength="2">
<EjsDataManager Url="https://services.odata.org/V4/Northwind/Northwind.svc/" Adaptor="Adaptors.ODataV4Adaptor" CrossDomain=true></EjsDataManager>
<AutoCompleteFieldSettings Value="ContactName"></AutoCompleteFieldSettings>
</EjsAutoComplete>
<ValidationMessage For="()=>model.TestProperty" />
</div>
<EjsButton IsPrimary="true" HtmlAttributes="@(new Dictionary<string,object>{ { "type", "submit"} })">Save</EjsButton>
</EditForm>
|
|
I really would welcome debounce or delay option for SfAutoComplete. All similar components have this option (Telerik or HxAutosuggest | HAVIT Blazor - Free Bootstrap 5 components). Some web APIs have paid access based on number of calls which are depleted by unnecessary calls from SfAutoComplete.
Is there some way to achieve this behavior with current SfAutoComplete version? Based on its events maybe?
Thank you for your support!
Zdenek
Hi Rodrigo,
you can refer to the debounce concept as mentioned below in Autocomplete filtering event. Please refer to the sample for more details.
Sample Link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/BlazorServer-2011657524
<SfAutoComplete @ref="@autoComplete" TValue="Countries" TItem="Countries" PopupWidth="@PopupWidth" PopupHeight="@PopupHeight" FloatLabelType='@FloatLabelType.Never' AllowFiltering="true" ShowPopupButton="true" ShowClearButton="true" CssClass="e-small" @bind-Value="Value" AllowCustom="@AllowCustom"> <SfDataManager @ref="datamanager" AdaptorInstance="@typeof(CountryCustomAdaptor)" Adaptor="Adaptors.CustomAdaptor"></SfDataManager>
@if (MultiColumn) { <AutoCompleteTemplates TItem="Countries"> <HeaderTemplate> <table> <tr> @foreach (ColumnDetails field in DataContext.Columns) { <th><div class="e-text" style="@($"width:{field.Width}px;")">@field.Text</div></th> } </tr> </table> </HeaderTemplate> <ItemTemplate> <table> <tbody> <tr> @foreach (ColumnDetails field in DataContext.Columns) { <td> <div class="e-text-left" style="@($"width:{field.Width}px;")" title="@field.Name"> @if (field.Name == "FirstName") { @context.CountryName } else if (field.Name == "ID") { @context.CountryId } else if (field.Name == "LastName") { @context.CountryName} </div> </td> } </tr> </tbody> </table> </ItemTemplate> </AutoCompleteTemplates>} <AutoCompleteFieldSettings Text="CountryName"></AutoCompleteFieldSettings> <AutoCompleteEvents TValue="Countries" TItem="Countries" Blur="FocusOut" Filtering="onInputDebounced"></AutoCompleteEvents> </SfAutoComplete>
SfDataManager datamanager; public async Task onFiltering(Syncfusion.Blazor.DropDowns.FilteringEventArgs args) { args.PreventDefaultAction = true; var query = new Query();
if (args.Text != "") { query = new Query().Where(new WhereFilter() { Field = "CountryName", value = args.Text, Operator = "Contains", IgnoreCase = true }); } var data = await this.datamanager.ExecuteQuery<Countries>(query); var resultData = new List<Countries>(); var dataResult = (data == null) ? new List<object>() : data; resultData = (dataResult as IEnumerable)?.Cast<Countries>()?.ToList(); await this.autoComplete.Filter(resultData, query); } Action<Syncfusion.Blazor.DropDowns.FilteringEventArgs> onInputDebounced; protected override async Task OnInitializedAsync() { onInputDebounced = DebounceEvent<Syncfusion.Blazor.DropDowns.FilteringEventArgs>(async e => await this.onFiltering(e), TimeSpan.FromMilliseconds(1000)); await base.OnInitializedAsync(); } Action<T> DebounceEvent<T>(Action<T> action, TimeSpan interval) { return Debounce<T>(arg => { InvokeAsync(() => { action(arg); StateHasChanged(); }); }, interval); } Action<T> Debounce<T>(Action<T> action, TimeSpan interval) { if (action == null) throw new ArgumentNullException(nameof(action));
var last = 0; return arg => { var current = System.Threading.Interlocked.Increment(ref last); Task.Delay(interval).ContinueWith(task => { if (current == last) { action(arg); } }); }; } |
Regards,
Udhaya Kumar D