I would like a comopnent similar to this one https://demos.telerik.com/kendo-ui/dropdowntree/index
The goal is to be able to show and select hierarchical data, because the multiselect is flat https://demos.telerik.com/blazor-ui/multiselect/overview
Here is a sample workaround that uses a treeview for the data, adds checkboxes to create item selection (you can also consider adding onclick handlers too - see here), and an animation container to create a dropdown:
<div style="position:relative;">
<span class="k-widget k-dropdown k-header" @onclick="@ToggleDropdown" style="width: 300px;">
<span class="k-dropdown-wrap k-state-default @( DropDownShown ? "k-state-focused" : "" )">
<span class="k-input">@GetSelectedItemsText()</span>
<span class="k-select">
<span class="k-icon k-i-arrow-60-down"></span>
</span>
</span>
</span>
<TelerikAnimationContainer @ref="dropdown" Width="300px" Height="400px" Class="k-popup">
<TelerikTreeView Data="@TreeData">
<TreeViewBindings>
<TreeViewBinding>
<ItemTemplate>
@{
TreeItem itm = context as TreeItem;
<input type="checkbox" id="cb1" class="k-checkbox" @bind="@itm.Selected">
<label class="k-checkbox-label" for="cb1">@itm.Text</label>
}
</ItemTemplate>
</TreeViewBinding>
</TreeViewBindings>
</TelerikTreeView>
</TelerikAnimationContainer>
</div>
@foreach (var item in SelectedItems)
{
<div>@item.Id</div>
}
@code {
// consider exposing these two as parameters and maybe giving them events if you encapsulate this in a standalone component
public IEnumerable<TreeItem> TreeData { get; set; }
public List<TreeItem> SelectedItems { get; set; } = new List<TreeItem>();
private bool DropDownShown { get; set; }
private TelerikAnimationContainer dropdown;
async Task ToggleDropdown()
{
DropDownShown = !DropDownShown;
await dropdown.ToggleAsync();
}
string GetSelectedItemsText()
{
//clean the current selection
SelectedItems = new List<TreeItem>();
//every time the DOM re-renders, we re-calculate the selection
//consider doing this only on an event such as the click handler above
foreach (var item in TreeData)
{
AppendSelectedItems(item);
}
// collect text for the dropdown element. Consider using
// only the first N items for better appearance
string result = string.Join(", ", SelectedItems);
return result;
}
void AppendSelectedItems(TreeItem item)
{
if (item.Selected)
{
SelectedItems.Add(item);
}
foreach (var childItem in item.Items)
{
AppendSelectedItems(childItem);
}
}
// data generation for the treeview
// see more at https://docs.telerik.com/blazor-ui/components/treeview/data-binding/overview
public class TreeItem
{
public string Text { get; set; }
public int Id { get; set; }
public List<TreeItem> Items { get; set; } = new List<TreeItem>();
public bool Expanded { get; set; }
public bool HasChildren { get; set; }
public bool Selected { get; set; }
// in this sample we override ToString to easily show text in the dropdown element
public override string ToString()
{
return this.Text;
}
}
protected override void OnInitialized()
{
LoadHierarchical();
}
private void LoadHierarchical()
{
List<TreeItem> roots = new List<TreeItem>() {
new TreeItem { Text = "Item 1", Id = 1, Expanded = true, HasChildren = true },
new TreeItem { Text = "Item 2", Id = 2, HasChildren = true }
};
roots[0].Items.Add(new TreeItem
{
Text = "Item 1 first child",
Id = 3
});
roots[0].Items.Add(new TreeItem
{
Text = "Item 1 second child",
Id = 4
});
roots[1].Items.Add(new TreeItem
{
Text = "Item 2 first child",
Id = 5
});
roots[1].Items.Add(new TreeItem
{
Text = "Item 2 second child",
Id = 6
});
TreeData = roots;
}
}
Regards,
Marin Bratanov
Progress Telerik