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

Grid Hierarchy with Editor template in the child grid.

7 Answers 735 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Jerry
Top achievements
Rank 1
Jerry asked on 30 Apr 2014, 10:56 PM
I'm trying to get some editor templates in child grids.  They work fine in the parent grid but when I try to add them to the child grid, the .ToClientTemplate() returns invalid Template format.  Not sure what else to do. Thnx


Here's the code :
(Parent grid):
@(Html.Kendo().Grid<PDT.Dashboard.Models.CategoryVM>()
                    .Name("CategoryGrid")
                    .HtmlAttributes(new { @class = "expandable-rows grid-within-grid" })
                    .Editable(editable => { editable.Mode(GridEditMode.InLine); editable.DisplayDeleteConfirmation(false); })
                    .Columns(columns =>
                    {
                        columns.Bound(a => a.CategoryIconId)
                            .Title("Icon")
                            .ClientTemplate("<span class='icon30 gray-icon notes-icon-#= CategoryIconId #'></span>")
                            .EditorTemplateName("EditCategoryIcon")
                        columns.Bound(a => a.CategoryName)
                            .EditorTemplateName("EditCategoryName");
                        columns.Bound(a => a.IsDeleted)
                            .Title("Active")
                            .ClientTemplate("<span> #= IsDeleted ? 'Active' : 'Inactive' #</span>")
                        columns.Bound(a => a.SortOrder)
                            .EditorTemplateName("EditSortOrder")
                        columns.Command(command => { command.Edit().HtmlAttributes(new { title = "Edit" }); }).Width(55);
                    })
                    .Sortable()
                    .Pageable(p => p.PageSizes(new[] { 10, 20, 50, 100 }))
                    .ClientDetailTemplateId("AdminSubCategoryTemplate")
                    .DataSource(dataSource => dataSource
                        .Ajax()
                        .PageSize(20)
                        .Read(read => read.Action("GetCategories", "Permissions"))
                        .Create(create => create.Action("AddCategory", "Permissions"))
                        .Update(update => update.Action("UpdateCategory", "Permissions"))
                        .Model(model => { model.Id(m => m.CategoryId);  })
                                    .Sort(s => { s.Add(m => m.SortOrder).Ascending(); })
                        .Events(e =>
                        {
                            e.Error("categoryErrorHandler");
                        })
                    ))






​ @(Html.Kendo().Grid<PDT.Dashboard.Models.SubCategoryVM>()
        .Name("grid_#=CategoryId#")
        .Editable(editable => { editable.Mode(GridEditMode.InLine); editable.DisplayDeleteConfirmation(false); })
        .ToolBar(tb => tb.Create())
        .Columns(columns =>
        {
            columns.Bound(a => a.SubCategoryName)
                            .EditorTemplateName("EditSubCategoryName");
            columns.Bound(a => a.IsDeleted)
                .Title("Active")
                .ClientTemplate("<span> \\#= IsDeleted ? 'Active' : 'Inactive' \\#</span>")
            columns.Bound(a => a.SortOrder).Width(100);
            columns.Command(command => { command.Edit(); }).Width(70);
        })
        .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(5)
            .Read(read => read.Action("GetSubCategories", "Permissions", new { categoryId = "#=CategoryId#" }))
            .Create(create => create.Action("AddSubCategory", "Permissions", new { parentCategoryId = "#=CategoryId#" }))
            .Update(update => update.Action("UpdateSubCategory", "Permissions"))
            .Model(model =>
            {
                model.Id(m => m.SubCategoryId);
                model.Field(m => m.CategoryId).Editable(false);
            })
            .Sort(s => { s.Add(m => m.SortOrder).Ascending(); })
            .Events(e =>
            {
                e.Error("subcategoryErrorHandler");
            })
        )
        .Pageable()
        .Sortable()
        .ToClientTemplate()
    )


EditCategoryName.cshtml:

<span class="k-widget k-numerictextbox" >
<span class="k-numeric-wrap k-state-default k-expand-padding">
        <input class="k-input text-box single-line" id="CategoryName" name="CategoryName" type="text" value="" data-bind="value:CategoryName">
    </span>
</span>






EditSubCategoryName.cshtml:
<span class="k-widget k-numerictextbox" >
<span class="k-numeric-wrap k-state-default k-expand-padding">
        <input class="k-input text-box single-line" id="SubCategoryName" name="SubCategoryName" type="text" value="" data-bind="value:SubCategoryName">
    </span>
