This is a migrated thread and some comments may be shown as answers.

How to select the first item after the Read() is completed

7 Answers 1078 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Joel
Top achievements
Rank 1
Iron
Joel asked on 29 Aug 2019, 01:59 AM

Hi,

  I am working on a ASP.Net Core MVC project.

  When user click on the Detail button, i will return a partial view with a treeview in it.

  When the page is first loaded, i want the first item in the treeview to be selected programmatically after the Read() operation is competed. (Note: i want to avoid asking user to do that after the page is first loaded)

  Can you share with me how to achieve that?

Index.cshtml

@(Html.Kendo().TreeView()
    .Name("machinesTreeView")
    .DataTextField("MachineName")
    .TemplateId("treeview-template")
    .DataSource(dataSource => dataSource
        .Read(read => read
            .Action("Machines", "MachineDetails", new { productionLineName = Model.ProductionLineName })
        )
    )
)

 

script

<script>
    function onSelectMachine(e) {
        // load content into the pane with ID="detailsPane"
        var detailsUrl = '@Url.Action("Details", "MachineDetails")';
        $('#detailsPane').load(detailsUrl);
    }
 
    $(document).ready(function () {
        var treeview = $("#machinesTreeView").data("kendoTreeView");
        treeview.bind("select", onSelectMachine);
    });
</script>

 

controller

public async Task<IActionResult> Machines(string productionLineName)
{
    MachineDetailsModel model = await m_IFetchRealtimeData.GetMachineDetails(productionLineName);
    return Json(model.MachineInfosModel.OrderBy(x => x.MachineNo));
}

 

7 Answers, 1 is accepted

Sort by
0
Aleksandar
Telerik team
answered on 02 Sep 2019, 02:26 PM

Hi Joel,

Selecting the first item of a treeview can be achieved by binding a custom function to the DataBound event, as this event is triggered after the dataSource change event has been processed. The first node of the tree has a class of k-first, by which it can be selected:

function onDataBound(e){
        $('#treeview').getKendoTreeView().select(".k-first")
    };

Attached is a sample project demonstrating the above. Let me know if you have further questions.

Regards,
Aleksandar
Progress Telerik

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Joel
Top achievements
Rank 1
Iron
answered on 03 Sep 2019, 12:40 PM

The first time "Detail" button is clicked, following exception was recorded & the treeview is empty.

ReferenceError: onDataBound is not defined
    at <anonymous>:1:83
    at Object.n [as syncReady] (d:\development\vela mfg dashboard\source code\velamfgdashboard\velamfgdashboard\wwwroot\lib\kendo-ui\js\kendo.aspnetmvc.min.js:25:12755)
    at <anonymous>:1:7
    at DOMEval (d:\development\vela mfg dashboard\source code\velamfgdashboard\velamfgdashboard\wwwroot\lib\jquery\dist\jquery.js:111:13)
    at domManip (d:\development\vela mfg dashboard\source code\velamfgdashboard\velamfgdashboard\wwwroot\lib\jquery\dist\jquery.js:5762:9)
    at jQuery.fn.init.append (d:\development\vela mfg dashboard\source code\velamfgdashboard\velamfgdashboard\wwwroot\lib\jquery\dist\jquery.js:5898:11)
    at jQuery.fn.init.<anonymous> (d:\development\vela mfg dashboard\source code\velamfgdashboard\velamfgdashboard\wwwroot\lib\jquery\dist\jquery.js:5992:19)
    at access (d:\development\vela mfg dashboard\source code\velamfgdashboard\velamfgdashboard\wwwroot\lib\jquery\dist\jquery.js:3939:9)
    at jQuery.fn.init.html (d:\development\vela mfg dashboard\source code\velamfgdashboard\velamfgdashboard\wwwroot\lib\jquery\dist\jquery.js:5959:11)
    at Object.<anonymous> (d:\development\vela mfg dashboard\source code\velamfgdashboard\velamfgdashboard\wwwroot\lib\jquery\dist\jquery.js:9892:10)

 

When i click on the "Detail" button for the second time, the treeview is populated with the items & the first item is indeed selected. But the onSelectMachine(e) is not executed - the content is still the default page.

Only when i manually click on the treeview item then only the onSelectMachine(e) is executed.

Treeview definition

