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

checkboxes not working in treeview

7 Answers 356 Views
TreeView
This is a migrated thread and some comments may be shown as answers.
Scott
Top achievements
Rank 1
Scott asked on 30 Oct 2015, 11:50 PM

When I try to add checkboxes to the TreeView,devtools int he browser show I am getting "Invalid Template"

This works (but no checkboxes).  But if I uncomment the ".Checkboxes part, it throws error.  I have tried many variants, including just ".Checkboxes(true)".

<script id="UserDetailsTemplate" type="text/kendo-tmpl">

    @*@Html.Kendo().TextBox().Value("foo #= User_Login#").Name("yoda_#=User_Login#")*@
    @(Html.Kendo()
          .TabStrip()
          .Name("userTabStrip_#=Person_ID#")
          .SelectedIndex(0)
          .Items((items) =>
                 {
                     items.Add()
                          .Text("Contact Info");
                     items.Add()
                          .Text("Permissions")
                          .Content(obj => Html.Kendo()
                                              .TreeView()
                                              .DataTextField("Name")
                                              .Name("userModulePermissions#=Person_ID#")
                                              //.Checkboxes(cbxConfig => cbxConfig.Enabled(true)
                                              //                                  .CheckChildren(true)
                                              //                                  .Name("checkedNodes"))
                                              .DataSource(d => d.Read("PermissionsTree_Read",
                                                                      "SettingsUsers"))
                                              .ToClientTemplate());
                     items.Add()
                          .Text("Group Membership");
                 })
          .ToClientTemplate()
          )
</script>

Here is the action the provides the tree data:

         public JsonResult PermissionsTree_Read(long? id)
        {
            var moduleId = id;
            var tracDB = new TRACEntities();
            // because modules & permissions are not same thing, we have to distinguish what "level" we are at in the tree
            // modules are root level, permissions (sub_sections) are next (leaf) level
            if (moduleId == null)
            {
                var result = GetOrgModules()
                    .Select(m => new {   
                                         id = m.Module_Type_ID,
                                         Name = m.Module_Type_Name,
                                         hasChildren = GetUserModuleSubsectionPermissions(m.Module_Type_ID).Any(),
                                         @checked = false
                    });
                return Json(result,
                            JsonRequestBehavior.AllowGet);
            }
            else
            {
                var result = GetUserModuleSubsectionPermissions((long) moduleId)
                    .Select(p => new {
                                         id = p.Sub_Section_Type_Id,
                                         Name = p.Sub_Section_Type_Desc,
                                         hasChildren = false,  //always leaves
                                         //@checked = false  //I have tried with and without this line -- it was just a guess that this was needed
                                     });
                return Json(result,
                            JsonRequestBehavior.AllowGet);
            }
        }

 

7 Answers, 1 is accepted

Sort by
0
Scott
Top achievements
Rank 1
answered on 31 Oct 2015, 12:21 AM

Here is the error message:

 Error: Invalid template:' <div class="k-tabstrip-wrapper"><div class="k-widget k-tabstrip k-header" id="userTabStrip_#=Person_ID#"><ul class="k-reset k-tabstrip-items"><li class="k-item k-state-default k-state-active"><span class="k-link">Contact Info</span></li><li class="k-item k-state-default"><a class="k-link" href="\#userTabStrip_#=Person_ID#-2">Permissions</a></li><li class="k-item k-state-default"><span class="k-link">Group Membership</span></li></ul><div class="k-content k-state-active" id="userTabStrip_#=Person_ID#-1" style="display:block"></div><div class="k-content" id="userTabStrip_#=Person_ID#-2"><div class="k-widget k-treeview k-reset" id="userModulePermissions#=Person_ID#"></div><script> jQuery(function(){jQuery("\#userModulePermissions#=Person_ID#").kendoTreeView({"dataSource":{"transport":{"read":{"url":"/TRAC/TracMvc/SettingsUsers/PermissionsTree_Read"}},"schema":{"model":{}}},"checkboxes":{"name":"checkedNodes","template":"\u003cinput type=\u0027checkbox\u0027 name=\u0027#= treeview.checkboxes.name #\u0027 #= item.checked ? \u0027checked\u0027 : \u0027\u0027 # value=\u0027#= item.id #\u0027 /\u003e","checkChildren":true},"dataTextField":["Name"]});}); <\/script></div><div class="k-content" id="userTabStrip_#=Person_ID#-3"></div></div></div><script> jQuery(function(){jQuery("\#userTabStrip_#=Person_ID#").kendoTabStrip({});}); <\/script> ' Generated code:'var $kendoOutput, $kendoHtmlEncode = kendo.htmlEncode;with(data){$kendoOutput='\n \n <div class="k-tabstrip-wrapper"><div class="k-widget k-tabstrip k-header" id="userTabStrip_'+(Person_ID)+'"><ul class="k-reset k-tabstrip-items"><li class="k-item k-state-default k-state-active"><span class="k-link">Contact Info</span></li><li class="k-item k-state-default"><a class="k-link" href="#userTabStrip_'+(Person_ID)+'-2">Permissions</a></li><li class="k-item k-state-default"><span class="k-link">Group Membership</span></li></ul><div class="k-content k-state-active" id="userTabStrip_'+(Person_ID)+'-1" style="display:block"></div><div class="k-content" id="userTabStrip_'+(Person_ID)+'-2"><div class="k-widget k-treeview k-reset" id="userModulePermissions'+(Person_ID)+'"></div><script>\n\tjQuery(function(){jQuery("#userModulePermissions'+(Person_ID)+'").kendoTreeView({"dataSource":{"transport":{"read":{"url":"/TRAC/TracMvc/SettingsUsers/PermissionsTree_Read"}},"schema":{"model":{}}},"checkboxes":{"name":"checkedNodes","template":"\u003cinput type=\u0027checkbox\u0027 name=\u0027'+( treeview.checkboxes.name )+'\u0027 '+( item.checked ? \u0027checked\u0027 : \u0027\u0027 )+' value=\u0027'+( item.id )+'\u0027 /\u003e","checkChildren":true},"dataTextField":["Name"]});});\n<\/script></div><div class="k-content" id="userTabStrip_'+(Person_ID)+'-3"></div></div></div><script>\n\tjQuery(function(){jQuery("#userTabStrip_'+(Person_ID)+'").kendoTabStrip({});});\n<\/script>\n';}return $kendoOutput;'