</span>










7 Answers, 1 is accepted

Sort by
0
Petur Subev
Telerik team
answered on 02 May 2014, 12:23 PM
Hello Jerry,

Can you modify the following code library demo to replicate the case so we can search for a way to resolve it?

http://www.telerik.com/support/code-library/grid-ajax-hierarchy-editing

Kind Regards,
Petur Subev
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Jerry
Top achievements
Rank 1
answered on 09 May 2014, 12:45 AM
Ok so I think I figured out the problem with the editorTemplateName issue, and it seems that I wasn't escaping a format("\\#")  and that was causing the toclientTemplate to fail.  

I have another issue regarding Hierarchy grids and I have replicated it on the included sample project.  The issue is we're trying to do custom validation with red boxes around offending input boxes.  In our case, we're adding a new sub category(child) to an existing category(parent), and on error, we can't get the parentid such that we can locate the child grid (which uses parent id in the name, just like the example on the demo website) so that we can add the class to the input box with the duplicate sub category name.

Any help with this issue is greatly appreciated.
0
Petur Subev
Telerik team
answered on 12 May 2014, 12:32 PM
Hello Jerry,

Indeed inside the error handler you cannot get reference to the grid object. The most appropriate way to understand what the parent id is would be to get it from the server response. Since it is not available inside the error event, one way to overcome this would be to save it in a global variable.

e.g.

@{
    ViewBag.Title = "Home Page";
}
 
<script type="text/kendo" id="OrderDetailsTemplate">
  @(Html.Kendo().Grid<OrderDetailViewModel>()
        .Name("OrderDetails_#=OrderID#")
        .Columns(columns =>
        {           
            columns.Bound(od => od.Quantity).Width(200);
            columns.Bound(od => od.UnitPrice).Width(200);
            columns.Bound(od => od.Discount);
            columns.ForeignKey(od=> od.ProductID, (System.Collections.IEnumerable)ViewData["Products"], "ProductID", "ProductName");
            columns.Command(command =>
            {
                command.Edit();
                command.Destroy();
            });
        })
        .ToolBar(tools => tools.Create())
        .Pageable().Sortable().Filterable()
        .DataSource(source=> source.Ajax()
                .Model(model =>
                    {
                        model.Id(o => o.UIID);
                        model.Field(o => o.UIID).Editable(false);
                        model.Field(o => o.ProductID).DefaultValue(1);
                    })
                .Events(events => events.Error("error_handler"))
                .Read(read => read.Action("Read_OrderDetails", "OrderDetails", new { id = "#=OrderID#" }))
                .Update(update => update.Action("Update_OrderDetail", "OrderDetails"))
                .Create(create => create.Action("Create_OrderDetail", "OrderDetails", new { id = "#=OrderID#" }))
                .Destroy(destroy => destroy.Action("Destroy_OrderDetail", "OrderDetails")))                
        .ToClientTemplate()               
    )
           
</script>
 
 
<script type="text/kendo" id="OrdersTemplate">
  @(Html.Kendo().Grid<OrderViewModel>()
        .Name("Orders_#=EmployeeID#")
        .Columns(columns =>
        {
            columns.Bound(o => o.OrderID).Width(101);
            columns.Bound(o => o.ShipCountry).Width(140);
            columns.Bound(o => o.ShipAddress).Width(200);
            columns.Bound(o => o.ShipName).Width(200);
            columns.Bound(o => o.ShippedDate).Format("{0:d}");
            columns.Bound(o => o.SortOrder)
                .EditorTemplateName("SortOrderEditor")
                .Width(125);
            columns.Command(command =>
            {
                command.Edit();
                command.Destroy();
            });
        })
        .ToolBar(tools => tools.Create())
        .Pageable().Sortable().Filterable()
        .DataSource(source => source.Ajax()
            .Model(model =>
                    {
                        model.Id(o => o.OrderID);
                        model.Field(o => o.OrderID).Editable(false);
                    })
            .Events(events => events.Error("our_error_handler").RequestEnd("onRequestEnd"))
            .Read(read => read.Action("Read_Orders", "Orders", new { id = "#=EmployeeID#" }))
            .Update(update => update.Action("Update_Order", "Orders"))
            .Create(create => create.Action("Create_Order", "Orders", new { id = "#=EmployeeID#" }))
            .Destroy(destroy => destroy.Action("Destroy_Order", "Orders")))
        .ClientDetailTemplateId("OrderDetailsTemplate")
        .ToClientTemplate()
    )
     