@(Html.Kendo().TreeView()
    .Name("machinesTreeView")
    .DataTextField("MachineName")
    .TemplateId("treeview-template")
    .DataSource(dataSource => dataSource
        .Read(read => read
            .Action("Machines", "MachineDetails", new { productionLineName = Model.ProductionLineName })
        )                               
    )
    .Events(events => events
            .DataBound("onDataBound")
            .Select("onSelectMachine"))
)

 

script

function onDataBound(e) {
    $('#machinesTreeView').getKendoTreeView().select(".k-first")
}
 
function onSelectMachine(e) {
    var treeItem = $('#machinesTreeView').getKendoTreeView().dataItem(e.node);
    // Note: need to use Html.Raw
    var detailsUrl = '@Html.Raw( @Url.Action("Details", "MachineDetails",
                     new { productionLineName = Model.ProductionLineName, machineGuid = "-1" }))';
    detailsUrl = detailsUrl.replace("-1", treeItem.MachineGuid);
    // load content into the pane with ID="detailsPane"
    $('#detailsPane').load(detailsUrl);
}
0
Aleksandar
Telerik team
answered on 05 Sep 2019, 05:05 PM

Hi Joel,

I suspect the error observed is due to the JavaScript code being located in the partial view.

I modified the sample project to match more closely your scenario. A button is added and on click the partial view rendering the TreeView is rendered. The onDataBound and onSelect functions are also defined here:

<script>
    $('#details').on('click', function () {
        $.get({
            url: "/Home/LoadTreeView/",
            success: function (data) {
                $('#treeView').html(data)
            }
        })
    });

    function onDataBound(e) {
        var tree = $('#treeview').getKendoTreeView();
        tree.expand(".k-item");
        var firstElement = tree.items()[0];
        tree.select(firstElement);
        $('#data').text(firstElement.textContent);
    };

    function onSelect(e) {
        $('#data').text(e.node.firstChild.textContent)
    };
</script>

Once data binding is completed the first element of the tree is selected and it's value rendered. When you select a different option the selected option value is updated.

I hope this is more clear and helps you resolve your issue. Let me know if you have further questions.

Regards,
Aleksandar
Progress Telerik

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Joel
Top achievements
Rank 1
Iron
answered on 06 Sep 2019, 02:16 AM

Hi Aleksandar,

 You are right that the index.cshtml containing the treeview is a partial view.

 While your sample works, it still wouldn't help in my case.

 I ended up performing the event binding in the script & it works. (Note: i must say this is after much trial & error as i am very new in ASP.Net core & javascript)

$(document).ready(function () {
        // Note: use local treeview variable.
        var treeview = $("#machinesTreeView").data("kendoTreeView");
        treeview.bind("dataBound", onDataBound);
        treeview.bind("select", onSelectMachine);
    });

 

It is perhaps worth pointing out that the treeview is created inside a Splitter pane.

<div class="k-content wide">
@(Html.Kendo().Splitter()
              .Name("splitter")
              .Orientation(SplitterOrientation.Horizontal)
              .Panes(panes =>
              {
                  panes.Add()
                  .HtmlAttributes(new { id = "machinesPane"})
                  .Size("200px")
                  .Collapsible(false)
                  .Content(@<div class="pane-content k-content">
                        <h3>Machines</h3>
                        @*Tree view of machines*@
                        @(Html.Kendo().TreeView()
                            .Name("machinesTreeView")
                            .DataTextField("MachineName")
                            .TemplateId("treeview-template")
                            .DataSource(dataSource => dataSource
                                .Read(read => read
                                    .Action("Machines", "MachineDetails", new { productionLineName = Model.ProductionLineName })
                                )
                            )
                        )
                    </div>);
 
                  panes.Add()
                  .HtmlAttributes(new { id = "detailsPane" })
                  .Collapsible(false)
                  .Content(@<div class="pane-content">
                      <h2>Please select a machine</h2>
                    </div>);
              })
)
</div>
 
<script id="treeview-template" type="text/kendo-ui-template">
    <div class="d-flex">
        <div>
            <img src="@Url.Content("#=item.StateIconUrl#")" />
        </div>
        <div>
            <a id="machine-name">#=item.MachineName#</a>
        </div>
    </div>
</script>
0
Aleksandar
Telerik team
answered on 09 Sep 2019, 01:36 PM

