DevExtreme jQuery/JS - Templates
Templates allow you to customize DevExtreme widgets. This article gives an overview of the capabilities that DevExtreme provides for implementing and applying templates.
Default Templates
Default templates are based on data source fields. You can control appearance by adding or removing particular fields from data source objects. For example, the List widget's default template for items contains the text, visible, and disabled fields, among others. If you assign the following array to the widget's items or dataSource option, the first item will be disabled, the second hidden, both of them will have text, and the third item will render a custom markup:
function customMarkup() { var d = document.createElement("div"); d.innerHTML = "<i>Oranges</i>"; return d; } var fruits = [ { text: "Apples", disabled: true }, { text: "Lemons", visible: false }, { template: customMarkup } ];
You can achieve the same in the markup using the dxItem component that supports default and custom templates. Do not set the widget's dataSource option in this case.
jQuery
<div id="list"> <div data-options="dxItem: { text: 'Apples', disabled: true }"></div> <div data-options="dxItem: { text: 'Lemons', visible: false }"></div> <div data-options="dxItem: { }"> <i>Oranges</i> </div> </div>
$(function() { $("#list").dxList({/* ... */}); });
Angular
<dx-list> <dxi-item text="Apples" [disabled]="true"></dxi-item> <dxi-item text="Lemons" [visible]="false"></dxi-item> <dxi-item> <i>Oranges</i> </dxi-item> </dx-list>
import { DxListModule } from "devextreme-angular"; // ... @NgModule({ imports: [ // ... DxListModule ], // ... }) export class AppModule { }
AngularJS
<div dx-list="{ }"> <div data-options="dxItem: { text: 'Apples', disabled: true }"></div> <div data-options="dxItem: { text: 'Lemons', visible: false }"></div> <div data-options="dxItem: { }"> <i>Oranges</i> </div> </div>
angular.module('DemoApp', ['dx']) .controller('DemoController', function ($scope) { // ... });
Knockout
<div data-bind="dxList: { ... }"> <div data-options="dxItem: { text: 'Apples', disabled: true }"></div> <div data-options="dxItem: { text: 'Lemons', visible: false }"></div> <div data-options="dxItem: { }"> <i>Oranges</i> </div> </div>
var viewModel = { // ... }; ko.applyBindings(viewModel);
Vue
<template> <DxList> <DxItem text="Apples" :disabled="true" /> <DxItem text="Lemons" :visible="false" /> <DxItem> <template #default> <i>Oranges</i> </template> </DxItem> </DxList> </template> <script> import 'devextreme/dist/css/dx.common.css'; import 'devextreme/dist/css/dx.light.css'; import DxList, { DxItem } from 'devextreme-vue/list'; export default { components: { DxList, DxItem } } </script>
React
import React from 'react'; import 'devextreme/dist/css/dx.common.css'; import 'devextreme/dist/css/dx.light.css'; import List, { Item } from 'devextreme-react/list'; class App extends React.Component { render() { return ( <List> <Item text="Apples" disabled={true} /> <Item text="Lemons" visible={false} /> <Item> <i>Oranges</i> </Item> </List> ); } } export default App;
Default templates and the fields available in them depend on the widget. Refer to the items option description of a particular widget for a list of template fields.
Custom Templates
Templates are passed as options that end with ...Template (in jQuery, Angular, and Vue) or ...Render/...Component (in React).
Each template has access to the following parameters:
data
A data source object or an object with fields specific to a particular template. For information on the contents ofdata
, refer to the Template Data section of the template's API reference article.index
A zero-based index of the item in the collection. Available only in collection widget templates.element
A jQuery element that represents the widget element being customized. Available only if you use jQuery.
The following code shows how to declare a template and use these parameters. This code declares an itemTemplate for the List widget:
jQuery
$(function() { $("#listContainer").dxList({ items: [ { itemProperty: "someValue" }, // ... ], itemTemplate: function (data, index, element) { return index + " - " + data.itemProperty; // ===== or using the "element" parameter ===== const $item = $("<div>").text( index + " - " + data.itemProperty ); element.append($item); } }); });
Angular
<dx-list [items]="listData" itemTemplate="list-item"> <div *dxTemplate="let data of 'list-item'; let index = index"> {{index}} - {{data.itemProperty}} </div> </dx-list>
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { listData = [ { itemProperty: "someValue" }, // ... ] }
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { DxListModule } from 'devextreme-angular'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, DxListModule ], providers: [ ], bootstrap: [AppComponent] }) export class AppModule { }
Vue
<template> <DxList :items="listData" item-template="list-item"> <template #list-item="{ data, index }"> {{ index }} - {{ data.itemProperty }} </template> </DxList> </template> <script> import 'devextreme/dist/css/dx.common.css'; import 'devextreme/dist/css/dx.light.css'; import DxList from 'devextreme-vue/list'; export default { components: { DxList }, data() { return { listData: [ { itemProperty: 'someValue' }, // ... ] } } } </script>
React
import React from 'react'; import 'devextreme/dist/css/dx.common.css'; import 'devextreme/dist/css/dx.light.css'; import List from 'devextreme-react/list'; const renderListItem = (data, index) => { return ( <div>{index} - {data.itemProperty}</div> ); } class App extends React.Component { listData = [ { itemProperty: 'someValue' }, // ... ]; render() { return ( <List items={this.listData} itemRender={renderListItem} /> ); } } export default App;
Collection widgets also support templates for individual items. Do not specify the widget's dataSource option if you use individual templates.
jQuery
$(function() { $("#listContainer").dxList({ items: [{ template: function () { return $("<i>").text("Item 1") } }, { template: function () { return $("<b>").text("Item 2") } },{ template: function () { return $("<div>").append( $("<span>").text("Item with nested component"), $("<div>").dxButton({ text: "Click me" }) ) } }] }); });
Angular
<dx-list> <dxi-item> <i>Item 1</i> </dxi-item> <dxi-item> <b>Item 2</b> </dxi-item> <dxi-item> <div *dxTemplate> Item with a nested component <dx-button text="Click me"></dx-button> </div> </dxi-item> </dx-list>
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { DxListModule, DxButtonModule } from 'devextreme-angular'; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, DxListModule, DxButtonModule ], providers: [ ], bootstrap: [AppComponent] }) export class AppModule { }
Vue
<template> <DxList> <DxItem> <template #default> <i>Item 1</i> </template> </DxItem> <DxItem> <template #default> <i>Item 2</i> </template> </DxItem> <DxItem> <template #default> <div> Item with a nested component <DxButton text="Click me" /> </div> </template> </DxItem> </DxList> </template> <script> import 'devextreme/dist/css/dx.common.css'; import 'devextreme/dist/css/dx.light.css'; import DxList, { DxItem } from 'devextreme-vue/list'; import DxButton from 'devextreme-vue/button'; export default { components: { DxList, DxItem, DxButton } } </script>
React
import React from 'react'; import 'devextreme/dist/css/dx.common.css'; import 'devextreme/dist/css/dx.light.css'; import List, { Item } from 'devextreme-react/list'; import Button from 'devextreme-react/button'; class App extends React.Component { render() { return ( <List> <Item> <i>Item 1</i> </Item> <Item> <i>Item 2</i> </Item> <Item> Item with a nested component <Button text="Click me" /> </Item> </List> ); } } export default App;
See Also
3rd-Party Template Engines
You can use a 3rd-party template engine, but only with jQuery. DevExtreme supports the following template engines out of the box:
To use one of them, pass its name to the DevExpress.setTemplateEngine(name) method:
DevExpress.setTemplateEngine("underscore"); $(function() { $("#list").dxList({ // ... itemTemplate: $("#itemTemplate") }); })
<div id="list"></div> <script type="text/html" id="itemTemplate"> <!-- your Underscore template --> </script>
You can also use other template engines, but you need to implement functions that compile and render templates in this case. See DevExpress.setTemplateEngine(options) for details.