</script>
 
@(Html.Kendo().Grid<EmployeeViewModel>()
    .Name("Employees")
    .Columns(columns =>
    {
        columns.Bound(e => e.FirstName).Width(140);
        columns.Bound(e => e.LastName).Width(140);
        columns.Bound(e => e.Title).Width(200);
        columns.Bound(e => e.Country).Width(200);
        columns.Bound(e => e.City);
        columns.Command(command =>
            {
                command.Edit();
                command.Destroy();
            });
    })
    .ToolBar(tools => tools.Create())
    .Pageable().Sortable().Filterable()
    .DataSource(source => source.Ajax()
            .Model(model =>
                {
                    model.Id(e => e.EmployeeID);
                    model.Field(e => e.EmployeeID).Editable(false);
                })
                .Events(events => events.Error("error_handler"))
                .Read(read => read.Action("Read_Employees", "Employees"))
                .Update(update => update.Action("Update_Employee", "Employees"))
                .Create(create => create.Action("Create_Employee", "Employees"))
                .Destroy(destroy => destroy.Action("Destroy_Employee", "Employees")))
    .ClientDetailTemplateId("OrdersTemplate")
 
<script type="text/javascript">
    var parentId = 0;
 
    function onRequestEnd(e) {
        if (e.response.Errors) {
            parentId = e.response.Data[0].ParentId;
        }
    }
 
    function error_handler(e) {
        debugger;
        e.preventDefault();
        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);
        }
    }
 
    ///This is where we currently have the problem, we can't get the parent Id on error (during Add) so that we can find the offending input and add our validaiton class
    function our_error_handler(e) {
        debugger;
        //How do I get the parent Id from e?  It doesn't rebind to the data.
        //Obviously will never hit the error code because it's hard-coded to 0. I just need to see how to get the real parent Id.
        if (parentId > 0) {
            var grid = $("#Orders_" + parentId).data("kendoGrid");
            var gridElement = grid.editable.element;
            var errorMessage = "";
 
            grid.one("dataBinding", function (e) {
                e.preventDefault();   // cancel grid rebind to not show like the record was added even though there's an error.
                $.each(args.errors, function (key, value) {
                    if (value.errors) {
                        //Using ShipName here for example. We actually have sub categories that can't be duplicates.
                        if (key == "ShipName") {
                            gridElement.find("td[data-container-for=" + key + "] input").addClass("input-validation-error-custom");
                        }
                        else {
                            gridElement.find("td[data-container-for=" + key + "] span")
                            .first().addClass("input-validation-error-custom");
                        }
                        errorMessage += value.errors[0] + '<br />';
                    }
                });
                //Run our popup error handler... replaced with alert for this example.
                //Utility.showError(errorMessage);
                alert(errorMessage);
            });
        }
    }
</script>

I hope this gives you the basic idea.

Regards,
Petur Subev
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Kelso
Top achievements
Rank 1
answered on 26 Feb 2015, 02:41 PM
.ClientTemplate("<span> \\#= IsDeleted ? 'Active' : 'Inactive' \\#</span>")

Having # in the client template causes this issue for me. Also if you use .filterable in version 2014.2.903 in the client template will also cause this issue.
0
Kelso
Top achievements
Rank 1
answered on 26 Feb 2015, 02:43 PM
.ClientTemplate("<span> \\#= IsDeleted ? 'Active' : 'Inactive' \\#</span>") having # in the client template causes this and .filterable() in the client template in version 2014.2.903 also causes this issue.
0
Kelso
Top achievements
Rank 1
answered on 26 Feb 2015, 02:44 PM
Having .ClientTemplate("<span> \\#= IsDeleted ? 'Active' : 'Inactive' \\#</span>" in the client template will cause this and having .filterable() in version 2014.2.903 will also cause this.
0
Kelso
Top achievements
Rank 1
answered on 26 Feb 2015, 02:45 PM
Sorry I was having problems posting, its the # in the client template specifically.
Tags
Grid
Asked by
Jerry
Top achievements
Rank 1
Answers by
Petur Subev
Telerik team
Jerry
Top achievements
Rank 1
Kelso
Top achievements
Rank 1
Share this question
or