I have recently installed VS2012 and there I have Kendo 2012.3.1114. I just copied all the code from the VS2010 to VS2012 and it all just worked except for one small point. I have a nested grid and I use a template for the detail. That template is shown below. It works fine in the 2010 project but 2012 always says "Uncaught Error: Invalid template:" and the template is identical. If I comment out the .ClientTemplateId statement, the main grid displays just fine. If I paste the template into its own Partial View and display it separately, it displays just fine but it always errors as a template.
I have tried commenting out parts of the template, even getting to the point where it o nly has the Name and ToClientTemplate calls and it STILL errors. So I just wonder if something is broken with templates in the latest version of Kendo or the latest version of VS. The template is below:
<
script
id
=
"paneTemplate"
type
=
"text/kendo-tmpl"
>
@(Html.Kendo().Grid<
AWSQBCC.Models.Pane
>()
.Name("Panes_#=LiteId#")
.Columns(columns =>
{
//columns.Bound(p => p.PaneId);
columns.Bound(p => p.Sequence);
columns.Bound(p => p.LiteId).Hidden();
columns.ForeignKey(p => p.GlassId, (System.Collections.IEnumerable)ViewData["glasses"], "GlassId", "GlassType").Title("Glass Type");
columns.Command(command => { command.Edit(); command.Destroy(); });
})
.DataSource(dataSource => dataSource
.Ajax()
.Sort(sort =>
{
sort.Add(p => p.Sequence);
})
.Read(read => read.Action("Pane_Read", "Lite", new { id = "#=LiteId#" }))
.Destroy(destroy => destroy.Action("Pane_Delete", "Lite"))
.Update(update => update.Action("Pane_Update", "Lite"))
.Create(create => create.Action("Pane_Create", "Lite", new { id = "#=LiteId#" }))
.Model(model =>
{
model.Id(p => p.PaneId);
model.Field(p => p.PaneId).Editable(false);
model.Field(p => p.LiteId).Editable(false);
model.Field(p => p.GlassId);
})
.Events(events => { events.Error("error"); })
)
.ToolBar(commands => commands.Create())
.Editable(editable => editable.Mode(GridEditMode.InLine))
//.Events(events => events.DataBound("refresh"))
.ToClientTemplate())
</
script
>
9 Answers, 1 is accepted
<
script
id
=
"paneTemplate"
type
=
"text/kendo-tmpl"
>
<
div
class
=
"k-widget k-grid"
id
=
"Panes_#=LiteId#"
><
div
class
=
"k-toolbar k-grid-toolbar k-grid-top"
><
a
class
=
"k-button k-button-icontext k-grid-add"
href
=
"/Lite/Pane_Read/%23%3dLiteId%23?Panes_%23%3DLiteId%23-mode=insert"
><
span
class
=
"k-icon k-add"
></
span
>Add new item</
a
></
div
><
table
cellspacing
=
"0"
><
colgroup
><
col
/><
col
/><
col
/></
colgroup
><
thead
class
=
"k-grid-header"
><
tr
><
th
class
=
"k-header"
data-field
=
"Sequence"
data-title
=
"Sequence"
scope
=
"col"
><
span
class
=
"k-link"
>Sequence</
span
></
th
><
th
class
=
"k-header"
data-field
=
"LiteId"
data-title
=
"Lite Id"
scope
=
"col"
style
=
"display:none"
><
span
class
=
"k-link"
>Lite Id</
span
></
th
><
th
class
=
"k-header"
data-field
=
"GlassId"
data-title
=
"Glass Type"
scope
=
"col"
><
span
class
=
"k-link"
>Glass Type</
span
></
th
><
th
class
=
"k-header"
scope
=
"col"
><
span
class
=
"k-link"
> </
span
></
th
></
tr
></
thead
><
tbody
><
tr
class
=
"t-no-data"
><
td
colspan
=
"3"
></
td
></
tr
></
tbody
></
table
></
div
><
script
>
jQuery(function(){jQuery("\#Panes_#=LiteId#").kendoGrid({"columns":[{"title":"Sequence","field":"Sequence","encoded":true,"editor":"\u003cinput class=\"text-box\u0026#32;single-line\" data-val=\"true\" data-val-number=\"The\u0026#32;field\u0026#32;Sequence\u0026#32;must\u0026#32;be\u0026#32;a\u0026#32;number.\" data-val-required=\"The\u0026#32;Sequence\u0026#32;field\u0026#32;is\u0026#32;required.\" id=\"Sequence\" name=\"Sequence\" type=\"number\" value=\"0\" /\u003e\u003cspan class=\"field-validation-valid\" data-valmsg-for=\"Sequence\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e"},{"title":"Lite Id","hidden":true,"field":"LiteId","encoded":true},{"title":"Glass Type","field":"GlassId","encoded":true,"editor":"\u003cinput data-val=\"true\" data-val-number=\"The\u0026#32;field\u0026#32;GlassId\u0026#32;must\u0026#32;be\u0026#32;a\u0026#32;number.\" data-val-required=\"The\u0026#32;GlassId\u0026#32;field\u0026#32;is\u0026#32;required.\" id=\"GlassId\" name=\"GlassId\" type=\"text\" value=\"0\" /\u003e\u003cscript\u003e\tjQuery(function(){jQuery(\"\\#GlassId\").kendoDropDownList({\"dataSource\":[{\"Text\":\"Clear 3.0mm\",\"Value\":\"2\"},{\"Text\":\"Clear 3.9mm\",\"Value\":\"3\"},{\"Text\":\"Clear 4.7mm\",\"Value\":\"4\"},{\"Text\":\"Clear 5.7mm\",\"Value\":\"5\"},{\"Text\":\"LowE 240 3.0mm\",\"Value\":\"13\"},{\"Text\":\"LowE 240 3.9mm\",\"Value\":\"14\"},{\"Text\":\"LowE 240 4.7mm\",\"Value\":\"15\"},{\"Text\":\"LowE 240 5.7mm\",\"Value\":\"16\"},{\"Text\":\"LowE 270 3.0mm\",\"Value\":\"9\"},{\"Text\":\"LowE 270 3.9mm\",\"Value\":\"10\"},{\"Text\":\"LowE 270 4.7mm\",\"Value\":\"11\"},{\"Text\":\"LowE 270 5.7mm\",\"Value\":\"12\"},{\"Text\":\"LowE 366 3.0mm\",\"Value\":\"1\"},{\"Text\":\"LowE 366 3.9mm\",\"Value\":\"6\"},{\"Text\":\"LowE 366 4.7mm\",\"Value\":\"7\"},{\"Text\":\"LowE 366 5.7mm\",\"Value\":\"8\"},{\"Text\":\"Obscure 3.0mm\",\"Value\":\"17\"},{\"Text\":\"Obscure 3.9mm\",\"Value\":\"18\"},{\"Text\":\"Obscure 4.7mm\",\"Value\":\"19\"},{\"Text\":\"Obscure 5.7mm\",\"Value\":\"20\"}],\"dataTextField\":\"Text\",\"dataValueField\":\"Value\"});});\u003c\\/script\u003e\u003cspan class=\"field-validation-valid\" data-valmsg-for=\"GlassId\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e","values":[{"text":"Clear 3.0mm","value":"2"},{"text":"Clear 3.9mm","value":"3"},{"text":"Clear 4.7mm","value":"4"},{"text":"Clear 5.7mm","value":"5"},{"text":"LowE 240 3.0mm","value":"13"},{"text":"LowE 240 3.9mm","value":"14"},{"text":"LowE 240 4.7mm","value":"15"},{"text":"LowE 240 5.7mm","value":"16"},{"text":"LowE 270 3.0mm","value":"9"},{"text":"LowE 270 3.9mm","value":"10"},{"text":"LowE 270 4.7mm","value":"11"},{"text":"LowE 270 5.7mm","value":"12"},{"text":"LowE 366 3.0mm","value":"1"},{"text":"LowE 366 3.9mm","value":"6"},{"text":"LowE 366 4.7mm","value":"7"},{"text":"LowE 366 5.7mm","value":"8"},{"text":"Obscure 3.0mm","value":"17"},{"text":"Obscure 3.9mm","value":"18"},{"text":"Obscure 4.7mm","value":"19"},{"text":"Obscure 5.7mm","value":"20"}]},{"command":[{"name":"edit","buttonType":"ImageAndText","text":"Edit"},{"name":"destroy","buttonType":"ImageAndText","text":"Delete"}]}],"scrollable":false,"editable":{"confirmation":"Are you sure you want to delete this item?","mode":"inline","create":true,"update":true,"destroy":true},"toolbar":{"command":[{"name":null,"buttonType":"ImageAndText","text":"Add new item"}]},"dataSource":{"transport":{"read":{"url":"/Lite/Pane_Read/#=LiteId#"},"update":{"url":"/Lite/Pane_Update"},"create":{"url":"/Lite/Pane_Create/#=LiteId#"},"destroy":{"url":"/Lite/Pane_Delete"}},"serverPaging":true,"serverSorting":true,"serverFiltering":true,"serverGrouping":true,"serverAggregates":true,"type":"aspnetmvc-ajax","sort":[{"field":"Sequence","dir":"asc"}],"filter":[],"error":error,"schema":{"data":"Data","total":"Total","errors":"Errors","model":{"id":"PaneId","fields":{"PaneId":{"editable":false,"type":"number"},"Sequence":{"type":"number"},"LiteId":{"editable":false,"type":"number"},"GlassId":{"type":"number"}}}}}});});
<\/script>
</
script
>
This is pretty urgent for me since I can't even see a work around.
The reason for the problem is the AntiXssEncoder which is enabled in the Web.config httpRuntime configuration:
<
httpRuntime
targetFramework
=
"4.5"
encoderType
=
"System.Web.Security.AntiXss.AntiXssEncoder, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
/>
Kind regards,
Daniel
the Telerik team
The pros for the helpers would be that they enable intellisense and compile time checking of variable names and they can use Reflection to know more about the fields being encoded. But a possible con is that it may not be possible to code everything in a helper that is possible in the html. At the very least the helper might lag a release behind the html upgrades. I'm interested in people's thoughts on this.
Also, what are the implications of turning of the AntiXssEncoder and is it possible to turn it off just for some pages?
Thanks for your feedback.
Yes, not everything possible with Kendo UI Web/DataViz is possible with the MVC wrappers because they are configured to work with the MVC Controllers and not all options can be set.
Regarding the encoder - by default MVC uses the HttpEncoder so the application should still be protected from cross-site scripting attacks. It is possible to change the encoder in a particular view by setting the current encoder("System.Web.Security.AntiXss.AntiXssEncoder.Current") but this will change the encoder for the entire application as well.
It is also possible to specify the characters that does not need to be encoded with the MarkAsSafe method though I have not found a way to allow spaces in the attributes which is the reason for the error in most cases.
Daniel
the Telerik team
I've opened a support ticket to get it included in the next release. Feel free to lean on them as well.
HTH,
Robert McLaws
AdvancedREI.com
:)
I checked my web.config, there is no reference to AntiXssEncoder.
Here is my client detail template:
<
script
id
=
"incompleteTrainTemplate"
type
=
"text/kendo-tmpl"
>
@(Html.Kendo().Grid<
CNX.Domain.Entities.EDIRailcar
>()
.Name("IncompleteTrains_#=Id#")
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Columns(columns =>
{
columns.Bound(o => o.Id).Visible(false);
columns.Bound(o => o.EDI_417_TRAIN_GUID).Visible(false);
columns.Bound(o => o.EQUIPMENT_INITIAL);
columns.Bound(o => o.EQUIPMENT_NUMBER);
columns.Bound(o => o.WEIGHT);
columns.Bound(o => o.TARE_WEIGHT);
columns.Bound(o => o.STATUS);
})
.DataSource(dataSource => dataSource.Ajax()
.PageSize(10)
.Read(read => read.Action("IncompleteTrainsDetail", "MenuTrain", new { edi417Guid = "#=Id#" })
.Type(HttpVerbs.Post))
.Update(update => update.Action("IncompleteTrainsUpdate", "MenuTrain", Model).Type(HttpVerbs.Post))
.Model(model => model.Id(x => x.Id))
)
.Pageable()
.Sortable()
.Filterable()
.Events(ev => ev.Save("function(e){setTimeout(function(){$('#IncompleteTrains_\#=Id\#').data('kendoGrid').dataSource.sync()})}"))
.ToClientTemplate()
)
</
script
>
Is this not the correct way to reference it?
You should escape the character used for the id selector instead of the ones used for the template expression:
.Events(ev => ev.Save(
"function(e){setTimeout(function(){$('\\#IncompleteTrains_#=Id#').data('kendoGrid').dataSource.sync()})}"
))
.Events(ev => ev.Save(
"function(e){var that = this;setTimeout(function(){that.dataSource.sync()})}"
))
Regards,
Daniel
Telerik