Grid Hierarchy with Editor template in the child grid.

8 posts, 0 answers
  1. Jerry
    Jerry avatar
    3 posts
    Member since:
    Jun 2013

    Posted 30 Apr 2014 Link to this post

    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>










  2. Petur Subev
    Admin
    Petur Subev avatar
    1882 posts

    Posted 02 May 2014 Link to this post

    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.

     
  3. Jerry
    Jerry avatar
    3 posts
    Member since:
    Jun 2013

    Posted 08 May 2014 Link to this post

    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.
  4. Petur Subev
    Admin
    Petur Subev avatar
    1882 posts

    Posted 12 May 2014 Link to this post

    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.

     
  5. Kelso
    Kelso avatar
    36 posts
    Member since:
    Dec 2013

    Posted 26 Feb 2015 in reply to Petur Subev Link to this post

    .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.
  6. Kelso
    Kelso avatar
    36 posts
    Member since:
    Dec 2013

    Posted 26 Feb 2015 in reply to Petur Subev Link to this post

    .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.
  7. Kelso
    Kelso avatar
    36 posts
    Member since:
    Dec 2013

    Posted 26 Feb 2015 in reply to Petur Subev Link to this post

    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.
  8. Kelso
    Kelso avatar
    36 posts
    Member since:
    Dec 2013

    Posted 26 Feb 2015 in reply to Kelso Link to this post

    Sorry I was having problems posting, its the # in the client template specifically.
Back to Top