diff --git a/Havit.Blazor.Components.Web.Bootstrap.Documentation/XmlDoc/Havit.Blazor.Components.Web.Bootstrap.xml b/Havit.Blazor.Components.Web.Bootstrap.Documentation/XmlDoc/Havit.Blazor.Components.Web.Bootstrap.xml
index 7a6623a76..5ce553033 100755
--- a/Havit.Blazor.Components.Web.Bootstrap.Documentation/XmlDoc/Havit.Blazor.Components.Web.Bootstrap.xml
+++ b/Havit.Blazor.Components.Web.Bootstrap.Documentation/XmlDoc/Havit.Blazor.Components.Web.Bootstrap.xml
@@ -5077,11 +5077,21 @@
Hides the search icon when used!
+
+
+ If true, the first suggestion is highlighted until another is chosen by the user.
+
+
Shows whether the has been below minimum required length recently (before data provider loading is completed).
+
+
+ Input's index for the keyboard navigation. If this is the current index, then no item is selected.
+
+
If the is empty, we don't want to display anything when nothing (or below the minimum amount of characters) is typed into the input.
@@ -5163,6 +5173,11 @@
Additional CSS classes for the search box input.
+
+
+ If true, the first suggestion is highlighted until another is chosen by the user.
+
+
Settings for the component.
diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.nongeneric.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.nongeneric.cs
index b8e89da6d..262a92b4e 100644
--- a/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.nongeneric.cs
+++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.nongeneric.cs
@@ -19,6 +19,7 @@ static HxSearchBox()
ClearIcon = BootstrapIcon.XLg,
MinimumLength = 2,
Delay = 300,
+ HighlightFirstSuggestion = true
};
}
}
diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor.cs
index 8a064c45c..89f5a3e7e 100644
--- a/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor.cs
+++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/HxSearchBox.razor.cs
@@ -201,6 +201,12 @@ public partial class HxSearchBox : IAsyncDisposable
///
[Parameter] public RenderFragment InputGroupEndTemplate { get; set; }
+ ///
+ /// If true, the first suggestion is highlighted until another is chosen by the user.
+ ///
+ [Parameter] public bool? HighlightFirstSuggestion { get; set; }
+ protected bool HighlightFirstSuggestionEffective => this.HighlightFirstSuggestion ?? GetSettings()?.HighlightFirstSuggestion ?? GetDefaults()?.HighlightFirstSuggestion ?? throw new InvalidOperationException(nameof(HighlightFirstSuggestion) + " default for " + nameof(HxSearchBox) + " has to be set.");
+
private string dropdownToggleElementId = "hx" + Guid.NewGuid().ToString("N");
private string dropdownId = "hx" + Guid.NewGuid().ToString("N");
private List searchResults = new();
@@ -276,7 +282,15 @@ protected async Task UpdateSuggestionsAsync()
dataProviderInProgress = false;
- focusedItemIndex = default; // KeyboardNavigation
+ // KeyboardNavigation
+ if (HighlightFirstSuggestionEffective)
+ {
+ focusedItemIndex = 0; // First item in the searchResults collection.
+ }
+ else
+ {
+ focusedItemIndex = InputKeyboardNavigationIndex;
+ }
searchResults = result?.Data.ToList();
@@ -329,18 +343,23 @@ protected async Task HandleTextQueryValueChanged(string newTextQuery)
private const string EnterKeyCode = "Enter";
private const string NumpadEnterKeyCode = "NumpadEnter";
+ ///
+ /// Input's index for the keyboard navigation. If this is the current index, then no item is selected.
+ ///
+ private const int InputKeyboardNavigationIndex = -1;
+
private bool HasItemFocus(TItem item)
{
- TItem focusedItem = GetItemByIndex(focusedItemIndex);
-
- if ((focusedItem is not null) && (!focusedItem.Equals(default)))
- {
- return item.Equals(focusedItem);
- }
- else
+ if (focusedItemIndex > InputKeyboardNavigationIndex && focusedItemIndex < GetFreeTextItemIndex())
{
- return false;
+ TItem focusedItem = GetItemByIndex(focusedItemIndex);
+ if ((focusedItem is not null) && (!focusedItem.Equals(default)))
+ {
+ return item.Equals(focusedItem);
+ }
}
+
+ return false;
}
private bool HasFreeTextItemFocus()
@@ -368,7 +387,7 @@ private async Task UpdateFocusedItem(KeyboardEventArgs keyboardEventArgs)
if (keyboardEventArgs.Code == ArrowUpKeyCode)
{
int previousItemIndex = focusedItemIndex - 1;
- if (previousItemIndex >= -1) // If the index is -1, no item is focused.
+ if (previousItemIndex >= InputKeyboardNavigationIndex) // If the index equals InputKeyboardNavigationIndex, no item is focused.
{
focusedItemIndex = previousItemIndex;
}
@@ -376,7 +395,7 @@ private async Task UpdateFocusedItem(KeyboardEventArgs keyboardEventArgs)
else if (keyboardEventArgs.Code == ArrowDownKeyCode)
{
int nextItemIndex = focusedItemIndex + 1;
- if (nextItemIndex < GetFreeTextItemIndex()) // If the index equals GetFreeTextItemIndex(), then the freetext item is selected.
+ if (nextItemIndex <= GetFreeTextItemIndex()) // If the index equals GetFreeTextItemIndex(), then the freetext item is selected.
{
focusedItemIndex = nextItemIndex;
}
diff --git a/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/SearchBoxSettings.cs b/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/SearchBoxSettings.cs
index 9f9a7efbe..f36c98ece 100644
--- a/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/SearchBoxSettings.cs
+++ b/Havit.Blazor.Components.Web.Bootstrap/Forms/SearchBox/SearchBoxSettings.cs
@@ -44,4 +44,9 @@ public class SearchBoxSettings
/// Additional CSS classes for the search box input.
///
public string InputCssClass { get; set; }
+
+ ///
+ /// If true, the first suggestion is highlighted until another is chosen by the user.
+ ///
+ public bool? HighlightFirstSuggestion { get; set; }
}