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

Accessing Child Object Properties/Looping in ClientTemplate

5 Answers 980 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Vindaloo
Top achievements
Rank 1
Vindaloo asked on 01 Sep 2016, 05:35 AM

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>

5 Answers, 1 is accepted

Sort by
0
Viktor Tachev
Telerik team
answered on 02 Sep 2016, 01:26 PM
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
0
Vindaloo
Top achievements
Rank 1
answered on 04 Sep 2016, 07:27 PM

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.

0
Viktor Tachev
Telerik team
answered on 07 Sep 2016, 08:06 AM
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
0
Vindaloo
Top achievements
Rank 1
answered on 08 Sep 2016, 12:07 AM

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()
                );

0
Viktor Tachev
Telerik team
answered on 09 Sep 2016, 08:11 AM
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
Tags
Grid
Asked by
Vindaloo
Top achievements
Rank 1
Answers by
Viktor Tachev
Telerik team
Vindaloo
Top achievements
Rank 1
Share this question
or