I am working on a form where experienced agents need to input data quickly. Often enough they know the codes and so they can type them in the combo box, but they shouldn't have to look for the mouse to select the item, the combo box should select it when the user presses Tab to move to the next field.
This should happen only when the user has filtered the combo box so they see some items (and so the dropdown is open) - I want them to be able to select only items from the available options, AllowCustom does not work for me.
---
ADMIN EDIT
Here is one workaround you can consider:
https://blazorrepl.telerik.com/QoOAPyEZ233YP2AX19
@inject IJSRuntime js
@* Move this script to a separate JS file *@
<script suppress-error="BL9992">
function getHighligtedComboItem() {
// Get the currently focused item in this particular ComboBox.
var focusedItem = document.querySelector(".select-on-tab .k-list-item.k-focus");
if (focusedItem) {
return focusedItem.innerText;
}
}
</script>
<p>FirstFilteredItem: @FirstFilteredItem</p>
<p>Selected value: @ComboBoxValue</p>
<span onkeyup="@GetFirstFilteredItem">
<TelerikComboBox Data="@ComboBoxData"
Value="@ComboBoxValue"
ValueChanged="@( (int newValue) => ComboBoxValueChanged(newValue) )"
TextField="@nameof(ListItem.Text)"
ValueField="@nameof(ListItem.Value)"
Filterable="true"
FilterOperator="@StringFilterOperator.Contains"
OnBlur="@SelectItemOnTab"
OnOpen="@( () => IsComboBoxOpen = true )"
OnClose="@( () => IsComboBoxOpen = false )"
Placeholder="Select an item..."
ClearButton="true"
Width="200px">
<ComboBoxSettings>
<ComboBoxPopupSettings Class="select-on-tab" />
</ComboBoxSettings>
</TelerikComboBox>
</span>
<input placeholder="another form element" />
@code {
private IEnumerable<ListItem> ComboBoxData = Enumerable.Range(1, 123).Select(x => new ListItem { Text = "Item " + x, Value = x });
private int ComboBoxValue { get; set; }
private string FirstFilteredItem { get; set; } = string.Empty;
private bool IsComboBoxOpen { get; set; }
private async Task GetFirstFilteredItem(KeyboardEventArgs args)
{
if (!IsComboBoxOpen)
{
// Wait at least 300ms, which is the opening animation.
await Task.Delay(400);
}
else
{
// Wait, depending on the typical filtering time.
await Task.Delay(300);
}
// The code that will find the item text depends on the exact scenario and potential use of ItemTemplate.
FirstFilteredItem = await js.InvokeAsync<string>("getHighligtedComboItem");
}
private void SelectItemOnTab()
{
if (!string.IsNullOrEmpty(FirstFilteredItem))
{
// Match the filter operation to the filter operator of the ComboBox.
var matchingItem = ComboBoxData.Where(x => x.Text.ToLowerInvariant().Contains(FirstFilteredItem.Trim().ToLowerInvariant())).FirstOrDefault();
if (matchingItem != null)
{
ComboBoxValue = matchingItem.Value;
FirstFilteredItem = string.Empty;
}
}
}
private void ComboBoxValueChanged(int newValue)
{
ComboBoxValue = newValue;
FirstFilteredItem = string.Empty;
}
public class ListItem
{
public int Value { get; set; }
public string Text { get; set; } = string.Empty;
}
}