Hello,
would it be possible to add "OnFocus" event to DropDownList as there is already "OnBlur" event?
Thanks
Right now when a DropDownList has PopupHeight="Auto" the popup gets the height necesaary to display its items properly.
But when there are many items the popup also displays all items without a vertical scrollbar (maybe over the entire page and beyond), which is not good.
My suggestion would be to add a property for specifyig a "MaxPopupHeight" to limit the growth of the popup.
Also if "PopupHeight" is not specified it should take "Auto" as the default value instead of a static height in px, instead give the new "MaxPopupHeight" a limiting default value.
***Admin Edit***
Released in 3.0.0 through PopupSettings tag: https://docs.telerik.com/blazor-ui/upgrade/breaking-changes/3-0-0#popup-settings
***Admin Edit***
---
ADMIN EDIT
Here is a reproducible with the workaround highlighted in green:
@using System.Collections.ObjectModel
<h4>Option Selected: 6 @selectedSix</h4>
<br />
<TelerikDropDownList Data="@myDdlData"
TextField="MyTextField"
ValueField="MyValueField"
@bind-Value="@selectedSix" />
<h4>Option Selected: 7 @selectedSeven</h4>
<br />
<TelerikDropDownList Data="@myDdlData"
TextField="MyTextField"
ValueField="MyValueField"
@bind-Value="@selectedSeven">
</TelerikDropDownList>
<TelerikButton OnClick="@AddOption">Add Item</TelerikButton>
<ul>
@foreach (var item in myDdlData)
{
<li>@item.MyValueField</li>
}
</ul>
@code {
int selectedSix { get; set; } = 6;
int selectedSeven { get; set; } = 7;
ObservableCollection<MyDdlModel> myDdlData = new ObservableCollection<MyDdlModel>(Enumerable.Range(1, 5).Select(x => new MyDdlModel { MyTextField = "item " + x, MyValueField = x }));
protected override async Task OnInitializedAsync()
{
AddOption();
await Task.Delay(TimeSpan.FromSeconds(1));
AddOption();
}
void AddOption()
{
myDdlData.Add(new MyDdlModel { MyTextField = "item " + (myDdlData.Count + 1), MyValueField = myDdlData.Count + 1 });
int origSelection = selectedSeven;
selectedSeven = 0;
StateHasChanged();
//add this if it does not work
//await Task.Delay(30);//wait a rendering frame
selectedSeven = origSelection;
//add this if it does not work
//StateHasChanged();
}
public class MyDdlModel
{
public int MyValueField { get; set; }
public string MyTextField { get; set; }
}
}
Note: This behavior also occurs if the initial data is received after the component is initialized. The workaround in this case will be similar - set the selected value after the data is received.
---
The following knowledge base article describes how to select the default value in a drop down, but if there's no default value the selection is not cleared using this method.
When setting the bind value to null (or the default, or frankly anything that doesn't exist in the drop down) I'd like the drop down list selection to be cleared when there's no default value set on the DropDownList.
@page "/"
<br />
<TelerikButton OnClick="@ClearSelection">Clear selection</TelerikButton>
<TelerikDropDownList Data="@data" @bind-Value="selectedValue" />
@code {
List<string> data = new() { "selection" };
string selectedValue;
void ClearSelection()
{
// This does not cause the drop down to clear the selection and I think it should.
selectedValue = null;
}
}
Is it possible to drop dropDownList from outside, for example after its data has been changed, without clicking on it ?
ADMIN EDIT:
This feature is also applicable to ComboBox, AutoComplete, Multiselect, Date and Time Pickers components.
The first element of the dropdown gets read aloud at page load even without being focused.
Using the latest version of (Chrome and Chromevox) and (Firefox and NVDA).
DropdownList does not work very well with a screen reader.
It should work like this one https://www.w3.org/TR/wai-aria-practices-1.1/examples/listbox/listbox-collapsible.html
Using NVDA and Firefox, it reads the selected item 3 times, sometimes does not work at all (This is only when you open the dropdown using alt plus down arrow). Using just the arrow up and down keys does not work.
Using Cromevox and ChromeOn the dropdowns, it does not give a description of how many options are available like, "1 of 4" when you first tab to it. It reads it after I already selected the first option. That should be reversed, read the options first and not after its selected (This is only when you open the dropdown using alt plus down arrow). Using only the arrow key up and down it reads the selected item only but does not reads the other options.
Hello everyone,
We have opened this Feature Request to gather your insights on the addition of disabled items for the DropDownList.
As a workaround, for the time being, you could use the following code snippet. It would prevent the user from clicking on the item with the mouse, but navigating with the keyboard and selecting it would still work.
<style>
.disabled-item {
color: #D3D3D3;
width:100%;
}
/* remove default padding so the user can't click the underlying element outside the template
Note: this will also affect other dropdowns on the page
*/
.ddl-item {
padding: 4px 8px;
}
.k-popup ul.k-list li.k-item {
padding: 0;
}
</style>
@TheValue
<br />
<TelerikDropDownList Data="@myDdlData" TextField="MyTextField" ValueField="MyValueField" @bind-Value="@TheValue">
<ItemTemplate>
@{
MyDdlModel item = context as MyDdlModel;
<div @onclick:preventDefault="@item.IsDisabled"
@onclick:stopPropagation="@item.IsDisabled"
class="@( item.IsDisabled ? "disabled-item ddl-item" : "ddl-item" )">
@item.MyTextField
</div>
}
</ItemTemplate>
</TelerikDropDownList>
@code {
int TheValue { get; set; } = 2;
public class MyDdlModel
{
public int MyValueField { get; set; }
public string MyTextField { get; set; }
public bool IsDisabled { get; set; }
}
IEnumerable<MyDdlModel> myDdlData = Enumerable.Range(1, 20).Select(x => new MyDdlModel
{
MyTextField = "item " + x,
MyValueField = x,
IsDisabled = x % 3 == 0
});
}
I have a cascading DropDownList scenario with virtual scrolling. When the first DropDownList changes value, the second one should reset its scrollbar to the top, because it now contains new data. This doesn't happen.
Here is a REPL test page.
Hello,
If I scroll the page down and open a filterable DropDownList, the page will scroll up.
Here is a REPL test page
UI for Blazor 2.30 works as expected. This broke in version 3.0.0. The issue exists only in WebAssembly apps.
---
ADMIN EDIT
This behavior is observed in the DropDownList when filtering is enabled and in the ComboBox regardless of whether filtering is enabled or not.
The (filter) input gets focus, which shows the soft keyboard, which changes the viewport size, which causes the dropdown to hide. Unfortunately, there is no workaround at the moment (except perhaps disabling filtering for small viewports).
---
When used in Bootstrap Grid the DropDownList popup is misaligned on the first open. On a second click, it is aligned.
This behavior is also valid for Combobox and Autocomplete.
Reproduction code:
<div class="box">
<div class="row mt-3" style="align-items:center">
<div class="col-12 col-lg-4">
<span class="bold">ComboBox</span>
</div>
<div class="col">
<TelerikComboBox Data="@myComboData" TextField="ComboTextField" ValueField="ComboValueField"
@bind-Value="selectedCombo" ClearButton="true" Filterable="true">
</TelerikComboBox>
</div>
</div>
<div class="row mt-3" style="align-items:center">
<div class="col-12 col-lg-4">
<span class="bold">DropDownList</span>
</div>
<div class="col">
<TelerikDropDownList Data="@myDdlData" TextField="MyTextField" ValueField="MyValueField"
@bind-Value="@selectedDropDown">
</TelerikDropDownList>
</div>
</div>
<div class="row mt-3" style="align-items:center">
<div class="col-12 col-lg-4">
<span class="bold">Autocomplete</span>
</div>
<div class="col">
<TelerikAutoComplete Data="@Suggestions" @bind-Value="@AutoCompleteValue"
ClearButton="true" />
</div>
</div>
</div>
@code {
public int selectedDropDown { get; set; }
public int selectedCombo { get; set; }
public string AutoCompleteValue { get; set; }
//ComboBox
public class ComboModel
{
public int ComboValueField { get; set; }
public string ComboTextField { get; set; }
}
IEnumerable<ComboModel> myComboData = Enumerable.Range(1, 20).Select(x => new ComboModel { ComboTextField = "item " + x, ComboValueField = x });
//DropDownList
public class MyDdlModel
{
public int MyValueField { get; set; }
public string MyTextField { get; set; }
}
IEnumerable<MyDdlModel> myDdlData = Enumerable.Range(1, 20).Select(x => new MyDdlModel { MyTextField = "item " + x, MyValueField = x });
//Autocomplete
List<string> Suggestions { get; set; } = new List<string> {
"Manager", "Developer", "QA", "Technical Writer", "Support Engineer", "Sales Agent", "Architect", "Designer"
};
}
The DropDownList component is too basic to be used in complex environments. In the real world, no one is binding DropDownLists to List<string>, they are binding to complex datatypes, and the ability to do so has been present in MVC apps for a long time.
Given the following code, it is possible to bind to a List<object>, and two-way bind to the object that was selected.
<select @onchange="@OnChangedAsync">
<option></option>
@if (DataSource != null)
{
@foreach (var item in DataSource)
{
<option @key="item" value="@optionValueFunc(item)" selected="@(item.Equals(SelectedItem))">@optionTextFunc(item)</option>
}
}
</select>
#region Private Members
private Func<TSource, object> optionTextFunc;
private Func<TSource, object> optionValueFunc;
private TSource selectedItem = default(TSource);
#endregion
#region Public Parameters
/// <summary>
/// A List of objects to bind against.
/// </summary>
[Parameter]
public IList<TSource> DataSource { get; set; } = new List<TSource>();
/// <summary>
/// A lambda expression referencing the property containing the text to display to the end user. Example: @(c => c.DisplayName)
/// </summary>
[Parameter]
public Expression<Func<TSource, object>> OptionText { get; set; }
/// <summary>
/// A lambda expression referencing the property containing the value for this object, usually an identifier. Example: @(c => c.Id)
/// </summary>
[Parameter]
public Expression<Func<TSource, object>> OptionValue { get; set; }
/// <summary>
/// The item from the <see cref="DataSource" /> that has been selected.
/// </summary>
[Parameter]
public TSource SelectedItem { get; set; }
/// <summary>
/// The callback event required for two-way binding.
/// </summary>
[Parameter]
public EventCallback<TSource> SelectedItemChanged { get; set; }
#endregion
private async Task OnChangedAsync(ChangeEventArgs changeEventArgs)
{
await UpdateSelection(DataSource.FirstOrDefault(c => optionValueFunc(c).ToString() == changeEventArgs.Value.ToString()));
}
private async Task UpdateSelection(TSource item)
{
selectedItem = item;
await SelectedItemChanged.InvokeAsync(selectedItem);
}
protected override async Task OnInitializedAsync()
{
if (optionTextFunc == null && OptionText != null)
{
optionTextFunc = OptionText.Compile();
}
if (optionValueFunc == null && OptionText != null)
{
optionValueFunc = OptionValue.Compile();
}
await Task.CompletedTask;
}
Would really appreciate it if you would consider adding this to the next release.
The drop down list component does not allow the user to associate a label with the underlying html select input control, which goes against accessibility standards. It appears that most, if not all, of the other components follow the accessibility standards. Please fix the drop down list and/or allow attribute splatting so that developers can apply their own attributes (like aria-label) to meet accessibility standards.