Hello,
I'm trying to use Autocomplete as a search box.
The requirement is two parts:
(a) If the input to the search box is empty, display suggestions from local data
(b) if the input to the search box is at least one character, then display suggestions from remote data via ODatav4 adaptor.
Currently I can succeed to achieve both (a) and (b) separately using the documentation.
But it seems to work only exclusively as (a) or (b).
I'm having trouble alternating between the two dynamically.
For example, even if I provide the input to the FilterAsync function as my local data, the component still seems to retrieve from the remote data anyway.
Ideally I need a conditional statement to adjust the data source dynamically depending on the input.
Do you have any idea
Hi Sorin,
You can achieve your requirement by using ExecuteQuery in our data manager. Find the below code example to achieve your requirement
|
<SfDataManager @ref=DM Url="https://js.syncfusion.com/demos/ejservices/Wcf/Northwind.svc/Orders" CrossDomain="true"></SfDataManager>
<SfAutoComplete @ref="autoObj" TValue="string" TItem="Order" Placeholder="e.g. Australia" ShowPopupButton=true DataSource="@Countries" PopupHeight="130px"> <AutoCompleteFieldSettings Text="CustomerID" Value="EmployeeID"></AutoCompleteFieldSettings> <AutoCompleteEvents TValue="string" TItem="Order" Filtering="OnFilter"></AutoCompleteEvents> </SfAutoComplete>
@code { SfAutoComplete<string, Order> autoObj; public SfDataManager DM { get; set; } public List<Order> RemoteData { get; set; }
private async Task OnFilter(FilteringEventArgs args) { args.PreventDefaultAction = true;
object t = await DM.ExecuteQuery<Order>(new Query().Take(30)); var listdata = JsonConvert.DeserializeObject<List<Order>>(JsonConvert.SerializeObject(t)); RemoteData = listdata; WhereFilter nameFilter = new WhereFilter() { Field = "CustomerID", value = args.Text, Operator = "startswith", IgnoreCase = true }; Query query = new Query().Where(nameFilter); query = !string.IsNullOrEmpty(args.Text) ? query : new Query(); await autoObj.FilterAsync(RemoteData, query); }
public class Order { public int? EmployeeID { get; set; } public int? OrderID { get; set; } public string CustomerID { get; set; } public string ShipName { get; set; } public string ShipCity { get; set; } public double? Freight { get; set; } } // local data loading List<Order> Countries = new List<Order> { new Order() { EmployeeID=5, OrderID=10248, CustomerID="VINET" }, new Order() { EmployeeID=6, OrderID=10249, CustomerID="TOMSP" }, new Order() { EmployeeID=4, OrderID=10250, CustomerID="HANAR" } }; } |
Find the sample in the attachment:
Regards,
Sureshkumar P
Hello Sureshkumar,
Thank you for your quick response and great advice!
I'm able to follow your instructions to execute my objective!
I have one follow up question.
So the implementation above can achieve the original goals, but with a limitation.
The Goal (a) needs to be achieved in two ways:
(a-1) when user FocusIn on the empty text box
(a-2) when the user presses delete key to delete all characters
The case (a-1) is easily achieved in the above code.
However the case (a-2) is hard to achieve because it seems that the OnFiltering event only gets fired when there is at least one character in the autocomplete box. So it means it's useless to add an if statement in to the "OnFiltering" function to check for empty string.
For some reason
the AutoComplete does not have any "OnInput" event. And I noticed that the string that is bound to the component will only get updated at the "FocusOut" event.
Do you have any advice how to achieve (a-2)?
My guess is maybe using "@onkeydown" event outside of the Autocomplete component, however then it's hard to get the value of the search string because it is only bound on FocusOut
Hi Sorin,
You can achieve your requirement by calling the local data inside the filtering event when clear the searched value as in the below code.
Find the modified code example here:
|
@code { SfAutoComplete<string, Order> autoObj; public SfDataManager DM { get; set; } public List<Order> RemoteData { get; set; }
private async Task OnFilter(FilteringEventArgs args) { args.PreventDefaultAction = true; if (!string.IsNullOrEmpty(args.Text)) { object t = await DM.ExecuteQuery<Order>(new Query().Take(30)); var listdata = JsonConvert.DeserializeObject<List<Order>>(JsonConvert.SerializeObject(t)); RemoteData = listdata; WhereFilter nameFilter = new WhereFilter() { Field = "CustomerID", value = args.Text, Operator = "startswith", IgnoreCase = true }; Query query = new Query().Where(nameFilter); query = !string.IsNullOrEmpty(args.Text) ? query : new Query(); await autoObj.FilterAsync(RemoteData, query); } else { await autoObj.FilterAsync(Countries, new Query()); } }
public class Order { public int? EmployeeID { get; set; } public int? OrderID { get; set; } public string CustomerID { get; set; } public string ShipName { get; set; } public string ShipCity { get; set; } public double? Freight { get; set; } } // local data loading List<Order> Countries = new List<Order> { new Order() { EmployeeID=5, OrderID=10248, CustomerID="VINET" }, new Order() { EmployeeID=6, OrderID=10249, CustomerID="TOMSP" }, new Order() { EmployeeID=4, OrderID=10250, CustomerID="HANAR" } }; } |
Find the modified sample in the attachment:
Regards,
Sureshkumar P
Hello Sureshkumar,
Thank you for your feedback! It worked as you said.
I realize my problem was that my condition was if(args.Text != "") and that's why it wasn't behaving as expected.
But when I use if (!string.IsNullOrEmpty(args.Text)) then it works as expected.
Sorin,
Thanks for your update.
Regards,
Sureshkumar P