...ath.floor(f.length/2),e}catch(a){throw Error(r.format("Invalid template:'{0}' Ge...

0
Accepted
Dimo
Telerik team
answered on 02 Nov 2015, 05:52 PM
Hi Scott,

The problem is caused by the fact that the TreeView uses internally a Kendo UI template for the checkboxes, and the # characters inside this template are not escaped (and they cannot be escaped automatically).

http://docs.telerik.com/kendo-ui/framework/templates/overview#template-syntax

Generally, a possible approach is to escape the nested template expressions manually with custom code like this:

@{
    var treeView = Html.Kendo().TreeView()
                    .Name("TREEVIEW-NAME")
                    .ToClientTemplate().ToHtmlString().Replace("#", "\\#").Replace(@"jQuery(""\\#TREEVIEW-NAME"")", @"jQuery(""\\#TREEVIEW-NAME"")");
}
<script id="template" type="text/kendo-tmpl">
 
    @Html.Raw(treeView)
 
</script>


However, this will be rather cumbersome in a Grid detail template, because you need unique TreeView names, so my primary recommendation is to use client-side TreeView initialization syntax (i.e HTML + Javascript), which will allow you to have full control over the HTML markup and Javascript initialization statement.

http://docs.telerik.com/kendo-ui/api/javascript/ui/treeview

Regards,
Dimo
Telerik
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
Scott
Top achievements
Rank 1
answered on 02 Nov 2015, 07:07 PM

I'm not sure I understand.  It seemed to work fine without checkboxes.  Only with checkboxes does the problem arise.  Your answer seems to indicate this should be a problem with all treeviews embedded within a template.

I am starting to think that the problem of "escaping" with nested templates is just too much of a hassle.  

But this seriously cripples the value of the MVC kendo() helpers in razor pages, the point of which is to avoid writing javascript.

0
Scott
Top achievements
Rank 1
answered on 02 Nov 2015, 07:13 PM

 The other thing I would ask is isn't this a bug in .ToClientTemplate()?  Shouldn't it recognize a nested template & escape as needed?

0
Accepted
Dimo
Telerik team
answered on 04 Nov 2015, 03:56 PM
Hi Scott,

When TreeView checkboxes are enabled, the widget generates and renders a Kendo UI template that includes expressions with # characters. These characters should be treated as literals by the Grid, however, they are not escaped, so the Grid tries to evaluate the TreeView's template expressions as well, which causes the Javascript error.

The TreeView itself is not able to escape its template expressions automatically, because the widget is not aware of the exact level of its template nesting. In other words, the TreeView is not aware if it is part of a first-level client template, or if it is placed in a nested client template, which is injected in another client template, and so on.

The main task of .ToClientTemplate() is to escape the closing </script> tag that the widget renders.

Regards,
Dimo
Telerik
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
Scott
Top achievements
Rank 1
answered on 04 Nov 2015, 09:26 PM

Is there a general guide or tutorial on nesting of client templates, and how to escape them to the correct number of levels?

Or is the best advice to not use client templates for complicated nesting of widgets, and take a different approach?

0
Dimo
Telerik team
answered on 06 Nov 2015, 03:44 PM
Hi Scott,

The rule of thumb is to add additional "\\" for each new level of client template nesting. I am afraid there is no automated way to measure the nesting level programmatically, so the number of backslashes should be hard-coded.

http://docs.telerik.com/kendo-ui/framework/templates/overview#escaping-hash-literals

The above procedure is possible to follow in most cases, so client templates can be used in complicated scenarios as well. The problem in this particular case is that the TreeView defines a client template, which you don't have control over, so you can't prepend backslashes, depending on the nesting level.

Regards,
Dimo
Telerik
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
TreeView
Asked by
Scott
Top achievements
Rank 1
Answers by
Scott
Top achievements
Rank 1
Dimo
Telerik team
Share this question
or