最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Kendo UI Template: Invalid Template Error - Stack Overflow

programmeradmin1浏览0评论

I'm trying to make a Kendo UI grid template. When I run the following Chrome gives me the error message. I've left out most of the rest of the message because it is just printing out all the generated HTML and javascript to the console.

Uncaught Error: Invalid template:'<div class="k-widget&#32;k-grid" id="l...

I'm trying to follow the "detailtemplate.cshtml" example on the page .html

I'm having a hard time figuring out what I'm doing wrong. If I erase everything between the template's script tags and just put in some dumb HTML it all works fine so I'm sure the problem has something to do with the way I'm putting the kendo grid in.

This is the code I have in my HTML page. The problem is somewhere inside the <script> with the id "GridDetailsTemplate".

<div id="pendingApproval-tab">
    @(Html.Kendo().Grid<Moly.BusinessLogic.Entities.MolyAssayEntity>()
        .Name("pending-approval-grid")
        .HtmlAttributes(new { style = "overflow: auto; height: 600px"})
        .Columns(columns =>
        {
            columns.Bound(x => x.MolyLotID).HtmlAttributes(new {@class = "moly-lot-id"}).Hidden();
            columns.Template(@<div></div>).ClientTemplate("<input class='ready-checkbox' type='checkbox'/>").Title("Ready");
            columns.Bound(x => x.LotNo).Title("Lot").Groupable(false);
            columns.Bound(x => x.DateProduced).Format("{0:MM/dd/yy}").Title("Date");
            columns.Bound(x => x.NetWetWeight).Title("Net Wet Weight");
            columns.Bound(x => x.TareWeight).Title("Tare Weight");
            columns.Bound(x => x.NetDryWeight).Title("Dry Weight");
            columns.Bound(x => x.GrossWeight).Title("Gross Weight");
            columns.Bound(x => x.MolyWeight).Title("Lbs Mo");
            columns.Bound(x => x.MoisturePercent).Title("% H20");
            columns.Bound(x => x.MolyPercent).Title("Mo");
            columns.Bound(x => x.CopperPercent).Title("Cu");
            columns.Bound(x => x.LeadPercent).Title("Pb");
            columns.Bound(x => x.InsolublesPercent).Title("Insol");
            columns.Bound(x => x.ArsenicPercent).Title("As");
            columns.Bound(x => x.CalciumOxidePercent).Title("CaO");
            columns.Bound(x => x.IronPercent).Title("Fe");
            columns.Bound(x => x.MagnesiumOxidePercent).Title("MgO");
            columns.Bound(x => x.SodiumPercent).Title("Na");
            columns.Bound(x => x.BatchID).Title("Batch ID");
            columns.Bound(x => x.DunnageWt).Title("Dunnage Wt.");
            columns.Bound(x => x.Comment).Title("Comments");
        })
        .ToolBar(toolbar =>
        {
            toolbar.Save();
        })
        .Editable(editable => editable.Mode(GridEditMode.InCell))
        .ClientDetailTemplateId("GridDetailsTemplate")
        .DataSource(ds => ds
            .Ajax()
            .Batch(true)
            .Model(model => 
            {
                model.Id(m => m.MolyLotID);       
            })
            .Update(update => update.Action("UpdateMoly", "MolyLot"))
            .Read(read => read
                .Action("PendingApproval", "MolyLot")
                .Type(HttpVerbs.Post)
            )
        )
        .Events(events => events.DataBound("dataBound"))
    )
</div>

<script type="text/javascript">
    function dataBound() {
        this.expandRow(this.tbody.find("tr.k-master-row").first());
    }
</script>

<script id="GridDetailsTemplate" type="text/kendo-tmpl">
    @(Html.Kendo().Grid<Moly.BusinessLogic.Entities.UnroastedContainerEntity>()
        .Name("lot-details-grid")
        .Columns(columns =>
        {
            columns.Bound(x => x.ContainerNumber).Title("Number");
            columns.Bound(x => x.Type).Title("Type");
            columns.Bound(x => x.GrossWeight).Title("Gross Weight");
            columns.Bound(x => x.TareWeight).Title("Tare Weight");
        })
        .DataSource(DataSource => DataSource
            .Ajax()
            .Read(read => read.Action("GetBags", "MolyLot"))
        )
        .ToClientTemplate()
    )
