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

Can a Grid Column.ClientTemplate be a Kendo ListView?

6 Answers 698 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Tim
Top achievements
Rank 1
Tim asked on 04 Dec 2012, 09:14 PM
Is it possilbe to embed a List View into a Kendo Grid column via a client template?  
If it's possible how to you bind the List view to the Permmisions list? (Permissions being an IEnumberable<PermissionModel>) 

@(Html.Kendo().Grid<RoleModel>()
    .Name("RoleGrid")
    .Columns(x =>
                 {
                     x.Bound(p => p.Name).Width(150);
                     x.Bound(p => p.Description).Width(350);
                     x.Bound(p => p.Permissions).ClientTemplate("test");                   
                     
                     x.Command(command =>
                                   {
                                       command.Edit();
                                       command.Destroy();
                                   });
                 }))


<script type="text/x-kendo-template" id="test" >
    @(Html.Kendo().ListView<PermissionModel>().Name("listView")
                                                                                     .AutoBind(true)
                                                                                     .ToClientTemplate()
                                                                                     )
</script>

6 Answers, 1 is accepted

Sort by
0
Vladimir Iliev
Telerik team
answered on 06 Dec 2012, 05:28 PM
Hi Tim,

 
Basically you can use the DataBound event of the Grid to iterate over current Grid rows and initialize ListView from div element that is placed in the client template of the column with current row dataItem for dataSource data. Please check the example below (the EmployeeList contains IEnumerable<Employee>):

@(Html.Kendo().Grid<ForeignKeyColumnDemo.Models.Order>()
    .Name("Grid")   
    .Columns(columns => {       
        columns.Bound(p => p.OrderID);
        columns.ForeignKey(p => p.EmployeeId, (System.Collections.IEnumerable)ViewData["employees"], "EmployeeId", "Name");
        columns.Bound(p => p.OrderDescription);
        columns.Bound(p => p.OrderDate).Format("{0:d}");
        columns.Bound(p => p.EmployeeList).ClientTemplate("<div class='TreeView'></div>");
    })   
    .Pageable()
    .Sortable()
    .Scrollable()
    .Filterable()
    .Events(e => e.DataBound("onDataBound"))
    .DataSource(dataSource => dataSource       
        .Ajax()     
        .ServerOperation(false)
        .Read(read => read.Action("ForeignKeyColumn_Read", "Home"))
    )
)
 
<script type="text/x-kendo-tmpl" id="template">
    <p>
        <h3>Employee name: ${Name}</h3>
        <strong>Employee id:</strong> ${EmployeeId}
    </p>
</script>
 
<script>   
    function onDataBound(e) {
        $("#Grid tbody tr .TreeView").each(function () {
            var currentDataItem = $("#Grid").data("kendoGrid").dataItem($(this).closest("tr"));
 
            $(this).kendoListView({
                dataSource: {
                    data: currentDataItem.EmployeeList
                },
                template: kendo.template($("#template").html())
            })
        })
    }
</script>


Kind Regards,
Vladimir Iliev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Tim
Top achievements
Rank 1
answered on 06 Dec 2012, 07:18 PM
Thanks that works great.  However if the grid is editable: ".Editable(editable => editable.Mode(GridEditMode.PopUp))"

Then use an edit command to open the pop-up and then click cancel, the List view gets cleared out for the row you were editing.  If you click update, the List view does not clean out. (It will even bring the list view back.  I assume this is because Update causes the databound event to occur.) 

What event does Cancel cause?
0
Vladimir Iliev
Telerik team
answered on 10 Dec 2012, 08:14 AM
Hi Tim,

Basically the Cancel action does not trigger any event and in order to initialize the ListView again you should use the Edit event to bind Click event to the Cancel button. Please check the example below:


Grid events:

.Events(e => {
    e.DataBound("onDataBound");
    e.Edit("onEdit");
})


Edit event handler:
function onEdit(e) {
    //replace with your ListView element class name
    var listViewClass = "ListView";
    //Bind click event to the Cancel button
    $(e.container).find(".k-grid-cancel").on("mousedown touchend", function () {
        //get current row UID
        currentRowUID = $(event.srcElement).closest("tr").attr("data-uid");
 
        setTimeout(function () {
            //find the refreshed row
            currentRow = $("[data-uid=" + currentRowUID + "]");
            //get it's dataItem
            currentDataItem = $("#Grid").data("kendoGrid").dataItem(currentRow);
            //initialize the ListView
            currentRow.find("." + listViewClass).kendoListView({
                dataSource: {
                    data: currentDataItem.EmployeeList
                },
                template: kendo.template($("#template").html())
            })
        },100)
    })
}

DataBound event handler:
function onDataBound(e) {
    var listViewClass = "ListView";
 
    $("#Grid tbody tr ." + listViewClass).each(function () {
        var currentDataItem = $("#Grid").data("kendoGrid").dataItem($(this).closest("tr"));
        $(this).kendoListView({
            dataSource: {
                data: currentDataItem.EmployeeList
            },
            template: kendo.template($("#template").html())
        })
    })
}


Kind Regards,
Vladimir Iliev
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Mike
Top achievements
Rank 1
answered on 20 Dec 2012, 10:18 PM
I implemented this on my Grid, but it looks like the onEdit javascript function is not working correctly.  On 

currentRowUID = $(event.srcElement).closest("tr").attr("data-uid");
It finds a srcElement, but it cannot find a "closest" tr, making the currentRowUID undefined.  My full code below:

