Accessing Child Object Properties/Looping in ClientTemplate

6 posts, 0 answers
  1. Vindaloo
    Vindaloo avatar
    3 posts
    Member since:
    Sep 2011

    Posted 01 Sep Link to this post

    Hi,

    I am trying to build a grid that has a detail template displaying child records. One of the columns in the grid (both the main grid and sub-grid) should display a dropdown menu. This is all mostly straightforward but I have a couple of issues/questions.

    1. The properties of the child objects do not seem to be available within the context of the detail template. How can I access those properties?

    2. I cannot seem to figure out how to add the dropdown menu in the grid column. I've tried to apply examples from the demos but keep getting errors like "Invalid Template" when attempting to use a client template or "Cannot convert lambda expression" when I try to use a foreach loop to add submenu items.

    Product: Telerik MVC UI

    Version: 2016.2.714

     

    Please take a look at the attached sample solution and point me in the right direction. (I could not add the Content and Scripts folders as they cause me to exceed the 2MB upload limit; however those folder are out of the box Telerik MVC UI scaffolded so I hope you can add them). Also see the Razor View code below.

    @{
        ViewBag.Title = "Home Page";
    }
    <div class="container-fluid">
        <div class="row">
            <div class="col-xs-18 col-md-12">
    @(Html.Kendo().Grid<TelerikMvcApp1.Models.Shop>()
            .Name("grid")
            .Columns(columns =>
            {
                columns.Bound(e => e.ShopId).Width(110);
                columns.Bound(e => e.ShopName);
                columns.Template(@<text></text>).ClientTemplate(
                    Html.Kendo().Menu()
                        .Name("menu_#=ShopId#")
                        .Items(menu =>
                        {
                            menu.Add().Text("Pay Affiliates").Items(nested =>
                            {
                                // How does one loop through the affiliates here?
                                nested.Add()
                                    .Text("[How to get affiliate name here]?");
                                   // .Action("ActionName", "ControllerName", new { ShopId = "#=ShopId#", AffiliateId = "#=AffiliateId#" });
                                    });

                            })
                        .ToClientTemplate().ToHtmlString()
                    );
            })
            .Sortable()
            .Pageable()
            .Scrollable()
            .ClientDetailTemplateId("affiliates-template")
            .HtmlAttributes(new { style = "height:600px;" })
            .DataSource(dataSource => dataSource
                .Ajax()
                .PageSize(6)
                .Read(read => read.Action("Shops_Read", "Grid"))
            )
            .Events(events => events.DataBound("dataBound"))
    )
          </div>
        </div>
    </div>
    <script id="affiliates-template" type="text/kendo-tmpl">
        @(Html.Kendo().Grid<TelerikMvcApp1.Models.Affiliate>()
                .Name("grid_#=ShopId#") // template expression, to be evaluated in the master context
                .Columns(columns =>
                {
                    columns.Bound(o => o.AffiliateId).Width(110).ClientTemplate(" \\#= AffiliateId \\#"); ;
                    columns.Bound(o => o.AffiliateName).ClientTemplate(" \\#= AffiliateName \\# promotes \\#= ShopName \\#");
                })
                .DataSource(dataSource => dataSource
                    .Ajax()
                    .PageSize(10)
                    .Read(read => read.Action("Affiliates_Read", "Grid", new { ShopId = "#=ShopId#" }))
                )
                .Pageable()
                .Sortable()
                .ToClientTemplate()
        )
    </script>
    <script>
        function dataBound() {
            this.expandRow(this.tbody.find("tr.k-master-row").first());
        }
    </script>

  2. Viktor Tachev
    Admin
    Viktor Tachev avatar
    1488 posts

    Posted 02 Sep Link to this post

    Hello Vindaloo,


    The Invalid Template message can be displayed if there are non-escaped hash characters. Please ensure that the characters are escaped. Also check out the following article that describes how you can use JavaScript and conditional logic in a ClientTemplate.


    Regarding the other error you describe, please examine the thread below that discusses similar behavior.


    With that said, would you elaborate in more detail on what you mean by  "properties of the child objects do not seem to be available within the context of the detail template"?

    I tested the behavior and the properties from the Affiliate model were accessed as expected on my end.

    Regards,
    Viktor Tachev
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Vindaloo
    Vindaloo avatar
    3 posts
    Member since:
    Sep 2011

    Posted 04 Sep in reply to Viktor Tachev Link to this post

    Hi Viktor,

    Thanks for your assistance. To clarify, the Affiliate Id column values are all "null" and the Affiliate Name in all rows is "undefined promotes Shop 1", instead of "1" and "Affiliate 1 promotes Shop 1", "2" and "Affiliate 2 promotes Shop 1", etc.

    Secondly I've reviewed the links you provided (I had read those resources already but reviewed them again) but still can't seem to work out how to iterate through a collection to create the 'Pay Affiliate' submenu.

    Are you able to upload the solution the you say works for you? Any help would be appreciated. Thanks.

  5. Viktor Tachev
    Admin
    Viktor Tachev avatar
    1488 posts

    Posted 07 Sep Link to this post

    Hello Vindaloo,

    Thank you for clarifying the scenario.

    The behavior you are seeing is expected because the Affiliates_Read method returns collection of Shop objects. However, the Grid expects Affiliate. In order to show the data you need to ensure that the correct data is returned from the server.

    public ActionResult Affiliates_Read(int shopId, [DataSourceRequest]DataSourceRequest request)
    {
        var result = SampleData.Shops
            .Where(shop => shop.ShopId == shopId).FirstOrDefault().Affiliates.AsEnumerable();
     
        return Json(result.ToDataSourceResult(request));
    }


    Regards,
    Viktor Tachev
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  6. Vindaloo
    Vindaloo avatar
    3 posts
    Member since:
    Sep 2011

    Posted 07 Sep in reply to Viktor Tachev Link to this post

    Hi Viktor,

    Thanks once again for your reply. You're right, I was returning the wrong type!

    Do you have any suggestion for my question about iterating through the list of Affiliates in a ClientTemplate? I can do this in C# within the server Template as shown in the extract below. But my grid is Ajax-bound and I'm struggling to write the same thing in ClientTemplate 'syntax'. I'd appreciate your guidance on this. Thanks.

                columns.Bound(e => e.ShopId).Width(110);
                columns.Bound(e => e.ShopName);
                columns.Template(@<text>
                    @Html.Kendo().Menu().Name("menu_"+@item.ShopId).Items(menu =>
               {
                   menu.Add().Text("Pay Affiliates").Items(nested =>
                   {
                       foreach (var affiliate in @item.Affiliates)
                       {
                           nested.Add()
                            .Text("Pay " + affiliate.AffiliateName)
                            .Action("PayAffiliate", "Payment", new { AffiliateId = affiliate.AffiliateId });
                       }
                   });
               })
                    </text>).ClientTemplate(
                    Html.Kendo().Menu()
                        .Name("menu_#=ShopId#")
                        .Items(menu =>
                        {
                            menu.Add().Text("Pay Affiliates").Items(nested =>
                            {
                               // How does one loop through the affiliates here?
                                "# for (var i=0; i<Affiliates.length; i++) { #" +
                                    "<a href='" +
                                        Url.Action("PayAffiliate", "Payment") +
                                        "/#= ShopId #/#= AffiliateId #'" +
                                    ">Pay #= AffiliateName #</a>" +
                                "# } #"
                            });

                        })
                        .ToClientTemplate().ToHtmlString()
                    );

  7. Viktor Tachev
    Admin
    Viktor Tachev avatar
    1488 posts

    Posted 09 Sep Link to this post

    Hi,

    When you are using Ajax binding you need to ensure that you are using ClientTemplate for the columns in the Grid component. As for using a for loop in the template please check out the examples in the article below.



    Regards,
    Viktor Tachev
    Telerik by Progress
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for ASP.NET MVC is VS 2017 Ready