Unplanned
Last Updated: 06 Dec 2023 15:36 by Peter
Maria
Created on: 05 Mar 2020 09:37
Category: UI for Blazor
Type: Feature Request
57
DropDownTree

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

2 comments
Peter
Posted on: 06 Dec 2023 15:36
Can someone update this to be more bootstrap friendly, since that's what the demos are based on in '23
ADMIN
Marin Bratanov
Posted on: 05 Mar 2020 09:38

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

 UI for Blazor