diff --git a/samples/BlazorServer/Pages/Index.razor b/samples/BlazorServer/Pages/Index.razor
index 83c9312..f94f58d 100644
--- a/samples/BlazorServer/Pages/Index.razor
+++ b/samples/BlazorServer/Pages/Index.razor
@@ -189,6 +189,23 @@
}
+Blazored Typeahead - Error Handler
+
+
+
+ @person.Firstname
+
+
+ @person.Firstname @person.Lastname
+
+
+ @context.Message
+
+
+
+
@code {
private bool IsDisabled = true;
@@ -264,6 +281,16 @@
{
return await Task.FromResult(People.Where(x => x.Firstname.ToLower().Contains(searchText.ToLower())).ToList());
}
+
+ private async Task> GetErrorPeople(string searchText)
+ {
+ if (searchText.Contains("win", StringComparison.InvariantCultureIgnoreCase))
+ {
+ return await GetPeopleLocal(searchText);
+ }
+
+ throw new InvalidOperationException("Only people with 'win' in name allowed");
+ }
private void HandleFormSubmit()
{
diff --git a/src/Blazored.Typeahead/BlazoredTypeahead.razor b/src/Blazored.Typeahead/BlazoredTypeahead.razor
index c6d7350..a1589d9 100644
--- a/src/Blazored.Typeahead/BlazoredTypeahead.razor
+++ b/src/Blazored.Typeahead/BlazoredTypeahead.razor
@@ -214,4 +214,10 @@
}
}
+ else if (ShowError())
+ {
+
+ @ErrorTemplate(Error)
+
+ }
diff --git a/src/Blazored.Typeahead/BlazoredTypeahead.razor.cs b/src/Blazored.Typeahead/BlazoredTypeahead.razor.cs
index 623aaf6..2ffacdf 100644
--- a/src/Blazored.Typeahead/BlazoredTypeahead.razor.cs
+++ b/src/Blazored.Typeahead/BlazoredTypeahead.razor.cs
@@ -43,6 +43,7 @@ public partial class BlazoredTypeahead : ComponentBase, IDisposab
[Parameter] public RenderFragment SelectedTemplate { get; set; }
[Parameter] public RenderFragment HeaderTemplate { get; set; }
[Parameter] public RenderFragment FooterTemplate { get; set; }
+ [Parameter] public RenderFragment ErrorTemplate { get; set; }
[Parameter(CaptureUnmatchedValues = true)] public IReadOnlyDictionary AdditionalAttributes { get; set; }
[Parameter] public int MinimumLength { get; set; } = 1;
@@ -62,6 +63,10 @@ public partial class BlazoredTypeahead : ComponentBase, IDisposab
private TItem[] Suggestions { get; set; } = new TItem[0];
private int SelectedIndex { get; set; }
private bool ShowHelpTemplate { get; set; } = false;
+
+ private Exception Error { get; set; }
+ private bool HasError => Error != null;
+
private string SearchText
{
get => _searchText;
@@ -304,7 +309,6 @@ private async Task ResetControl()
await ValuesChanged.InvokeAsync(Values);
_editContext?.NotifyFieldChanged(_fieldIdentifier);
}
-
}
[JSInvokable("ResetControlBlur")]
@@ -332,7 +336,7 @@ private async Task ShowMaximumSuggestions()
IsSearching = true;
await InvokeAsync(StateHasChanged);
- Suggestions = (await SearchMethod?.Invoke(_searchText)).Take(MaximumSuggestions).ToArray();
+ Suggestions = await SearchForSuggestionsAsync();
IsSearching = false;
await InvokeAsync(StateHasChanged);
@@ -386,15 +390,32 @@ private async void Search(Object source, ElapsedEventArgs e)
ShowHelpTemplate = false;
IsSearching = true;
await InvokeAsync(StateHasChanged);
- Suggestions = (await SearchMethod?.Invoke(_searchText)).Take(MaximumSuggestions).ToArray();
+ Suggestions = await SearchForSuggestionsAsync();
IsSearching = false;
- IsShowingSuggestions = true;
await HookOutsideClick();
SelectedIndex = 0;
await InvokeAsync(StateHasChanged);
}
+ private async Task SearchForSuggestionsAsync()
+ {
+ try
+ {
+ Error = null;
+ var suggestions = (await SearchMethod?.Invoke(_searchText)).Take(MaximumSuggestions).ToArray();
+ IsShowingSuggestions = true;
+
+ return suggestions;
+ }
+ catch (Exception e) when (ErrorTemplate != null)
+ {
+ IsShowingSuggestions = false;
+ Error = e;
+ return null;
+ }
+ }
+
private async Task HookOutsideClick()
{
await JSRuntime.OnOutsideClick(_searchInput, this, "ResetControlBlur", true);
@@ -403,7 +424,7 @@ private async Task HookOutsideClick()
private async Task SelectResult(TItem item)
{
var value = ConvertMethod(item);
-
+
if (IsMultiselect)
{
var valueList = Values ?? new List();
@@ -444,14 +465,16 @@ private async Task SelectNotFoundPlaceholder()
private bool ShouldShowHelpTemplate()
{
return SearchText.Length > 0 &&
- ShowHelpTemplate &&
- HelpTemplate != null;
+ ShowHelpTemplate &&
+ HelpTemplate != null;
}
private bool ShouldShowSuggestions()
{
return IsShowingSuggestions &&
- Suggestions.Any() && !IsSearchingOrDebouncing;
+ Suggestions.Any() &&
+ !IsSearchingOrDebouncing &&
+ !HasError;
}
private void MoveSelection(int count)
@@ -478,11 +501,21 @@ private Task SelectTheFirstAndOnlySuggestion()
}
private bool IsSearchingOrDebouncing => IsSearching || _debounceTimer.Enabled;
+
private bool ShowNotFound()
{
return IsShowingSuggestions &&
!IsSearchingOrDebouncing &&
- !Suggestions.Any();
+ !Suggestions.Any() &&
+ !HasError;
+ }
+
+ private bool ShowError()
+ {
+ return ErrorTemplate != null &&
+ HasError &&
+ !IsShowingSuggestions &&
+ !IsSearchingOrDebouncing;
}
public void Dispose()
@@ -504,4 +537,4 @@ public async Task Focus()
await HandleClickOnMask();
}
}
-}
+}
\ No newline at end of file