</script>

Here is the "real" template that is generated with my template code:

<div class="k-widget&#32;k-grid" id="lot-details-grid">
    <table cellspacing="0">
        <colgroup>
            <col />
            <col />
            <col />
            <col />
        </colgroup>
        <thead class="k-grid-header">
            <tr>
                <th class="k-header" data-field="ContainerNumber" data-title="Number"
                scope="col"><span class="k-link">Number</span>
                </th>
                <th class="k-header" data-field="Type" data-title="Type" scope="col"><span class="k-link">Type</span>
                </th>
                <th class="k-header" data-field="GrossWeight" data-title="Gross&#32;Weight"
                scope="col"><span class="k-link">Gross Weight</span>
                </th>
                <th class="k-header" data-field="TareWeight" data-title="Tare&#32;Weight"
                scope="col"><span class="k-link">Tare Weight</span>
                </th>
            </tr>
        </thead>
        <tbody>
            <tr class="t-no-data">
                <td colspan="4"></td>
            </tr>
        </tbody>
    </table>
</div>
<script>
    jQuery(function () {
        jQuery("\#lot-details-grid").kendoGrid({
            "columns": [{
                "title": "Number",
                "field": "ContainerNumber",
                "encoded": true
            }, {
                "title": "Type",
                "field": "Type",
                "encoded": true
            }, {
                "title": "Gross Weight",
                "field": "GrossWeight",
                "encoded": true
            }, {
                "title": "Tare Weight",
                "field": "TareWeight",
                "encoded": true
            }],
            "scrollable": false,
            "dataSource": {
                "transport": {
                    "read": {
                        "url": "/Moly.Web/controller/action"
                    }
                },
                "serverPaging": true,
                "serverSorting": true,
                "serverFiltering": true,
                "serverGrouping": true,
                "serverAggregates": true,
                "type": "aspnetmvc-ajax",
                "filter": [],
                "schema": {
                    "data": "Data",
                    "total": "Total",
                    "errors": "Errors",
                    "model": {
                        "fields": {
                            "UnroastedContainerID": {
                                "type": "number"
                            },
                            "MolyLotID": {
                                "type": "number"
                            },
                            "GrossWeight": {
                                "type": "number"
                            },
                            "Type": {
                                "type": "string"
                            },
                            "TareWeight": {
                                "type": "number"
                            },
                            "ContainerNumber": {
                                "type": "string"
                            },
                            "Units": {
                                "type": "string"
                            },
                            "MolyLot": {
                                "type": "object"
                            }
                        }
                    }
                }
            },
            "detailTemplate": kendo.template($('\#GridDetailsTemplate').html())
        });
    }); < \ / script >
        ' Generated code:'
    var o, e = kendo.htmlEncode;
    with(data) {
        o = '\n        <div class="k-widget&';
        32;
        k - grid " id="
        lot - details - grid "><table cellspacing="
        0 "><colgroup><col /><col /><col /><col /></colgroup><thead class="
        k - grid - header "><tr><th class="
        k - header " data-field="
        ContainerNumber " data-title="
        Number " scope="
        col "><span class="
        k - link ">Number</span></th><th class="
        k - header " data-field="
        Type " data-title="
        Type " scope="
        col "><span class="
        k - link ">Type</span></th><th class="
        k - header " data-field="
        GrossWeight " data-title="
        Gross & ;
        o += '32;Weight" scope="col"><span class="k-link">Gross Weight</span></th><th class="k-header" data-field="TareWeight" data-title="Tare&';
        32;
        Weight " scope="
        col "><span class="
        k - link ">Tare Weight</span></th></tr></thead><tbody><tr class="
        t - no - data "><td colspan="
        4 "></td></tr></tbody></table></div><script>
    jQuery(function(){jQuery("#lot - details - grid ").kendoGrid({"
        columns ":[{"
        title ":"
        Number ","
        field ":"
        ContainerNumber ","
        encoded ":true},{"
        title ":"
        Type ","
        field ":"
        Type ","
        encoded ":true},{"
        title ":"
        Gross Weight ","
        field ":"
        GrossWeight ","
        encoded ":true},{"
        title ":"
        Tare Weight ","
        field ":"
        TareWeight ","
        encoded ":true}],"
        scrollable ":false,"
        dataSource ":{"
        transport ":{"
        read ":{"
        url ":" / Moly.Web / controller / action "}},"
        serverPaging ":true,"
        serverSorting ":true,"
        serverFiltering ":true,"
        serverGrouping ":true,"
        serverAggregates ":true,"
        type ":"
        aspnetmvc - ajax ","
        filter ":[],"
        schema ":{"
        data ":"
        Data ","
        total ":"
        Total ","
        errors ":"
        Errors ","
        model ":{"
        fields ":{"
        UnroastedContainerID ":{"
        type ":"
        number "},"
        MolyLotID ":{"
        type ":"
        number "},"
        GrossWeight ":{"
        type ":"
        number "},"
        Type ":{"
        type ":"
        string "},"
        TareWeight ":{"
        type ":"
        number "},"
        ContainerNumber ":{"
        type ":"
        string "},"
        Units ":{"
        type ":"
        string "},"
        MolyLot ":{"
        type ":"
        object "}}}}},"
        detailTemplate ":kendo.template($('#GridDetailsTemplate').html())});});
<\/script>
    ;o+=;}return o;'

I'm trying to make a Kendo UI grid template. When I run the following Chrome gives me the error message. I've left out most of the rest of the message because it is just printing out all the generated HTML and javascript to the console.

Uncaught Error: Invalid template:'<div class="k-widget&#32;k-grid" id="l...

I'm trying to follow the "detailtemplate.cshtml" example on the page http://demos.kendoui./web/grid/detailtemplate.html

I'm having a hard time figuring out what I'm doing wrong. If I erase everything between the template's script tags and just put in some dumb HTML it all works fine so I'm sure the problem has something to do with the way I'm putting the kendo grid in.

This is the code I have in my HTML page. The problem is somewhere inside the <script> with the id "GridDetailsTemplate".

<div id="pendingApproval-tab">
    @(Html.Kendo().Grid<Moly.BusinessLogic.Entities.MolyAssayEntity>()
        .Name("pending-approval-grid")
        .HtmlAttributes(new { style = "overflow: auto; height: 600px"})
        .Columns(columns =>
        {
            columns.Bound(x => x.MolyLotID).HtmlAttributes(new {@class = "moly-lot-id"}).Hidden();
            columns.Template(@<div></div>).ClientTemplate("<input class='ready-checkbox' type='checkbox'/>").Title("Ready");
            columns.Bound(x => x.LotNo).Title("Lot").Groupable(false);
            columns.Bound(x => x.DateProduced).Format("{0:MM/dd/yy}").Title("Date");
            columns.Bound(x => x.NetWetWeight).Title("Net Wet Weight");
            columns.Bound(x => x.TareWeight).Title("Tare Weight");
            columns.Bound(x => x.NetDryWeight).Title("Dry Weight");
            columns.Bound(x => x.GrossWeight).Title("Gross Weight");
            columns.Bound(x => x.MolyWeight).Title("Lbs Mo");
            columns.Bound(x => x.MoisturePercent).Title("% H20");
            columns.Bound(x => x.MolyPercent).Title("Mo");
            columns.Bound(x => x.CopperPercent).Title("Cu");
            columns.Bound(x => x.LeadPercent).Title("Pb");
            columns.Bound(x => x.InsolublesPercent).Title("Insol");
            columns.Bound(x => x.ArsenicPercent).Title("As");
            columns.Bound(x => x.CalciumOxidePercent).Title("CaO");
            columns.Bound(x => x.IronPercent).Title("Fe");
            columns.Bound(x => x.MagnesiumOxidePercent).Title("MgO");
            columns.Bound(x => x.SodiumPercent).Title("Na");
            columns.Bound(x => x.BatchID).Title("Batch ID");
            columns.Bound(x => x.DunnageWt).Title("Dunnage Wt.");
            columns.Bound(x => x.Comment).Title("Comments");
        })
        .ToolBar(toolbar =>
        {
            toolbar.Save();
        })
        .Editable(editable => editable.Mode(GridEditMode.InCell))
        .ClientDetailTemplateId("GridDetailsTemplate")
        .DataSource(ds => ds
            .Ajax()
            .Batch(true)
            .Model(model => 
            {
                model.Id(m => m.MolyLotID);       
            })
            .Update(update => update.Action("UpdateMoly", "MolyLot"))
            .Read(read => read
                .Action("PendingApproval", "MolyLot")
                .Type(HttpVerbs.Post)
            )
        )
        .Events(events => events.DataBound("dataBound"))
    )
</div>

<script type="text/javascript">
    function dataBound() {
        this.expandRow(this.tbody.find("tr.k-master-row").first());
    }
</script>

<script id="GridDetailsTemplate" type="text/kendo-tmpl">
    @(Html.Kendo().Grid<Moly.BusinessLogic.Entities.UnroastedContainerEntity>()
        .Name("lot-details-grid")
        .Columns(columns =>
        {
            columns.Bound(x => x.ContainerNumber).Title("Number");
            columns.Bound(x => x.Type).Title("Type");
            columns.Bound(x => x.GrossWeight).Title("Gross Weight");
            columns.Bound(x => x.TareWeight).Title("Tare Weight");
        })
        .DataSource(DataSource => DataSource
            .Ajax()
            .Read(read => read.Action("GetBags", "MolyLot"))
        )
        .ToClientTemplate()
    )
</script>

Here is the "real" template that is generated with my template code:

<div class="k-widget&#32;k-grid" id="lot-details-grid">
    <table cellspacing="0">
        <colgroup>
            <col />
            <col />
            <col />
            <col />
        </colgroup>
        <thead class="k-grid-header">
            <tr>
                <th class="k-header" data-field="ContainerNumber" data-title="Number"
                scope="col"><span class="k-link">Number</span>
                </th>
                <th class="k-header" data-field="Type" data-title="Type" scope="col"><span class="k-link">Type</span>
                </th>
                <th class="k-header" data-field="GrossWeight" data-title="Gross&#32;Weight"
                scope="col"><span class="k-link">Gross Weight</span>
                </th>
                <th class="k-header" data-field="TareWeight" data-title="Tare&#32;Weight"
                scope="col"><span class="k-link">Tare Weight</span>
                </th>
            </tr>
        </thead>
        <tbody>
            <tr class="t-no-data">
                <td colspan="4"></td>
            </tr>
        </tbody>
    </table>
</div>
<script>
    jQuery(function () {
        jQuery("\#lot-details-grid").kendoGrid({
            "columns": [{
                "title": "Number",
                "field": "ContainerNumber",
                "encoded": true
            }, {
                "title": "Type",
                "field": "Type",
                "encoded": true
            }, {
                "title": "Gross Weight",
                "field": "GrossWeight",
                "encoded": true
            }, {
                "title": "Tare Weight",
                "field": "TareWeight",
                "encoded": true
            }],
            "scrollable": false,
            "dataSource": {
                "transport": {
                    "read": {
                        "url": "/Moly.Web/controller/action"
                    }
                },
                "serverPaging": true,
                "serverSorting": true,
                "serverFiltering": true,
                "serverGrouping": true,
                "serverAggregates": true,
                "type": "aspnetmvc-ajax",
                "filter": [],
                "schema": {
                    "data": "Data",
                    "total": "Total",
                    "errors": "Errors",
                    "model": {
                        "fields": {
                            "UnroastedContainerID": {
                                "type": "number"
                            },
                            "MolyLotID": {
                                "type": "number"
                            },
                            "GrossWeight": {
                                "type": "number"
                            },
                            "Type": {
                                "type": "string"
                            },
                            "TareWeight": {
                                "type": "number"
                            },
                            "ContainerNumber": {
                                "type": "string"
                            },
                            "Units": {
                                "type": "string"
                            },
                            "MolyLot": {
                                "type": "object"
                            }
                        }
                    }
                }
            },
            "detailTemplate": kendo.template($('\#GridDetailsTemplate').html())
        });
    }); < \ / script >
        ' Generated code:'
    var o, e = kendo.htmlEncode;
    with(data) {
        o = '\n        <div class="k-widget&';
        32;
        k - grid " id="
        lot - details - grid "><table cellspacing="
        0 "><colgroup><col /><col /><col /><col /></colgroup><thead class="
        k - grid - header "><tr><th class="
        k - header " data-field="
        ContainerNumber " data-title="
        Number " scope="
        col "><span class="
        k - link ">Number</span></th><th class="
        k - header " data-field="
        Type " data-title="
        Type " scope="
        col "><span class="
        k - link ">Type</span></th><th class="
        k - header " data-field="
        GrossWeight " data-title="
        Gross & ;
        o += '32;Weight" scope="col"><span class="k-link">Gross Weight</span></th><th class="k-header" data-field="TareWeight" data-title="Tare&';
        32;
        Weight " scope="
        col "><span class="
        k - link ">Tare Weight</span></th></tr></thead><tbody><tr class="
        t - no - data "><td colspan="
        4 "></td></tr></tbody></table></div><script>
    jQuery(function(){jQuery("#lot - details - grid ").kendoGrid({"
        columns ":[{"
        title ":"
        Number ","
        field ":"
        ContainerNumber ","
        encoded ":true},{"
        title ":"
        Type ","
        field ":"
        Type ","
        encoded ":true},{"
        title ":"
        Gross Weight ","
        field ":"
        GrossWeight ","
        encoded ":true},{"
        title ":"
        Tare Weight ","
        field ":"
        TareWeight ","
        encoded ":true}],"
        scrollable ":false,"
        dataSource ":{"
        transport ":{"
        read ":{"
        url ":" / Moly.Web / controller / action "}},"
        serverPaging ":true,"
        serverSorting ":true,"
        serverFiltering ":true,"
        serverGrouping ":true,"
        serverAggregates ":true,"
        type ":"
        aspnetmvc - ajax ","
        filter ":[],"
        schema ":{"
        data ":"
        Data ","
        total ":"
        Total ","
        errors ":"
        Errors ","
        model ":{"
        fields ":{"
        UnroastedContainerID ":{"
        type ":"
        number "},"
        MolyLotID ":{"
        type ":"
        number "},"
        GrossWeight ":{"
        type ":"
        number "},"
        Type ":{"
        type ":"
        string "},"
        TareWeight ":{"
        type ":"
        number "},"
        ContainerNumber ":{"
        type ":"
        string "},"
        Units ":{"
        type ":"
        string "},"
        MolyLot ":{"
        type ":"
        object "}}}}},"
        detailTemplate ":kendo.template($('#GridDetailsTemplate').html())});});
<\/script>
    ;o+=;}return o;'
Share Improve this question edited Dec 21, 2012 at 22:28 Aaron Salazar asked Dec 21, 2012 at 21:29 Aaron SalazarAaron Salazar 4,53710 gold badges43 silver badges55 bronze badges 6
  • 1 The most interesting part is that it will be really helpful if you share the whole invalid template :) usually there is # symbol which breaks the tamplate. Share it so we can take a look – Petur Subev Commented Dec 21, 2012 at 22:24
  • The invalid template is there in the code section. It is the one with the ID "GridDetailsTemplate". – Aaron Salazar Commented Dec 21, 2012 at 22:26
  • I mean the error message. It contains the 'real' template :) – Petur Subev Commented Dec 21, 2012 at 22:28
  • Oh, I see what you meant. I've added that code. Of course it is minified so I de-minified it with some online tool. – Aaron Salazar Commented Dec 21, 2012 at 22:33
  • Could you check if the problem is not the same as the one [here][1] ? [1]: stackoverflow./questions/13616320/… – Petur Subev Commented Dec 21, 2012 at 22:46
 |  Show 1 more ment

3 Answers 3

Reset to default 6

I came across this problem yesterday, so I found a solution that doesn't require you to remove the encoder.

using System.Web;
using System.Web.Mvc;
using System.Web.Security.AntiXss;
using System.Web.Util;

namespace Your.Namespace.Here
{
    public static class KendoMvcExtensions
    {

        public static IHtmlString ToMvcClientTemplate(this MvcHtmlString mvcString)
        {
            if (HttpEncoder.Current.GetType() == typeof (AntiXssEncoder))
            {
                var initial = mvcString.ToHtmlString();
                var corrected = initial.Replace("\\u0026", "&").Replace("%23", "#").Replace("%3D", "=").Replace("&#32;", " ");
                return new HtmlString(corrected);
            }

            return mvcString;
        }
    }
}

It checks to see if the AntiXssEncoder is active, and if it is, it removes the offending encoding characters. You can take out the encoder check if you want, but don't change the order that the characters are replaced... it is structured that way because .NET will make some of the characters (especially validator text) have mixed encoding (UTF-8 and Unicode in the same character set, example: \u0026#32, which un-encoded once bees &#32 and un-encoded twice bees " ").

To use it, just call .ToMvcClientTemplate() at the end of any offending control declaration. In the case of the OP, you would put it right after the closing parenthesis before you close the div.

I'm keeping a copy of this code here in case someone somewhere else posts a better solution, as I've posted this code in several places.

HTH

For anyone having similar problem, i solved like this:

I have removed this line in the Web.config

<httpRuntime targetFramework="4.5" encoderType="System.Web.Security.AntiXss.AntiXssEncoder, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />.

I used a javascript function to clean my MVC partial before , I also added a remover for \ because I fount the MVC version added many in.

    function fixTemplate(template) {
    template = template.replace(/\\u0026/g, "&");
    template = template.replace(/%23/g, "#");
    template = template.replace(/%3D/g, "=");
    template = template.replace(/&#32/g, " ");
    template = template.replace(/\\/g, "");
    return template;
}

I don't know if there is a more efficient way to do this so feel free to ment.

发布评论

评论列表(0)

  1. 暂无评论
ok 不同模板 switch ($forum['model']) { /*case '0': include _include(APP_PATH . 'view/htm/read.htm'); break;*/ default: include _include(theme_load('read', $fid)); break; } } break; case '10': // 主题外链 / thread external link http_location(htmlspecialchars_decode(trim($thread['description']))); break; case '11': // 单页 / single page $attachlist = array(); $imagelist = array(); $thread['filelist'] = array(); $threadlist = NULL; $thread['files'] > 0 and list($attachlist, $imagelist, $thread['filelist']) = well_attach_find_by_tid($tid); $data = data_read_cache($tid); empty($data) and message(-1, lang('data_malformation')); $tidlist = $forum['threads'] ? page_find_by_fid($fid, $page, $pagesize) : NULL; if ($tidlist) { $tidarr = arrlist_values($tidlist, 'tid'); $threadlist = well_thread_find($tidarr, $pagesize); // 按之前tidlist排序 $threadlist = array2_sort_key($threadlist, $tidlist, 'tid'); } $allowpost = forum_access_user($fid, $gid, 'allowpost'); $allowupdate = forum_access_mod($fid, $gid, 'allowupdate'); $allowdelete = forum_access_mod($fid, $gid, 'allowdelete'); $access = array('allowpost' => $allowpost, 'allowupdate' => $allowupdate, 'allowdelete' => $allowdelete); $header['title'] = $thread['subject']; $header['mobile_link'] = $thread['url']; $header['keywords'] = $thread['keyword'] ? $thread['keyword'] : $thread['subject']; $header['description'] = $thread['description'] ? $thread['description'] : $thread['brief']; $_SESSION['fid'] = $fid; if ($ajax) { empty($conf['api_on']) and message(0, lang('closed')); $apilist['header'] = $header; $apilist['extra'] = $extra; $apilist['access'] = $access; $apilist['thread'] = well_thread_safe_info($thread); $apilist['thread_data'] = $data; $apilist['forum'] = $forum; $apilist['imagelist'] = $imagelist; $apilist['filelist'] = $thread['filelist']; $apilist['threadlist'] = $threadlist; message(0, $apilist); } else { include _include(theme_load('single_page', $fid)); } break; default: message(-1, lang('data_malformation')); break; } ?>