New to Telerik UI for ASP.NET CoreStart a free 30-day trial

Select the Folder Path When Clicking a TreeList Node

Environment

ProductTreeList for Progress® Telerik® UI for ASP.NET Core

Description

How can I bind the TreeList to Hierarchical data and select the folder path when a specified node is clicked?

Solution

To achieve the desired scenario:

  1. Customize the TreeList rows by using the RowTemplateId and AltRowTemplateId methods.
  2. Enable the Selectable option to allow multiple row selection: .Selectable(s => s.Mode(TreeListSelectionMode.Multiple)).
  3. Handle the change event of the TreeList, get the selected node, and manually select its parent nodes.
Razor
    @(Html.Kendo().TreeList<HierarchicalViewModel>()
        .Name("treelist")
        .Columns(columns =>
        {
            columns.Add().Field(e => e.ID);
        })
        .Selectable(s => s.Mode(TreeListSelectionMode.Multiple))
        .RowTemplateId("rowTemplate")
        .AltRowTemplateId("altRowTemplate")
        .DataSource(dataSource => dataSource
            .Read(read => read.Action("All", "Home"))
            .Model(m =>
            {
                m.Id(f => f.ID);
                m.ParentId(f => f.ParentID);
                m.Expanded(true);
            })
        )
        .Events(ev => ev.Change("onChange"))
    )

    <script id="rowTemplate" type="text/x-kendo-template">
        <tr data-uid='#: data.model.uid #' role="row" class='#=data.hasChildren? 'parentRow' : 'childRow'#'>
            <td role="gridcell">
                #for(var i = 0; i < (hasChildren ? level : (level + 1)); i++){#
                    <span class="k-icon k-i-none"></span>
                #}#
                #if(data.hasChildren){#
                    # if(data.model.expanded) { #
                      #= kendo.ui.icon("caret-alt-down") #
                	# } else { #
                      #= kendo.ui.icon("caret-alt-right") #
                	# } #
                #}#
                <span class="k-sprite #: data.model.SpriteCssClass #"></span>
                <span> #: data.model.Name # </span>
            </td>
        </tr>
    </script>

    <script id="altRowTemplate" type="text/x-kendo-template">
        <tr data-uid='#: data.model.uid #' role="row" class="k-alt #=data.hasChildren? 'parentRow' : 'childRow'#">
            <td role="gridcell">
                #for(var i = 0; i < (hasChildren ? level : (level + 1)); i++){#
                    <span class="k-icon k-i-none"></span>
                #}#
                #if(data.hasChildren){#
                    # if(data.model.expanded) { #
                      #= kendo.ui.icon("caret-alt-down") #
                	# } else { #
                      #= kendo.ui.icon("caret-alt-right") #
                	# } #
                #}#
                <span class="k-sprite #: data.model.SpriteCssClass #"></span>
                <span> #: data.model.Name # </span>
            </td>
        </tr>
    </script>

    <script>
        function findParentItems(allParentRows, selectedDataItem, selectedParentRows, level) {
            var treeList = $("#treelist").data("kendoTreeList");

            for(var i = 0; i < allParentRows.length; i++) {
                var currentDataItem = treeList.dataItem(allParentRows[i]);
                var addedItem = $.inArray( allParentRows[i], selectedParentRows );
                var currentLevel = $(allParentRows[i]).find(".k-icon").length; //get the current item level
                if(currentDataItem.ParentID != null && addedItem == -1 && currentLevel < level){
                    for(var j = 0; j < selectedParentRows.length; j++) { //loop through the already stored items
                        var dt = treeList.dataItem(selectedParentRows[j]);
                        if(currentDataItem.ID == dt.ParentID) { //check if the parent is a direct parent of the stored item
                            selectedParentRows.push(allParentRows[i]); //store it
                            findParentItems(allParentRows,currentDataItem, selectedParentRows, currentLevel);
                            break;
                        }
                    }
                }
            }
            return selectedParentRows;
        }

        function onChange(e) {
            var treeList = e.sender;
            var selectedRow = $("#treelist .k-grid-content table tbody").find("tr.k-selected");
            var rootLevel = $("#treelist .k-grid-content table tbody").find("tr:first").find(".k-icon").length;
            var level = $(selectedRow).find(".k-icon").length;
            var selectedRowDataItem = treeList.dataItem($(selectedRow));
            var prevParentRows = $(selectedRow).prevAll(".parentRow");

            if(rootLevel < level){ //selecting the root folder
                $("#treelist .k-grid-content table tbody").find("tr:first").addClass("k-selected").attr("aria-selected", true);
            }

            if(prevParentRows.length > 0) {
                var selectedParentRows = [];
                prevParentRows = $.grep(prevParentRows, function(n, i) { //get the direct parent of the selected item
                    var dataItem = treeList.dataItem($(n));
                    return (dataItem.ID == selectedRowDataItem.ParentID);
                });
                selectedParentRows.push(prevParentRows[0]); //store it
                var result = findParentItems($(selectedRow).prevAll(".parentRow"), selectedRowDataItem, selectedParentRows, level);

                for(var i = 0; i < result.length; i++) {
                    $(result[i]).addClass("k-selected").attr("aria-selected", true); //select the parent folder
                }
            }
        }
    </script>

More ASP.NET Core TreeList Resources

See Also