Hello,
I can see that sfAutoComplete will clear the text by the user upon tabbing out if that text doesn't match one of the items in the dropdown and AllowCustom="false".
However, if the user has previously selected a valid item from the auto complete dropdown but then returns and enters invalid text, I need the component to revert to the previously selected valid ItemData and corresponding text when the user tabs out of the field .
Furthermore, I need to make sure that the @bind-value property of my model is not updated if the user has entered something invalid.
Please advise how I can achieve this.
Thanks,
Chuck
|
<SfAutoComplete @ref="AutoObj" TValue="string" TItem="Countries" Placeholder="e.g. Australia" @bind-Value="@AutoVal" AllowCustom="true" DataSource="@Country">
<AutoCompleteFieldSettings Value="Name"></AutoCompleteFieldSettings>
<AutoCompleteEvents TValue="string" TItem="Countries" CustomValueSpecifier="OnCustom"></AutoCompleteEvents>
</SfAutoComplete>
public async Task OnCustom(CustomValueSpecifierEventArgs<Countries> args)
{
args.Item = new Countries() { Name = AutoVal };
} |
Hi Berly,
Thanks for the swift reply and this is exactly what I needed. The CustomValueSpecifier event works perfectly.
This brings me to a related question, I know that I can set the bind-value to the country code when first loading the sfAutoComplete component and it will automatically call ReadAsync when using a custom DataAdaptor (as I am retrieving country names from a back end service) to correctly set the country name in the text box.
However, is there a way to initialise the sfAutoComplete component with a specific Countries item without having to go through the process of invoking ReadAsync on the DataAdaptor. The reason being that in my case, when generating my model for an existing record, I already know both the country code and country name. So I can create a Countries item from that data and would like to be able to set that Countries item into the sfAutoComplete component when first loaded to avoid the call to the back end service. Only if the user tries to change the text in the sfAutoComplete component should it need to call DataAdaptor.ReadAsync.
Is there a way I can achieve this?
Thanks,
Chuck
Hi Berly,
Thanks for the additional info. I guess I can expose a method on the DataAdaptor to set the initial values from my model at the point my component is initialised such the DataAdaptor returns the initial Countries item when ReadAsync is called the first time.
One final question, if the user enters invalid text and presses tab I can set the item back to the valid one using CustomValueSpecifier handler as you have suggested. I also need to display a message to the user and set the focus back to the sfAutoComplete text box in this case.
I have tried adding the following to the event handler:
await JS.InvokeAsync<object>("alert", "No matching record exists");
await sfCountriesAutoComplete.FocusAsync();
However, focus still moves onto the next control.
Could you please advise how I can set focus back to the sfAutoComplete text box?
Thanks,
Chuck
|
<SfAutoComplete @ref="AutoObj" TValue="string" TItem="Countries" Placeholder="e.g. Australia" @bind-Value="@AutoVal" @onkeydown="@keydownhandler" AllowCustom="true" DataSource="@Country">
<AutoCompleteFieldSettings Value="Name"></AutoCompleteFieldSettings>
<AutoCompleteEvents TValue="string" TItem="Countries" Blur="blurhandler" CustomValueSpecifier="OnCustom"></AutoCompleteEvents>
</SfAutoComplete>
@code {
SfAutoComplete<string, Countries> AutoObj;
public bool isTab { get; set; }
public string AutoVal { get; set; }
public class Countries
{
public string Name { get; set; }
public string Code { get; set; }
}
List<Countries> Country = new List<Countries>
{
new Countries() { Name = "Australia", Code = "AU" },
new Countries() { Name = "Bermuda", Code = "BM" },
new Countries() { Name = "Canada", Code = "CA" },
new Countries() { Name = "Cameroon", Code = "CM" },
new Countries() { Name = "Denmark", Code = "DK" },
new Countries() { Name = "France", Code = "FR" },
new Countries() { Name = "Finland", Code = "FI" },
new Countries() { Name = "Germany", Code = "DE" },
new Countries() { Name = "Greenland", Code = "GL" },
new Countries() { Name = "Hong Kong", Code = "HK" },
new Countries() { Name = "India", Code = "IN" },
new Countries() { Name = "Italy", Code = "IT" },
new Countries() { Name = "Japan", Code = "JP" },
new Countries() { Name = "Mexico", Code = "MX" },
new Countries() { Name = "Norway", Code = "NO" },
new Countries() { Name = "Poland", Code = "PL" },
new Countries() { Name = "Switzerland", Code = "CH" },
new Countries() { Name = "United Kingdom", Code = "GB" },
new Countries() { Name = "United States", Code = "US" },
};
public async Task OnCustom(CustomValueSpecifierEventArgs<Countries> args)
{
args.Item = new Countries() { Name = AutoVal };
}
public void keydownhandler(KeyboardEventArgs args)
{
if(args.Code == "Tab")
{
this.isTab = true;
}
}
public async Task blurhandler()
{
if(this.isTab)
{
await AutoObj.FocusAsync();
this.isTab = false;
StateHasChanged();
}
}
} |
Hello,
Thank you for the recommendation on how to set focus back. Before implementing that, our testing has revealed an issue with the original solution to reset to a valid value by implementing CustomValueSpecifier.
This solution works perfectly if you type slow enough but if you enter an invalid value quickly, it doesn't get reverted back to the previous valid value. To reproduce:
Hi Berly,
Thanks for the rapid response. However, I am not entirely clear what the solution is for this issue. Are you saying that the ValueChange event will be fired twice and that I should hook into the second time it is called to restore the original valid value (which I will need to have saved somewhere previously) and set focus back to the control?
Or do I need to implement another approach to preventing the user from leaving the control with an invalid value after rapidly typing a letter and tabbing?
Thanks,
Chuck