Using Client Templates
The Telerik UI for ASP.NET MVC components provide templating options that let you customize and control their appearance or integrate other UI components. Many use cases require displaying a specified component element (for example, item, option, button, cell, and more) differently based on a specified condition or overriding its default look and feel. In such scenarios, client templates come in handy.
The templating options use Kendo UI Templates, which offer a way to create HTML chunks that can be merged automatically with JavaScript code. They are a substitute for traditional HTML string-building in JavaScript.
The available template types are:
- Inline Client Templates
- External Client Templates
- Partial Client Templates
- Content Security Policy Templates
Inline Client Templates
You can create an inline client template as a string
or a JavaScript
function. They are suitable for small templates.
The following example demonstrates how to define the template for the DropDownList items as a string
. To display the Model properties values as HTML, use the hash syntax (#=#
).
@(Html.Kendo().DropDownList()
.Name("customers")
.HtmlAttributes(new { style = "width: 100%" })
.DataTextField("ContactName")
.DataValueField("CustomerID")
.Template("<span class=\"contact-name\" style=\"color: \\#ffa96a;\"><b>#=ContactName #</b><p>#=CompanyName#</p></span>") // You can display the values of Model properties that are available in the data returned from the Read request.
.DataSource(source =>
{
source.Read(read =>
{
read.Action("Template_GetCustomers", "DropDownList");
});
})
.Height(400)
)
To set an inline template as a function, pass the name of the function in the template method.
@(Html.Kendo().DropDownList()
.Name("customers")
.HtmlAttributes(new { style = "width: 100%" })
.DataTextField("ContactName")
.DataValueField("CustomerID")
.Template("#=getDropDownItem(data)#")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("Template_GetCustomers", "DropDownList");
});
})
.Height(400)
)
<script>
function getDropDownItem(data) {
if (data.Country == "Germany") {
let templateString = ({ ContactName }) => `<span style="color: orange;"><b> ${kendo.htmlEncode(ContactName)}</b></span>`;
let template = kendo.template(templateString);
return template(data);
} else {
let templateString = ({ ContactName, CompanyName }) => `<span style="color: blue;"><b> ${kendo.htmlEncode(ContactName)}</b> --> ID: <i>${kendo.htmlEncode(CompanyName)}</i></span>`;
let template = kendo.template(templateString);
return template(data);
}
}
</script>
External Client Templates
The external client templates are preferable for more advanced and complex scenarios. Within an external template, you can add HTML markup and JavaScript logic, as long as the JavaScript is properly formatted with the Kendo UI Template syntax.
The external template is a Kendo UI Template defined by using HTML script blocks, which is suitable for larger templates.
For example, you can define an external client template for a Grid column by following the steps below:
-
Set up a script block with the
text/x-kendo-template
type.<script type="text/x-kendo-template"> <!--Template content here--> </script>
-
Add an
id
to the template script and ensure its value is unique on the page.<script type="text/x-kendo-template" id="myTemplate"> </script>
-
Specify the desired JavaScript logic in the template. For example, display the relevant information based on the value of the
Discontinued
property.<script type="text/x-kendo-template" id="myTemplate"> <div class="product-item"> #if(Discontinued){# <div><b>Active order</b></div> #}else{# <div>#: ProductName # is already shipped</div> #}# </div> </script>
-
Pass the
id
of the template to theClientTemplateId
method of the Grid column.@(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.ProductViewModel>() .Name("Grid") .Columns(columns => { columns.Bound(p => p.ProductName); columns.Bound(p => p.UnitPrice); columns.Bound(p => p.Discontinued).ClientTemplateId("myTemplate"); }) .Pageable() .Scrollable() .DataSource(dataSource => dataSource .Ajax() .PageSize(20) .Read("Products_Read", "Grid") ) )
Also, you can integrate Telerik UI for ASP.NET MVC components in the external client templates by using the HTML Helpers .
Adding HTML Helpers inside External Client Templates
By default, every Telerik UI HtmlHelper renders a script
element immediately after its HTML markup. If the helper declaration is placed inside an external Kendo UI template, the nested script elements will be invalid. The ToClientTemplate
method instructs the helper to escape its own script element so that it can be nested.
<script id="template" type="text/x-kendo-template">
@(Html.Kendo().NumericTextBox()
.Name("age")
.ToClientTemplate()
)
</script>
<div id="container"></div>
<script>
$(function () {
var template = kendo.template($("#template").html());
$("#container").append(template);
})
</script>
Partial Client Templates
As of the R1 SP1 2023 release, the majority of the Telerik UI for ASP.NET MVC components expose the ability to include arbitrary client template content within the boundaries of a Partial View by using the respective component's new TemplateView
method.
The example below illustrates how to incorporate the Grid Toolbar's template content within a Partial View.
@(Html.Kendo().Grid<Kendo.Mvc.Examples.Models.ProductViewModel>()
.Name("grid")
.Columns(columns => {
columns.Bound(p => p.ProductID).Visible(true).Width(100);
columns.Bound(p => p.ProductName);
columns.Bound(p => p.UnitPrice).Width(150);
columns.Bound(p => p.QuantityPerUnit);
})
.ToolBar(toolbar => {
toolbar.ClientTemplateView(Html.Partial("_ToolbarTemplatePartial"));
})
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
.Model(model => model.Id(p => p.ProductID))
.Read("ToolbarTemplate_Read", "Grid")
)
)
<div class="toolbar">
<label class="category-label" for="category">Show products by category:</label>
@(Html.Kendo().DropDownList()
.Name("categories")
.OptionLabel("All")
.DataTextField("CategoryName")
.DataValueField("CategoryID")
.HtmlAttributes(new { style = "width: 150px;" })
.DataSource(ds =>
{
ds.Read("ToolbarTemplate_Categories", "Grid");
})
.ToClientTemplate()
)
</div>
Content Security Policy (CSP) Templates
As of the R1 SP1 2023 release, Telerik UI for ASP.NET MVC addresses the content security policy issues related to the usafe-eval
directive for components except for the Spreadsheet.
To remove the unsafe-eval
keyword from the meta tag of your application, you must convert all client templates (inline, external, and partial templates) into CSP-compatible templates.
To create CSP-compatible templates, use any of the following approaches:
Using the Template Component
As of R2 2023 release, you can take advantage of the Template component that provides options for integrating a variety of Telerik UI for ASP.NET MVC components and HTML
code into the templates of the components. You can declare the desired UI component into the Template component configuration and use all options as they are available in the nested component itself.
In the preceding code:
- The
AddHtml()
of the Template component insertsHTML
into the column template of the TreeList. TheTitle
is a property of theModel
that binds to the TreeList. - The
TemplateComponentName()
defines the name of a custom Popup editor template, which is configured through the Template component.
@(Html.Kendo().TreeList<EmployeeViewModel>()
.Name("treelist")
.Columns(columns =>
{
columns.Add().Field(e => e.Name)
.Template(Html.Kendo().Template().AddHtml("<span style='color: green;'>${data.Name} - ${data.Title}</span>"));
})
.Editable(e => e.Mode("popup").TemplateComponentName("CustomPopupEditor"))
//Other configuration
)
//~/Views/Shared/EditorTemplates/CustomPopupEditor.cshtml
@model EmployeeViewModel
@(Html.Kendo().Template()
.AddHtml("<div class=\"k-edit-field\">")
.AddComponent(tbox => tbox
.TextBoxFor(model => model.Name)
.Label(l => l.Content("Full name:").Floating(true))
)
.AddHtml("</div>")
)
Using Client-Side Handler
Telerik UI for ASP.NET MVC introduces an overload of the components template methods that accept a JavaScript
function name. It allows you to define the template content through a client-side handler. This way, you can prevent the components from being dependent on the unsafe-eval
and reuse the templates within multiple components in different application pages.
The example below demonstrates how to load the item template of a ComboBox through a function handler.
@(Html.Kendo().ComboBox()
.Name("customers")
.DataTextField("ContactName")
.DataValueField("CustomerID")
.HtmlAttributes(new { style = "width: 100%;" })
.DataSource(source =>
{
source.Read(read =>
{
read.Action("Template_GetCustomers", "ComboBox");
});
})
.TemplateHandler("itemTemplateHandler")
)
function itemTemplateHandler(data) {
if(data.Country == "Germany"){
return `<div><b>${data.ContactName}</b></div>`;
} else {
return `<div><i>${data.ContactTitle}</i> - <b>${data.ContactName}</b></div>`;
}
}