@model IEnumerable<ConocoPhillips.CCApprovals.Models.TemplateActivityModel>
 
@(
 Html.Kendo().Grid(Model).Name("Activities")
    .Columns(columns =>
    {
        //columns.Bound(t => t.Id).Visible(false);
        columns.Bound(t => t.Level).Width("1em").Groupable(false);
        columns.Bound(t => t.Approvers).Groupable(false).Sortable(false).ClientTemplate("<div class='ListView'></div>");
        columns.Bound(t => t.IsInform).ClientTemplate(
            "# if(IsInform == true){ #" + @"Inform Only" +
            "# } else { #" + @"Requires Approval" +
            "#}#").EditorViewData(new { radioDictionary = new Dictionary<String, String>() { { "true", "Inform Only" }, { "false", "Requires Approval" } } }).EditorTemplateName("RadioButtonEditor");
        columns.Bound(t => t.IsMutuallyInclusive).ClientTemplate(
            "# if(IsMutuallyInclusive == true){ #" + @"Requires All Approvers" +
            "# } else { #" + @"Only One Approver Required" +
            "#}#").EditorViewData(new { radioDictionary = new Dictionary<String, String>() { { "true", "Requires All Approvers" }, { "false", "Only One Approver Required" } } }).EditorTemplateName("RadioButtonEditor");
        columns.Command(command => { command.Destroy(); command.Edit(); }).Title("Actions");
    })
    .ToolBar(toolbar => { toolbar.Create(); toolbar.Custom().Text("Refresh").Url("javascript:refreshGrid('Activities')").HtmlAttributes(new { @class = "refreshButton", style = "float: right; height: 30px; width: 30px;" }); })
    .Groupable()
    .Pageable()
    .Sortable()
    .Filterable()
    .Editable(editable => editable.Mode(GridEditMode.PopUp))
    .Events(e =>
    {
        e.DataBound("onDataBound");
        e.Edit("onEdit");
    })
    .DataSource(datasource => datasource
        .Ajax()
        .Model(model =>
        {
            model.Id(t => t.Id);
            model.Field(t => t.Id).Editable(false);
        })
        .Events(events => events.Error("error_handler"))
        //.Sort(c => c.Add("Level").Ascending())
        .Create(create => create.Action("Activities_Create", "Templates"))
        .Read(read => read.Action("Activities_Read", "Templates", new { @templateId = Model.First().TemplateId }))
        .Update(update => update.Action("Activities_Update", "Templates"))
        .Destroy(destroy => destroy.Action("Activities_Destroy", "Templates"))
    )
)
<script type="text/x-kendo-tmpl" id="template">
    <p>
        <h3>Name: ${Name}</h3>
        <strong>Id:</strong> ${UserID}
    </p>
</script>
<script type="text/javascript">
    function error_handler(e) {
        if (e.errors) {
            var message = "Errors:\n";
            $.each(e.errors, function (key, value) {
                if ('errors' in value) {
                    $.each(value.errors, function () {
                        message += this + "\n";
                    });
                }
            });
            alert(message);
        }
    }
 
    function onEdit(e) {
        //replace with your ListView element class name
        var listViewClass = "ListView";
        //Bind click event to the Cancel button
        $(e.container).find(".k-grid-cancel").on("mousedown touchend", function () {
            //get current row UID
            currentRowUID = $(event.srcElement).closest("tr").attr("data-uid");
 
            setTimeout(function () {
                //find the refreshed row
                currentRow = $("[data-uid=" + currentRowUID + "]");
                //get it's dataItem
                currentDataItem = $("#Activities").data("kendoGrid").dataItem(currentRow);
                //initialize the ListView
                currentRow.find("." + listViewClass).kendoListView({
                    dataSource: {
                        data: currentDataItem.Approvers
                    },
                    template: kendo.template($("#template").html())
                });
            }, 100);
        });
 
        kendoize();
    }
 
    function onDataBound(e) {
        var listViewClass = "ListView";
 
        $("#Activities tbody tr ." + listViewClass).each(function () {
            var currentDataItem = $("#Activities").data("kendoGrid").dataItem($(this).closest("tr"));
            $(this).kendoListView({
                dataSource: {
                    data: currentDataItem.Approvers
                },
                template: kendo.template($("#template").html())
            });
        });
 
        kendoize();
    }
</script>
(Ignore the kendoize method call).  Any help?
0
Tim
Top achievements
Rank 1
answered on 20 Dec 2012, 10:30 PM
Hi Mike,
 I had the same problem.

I found the X "close" button and the cancel button both have different sources.  Because of this I ended up making an event for each.

I would just use Chrome/Firebug too and insert a debugger; call in the function.  Then find $(event.srcElement) on the page and figure what navigation you need to do manually, while in debugger. 

$(e.container).find(".k-grid-cancel").on("mousedown touchend", function () {               
 //get current row UID                
currentRowUID = $(event.srcElement).closest("div").parent().attr('data-uid');
$(e.container).parent().find(
'.k-i-close').on("mousedown touchend", function () {                
//get current row UID                
currentRowUID = $(event.srcElement).parent().parent().parent().parent().find('.k-window-content').attr('data-uid');
0
Mike
Top achievements
Rank 1
answered on 20 Dec 2012, 10:48 PM
Lucky for me, your exact navigation worked for my grid too!  Thanks a bunch!
Tags
Grid
Asked by
Tim
Top achievements
Rank 1
Answers by
Vladimir Iliev
Telerik team
Tim
Top achievements
Rank 1
Mike
Top achievements
Rank 1
Share this question
or