Hi Joel,

I modified the provided code snippet a bit to match the desired outcome.

 @(Html.Kendo().Splitter()
        .Name("splitter")
        .Orientation(SplitterOrientation.Horizontal)
        .Panes(panes =>
        {
            panes.Add()
                .Size("200px")
                .Collapsible(false)
                .Content(@<div id="leftPane"></div>);
            panes.Add()
                .Collapsible(false)
                .Content(@<div>
                            <h2>Please select a machine</h2>
                            <div id="selectionContent"></div>
                            </div>);
        })
    )

In the left pane content I defined a div that would contain the TreeView and in the right pane a div for the selection details. Once the Details button is clicked, the partial view is returned and the TreeView is rendered in the left pane and the selection displayed in the right pane.

The modified sample project is attached for you to review.

Regards,
Aleksandar
Progress Telerik

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Joel
Top achievements
Rank 1
Iron
answered on 14 Sep 2019, 05:11 AM

Hi Aleksandar,

Thanks for your solution.
There is a nuget error when i try to compile your solution.

I am using VS2017 with Telerik.UI.for.AspNet.Core (2019.2.619)

Severity    Code    Description Project File    Line    Suppression State
Error   NU1102  Unable to find package Telerik.UI.for.AspNet.Core.Trial with version (>= 2019.2.619)
  - Found 1 version(s) in nuget.org [ Nearest version: 2018.3.911 ]
  - Found 0 version(s) in Microsoft Visual Studio Offline Packages
  - Found 0 version(s) in Kendo Mvc 2019.2.619
  - Found 0 version(s) in telerik.com   TreeView    D:\Coding\TreeView-SelectFirstNode2\TreeView_SelectFirstNode\TreeView\TreeView.csproj   1  

 

It works when downgraded to version 2018.3.911

I have reviewed your solution & the onSelect event is working in that environment.

However, it still wouldn't work in my project.

However, one difference compared to my application is that the details workspace will only be rendered when user click on the Details button.

Will that late rendering cause the "onDataBound/onSelect is not defined" error when it is clicked for the first time?

(Note: see ListView filtering with SharedDataSource post where i was told to put the script function at the top before the Kendo definition - which caught me by surprise that it has to be done in that way)

Here is the view containing the button group (where Dashboard & Details button resides), which is separated from the machine details view.

Index.cshtml

@(Html.Kendo().ButtonGroup()
.Name("workspaceButtons")
.Items(t =>
{
t.Add().Text("Dashboard");
t.Add().Text("Details");
})
.Events(ev => ev.Select("onSelect"))
 )
 
<script>
    var dashboardUrl = '@Url.Action("ShowDashboard", "ProductionDetails", new { productionLineName = Model.ProductionLineName })';
    var machineDetailsUrl = '@Url.Action("ShowMachineDetails", "ProductionDetails", new { productionLineName = Model.ProductionLineName })';
    function onSelect(e) {
        if (e.indices == 0) {
            // User click on the Dasboard button, load dashboard workpace
            $('#workspace').load(dashboardUrl);
        }
        else if (e.indices == 1) {
            // User click on the Details button, load dashboard workpace
            $('#workspace').load(machineDetailsUrl);
        }
    }
</script>

 

0
Aleksandar
Telerik team
answered on 17 Sep 2019, 12:43 PM

Hello Joel,

The NuGet error is due to the fact that I have used the Telerik.UI.for.AspNet.Core.Trial when creating the sample solution. As you already have an active License you can just remove the Telerik.UI.for.AspNet.Core.Trial from the NuGet packages for the solution and add reference to a licensed Telerik.UI.for.AspNet.Core package with the desired version. 

In the demo project I have tried to replicate your scenario as much as possible and to trigger the TreeView and show first item on button click. If the provided solution is not working in your project would it be possible to send a sample solution, where the issue is isolated, so I can investigate further? As for your concerns on issues with JavaScript errors of the type "onDataBound/onSelect is not defined" - those type of errors should not occur if the scripts have been referenced correctly.

Looking forward to your reply.

Regards,
Aleksandar
Progress Telerik

Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
TreeView
Asked by
Joel
Top achievements
Rank 1
Iron
Answers by
Aleksandar
Telerik team
Joel
Top achievements
Rank 1
Iron
Share this question
or