Customizing templates in EJ2 JavaScript ListView control

28 Jan 202523 minutes to read

The ListView control is designed to customize list items, group titles, and header titles. It utilizes the Essential JS2 Template Engine to render the elements.

Header template

The ListView header can be customized using the headerTemplate property.

To customize the header template in your application, set your customized template string to the headerTemplate property along with setting the showHeader property to true to display the ListView header.

let listviewInstance: ListView = new ListView({
     data: listData,
     headerTemplate: '<div class="header-content"><span>Header</span></div>',
     showHeader: true
})

In the following example, we have rendered ListView with customized header which contains search, add and sort buttons.

var fruitsdata = [
    { text: 'Date', id: '1', imgUrl: './dates.jpg' },
    { text: 'Fig', id: '2', imgUrl: './fig.jpg' },
    { text: 'Apple', id: '3', imgUrl: './apple.png' },
    { text: 'Apricot', id: '4', imgUrl: './apricot.jpg' },
    { text: 'Grape', id: '5', imgUrl: './grape.jpg' },
    { text: 'Strawberry', id: '6', imgUrl: './strawberry.jpg' },
    { text: 'Pineapple', id: '7', imgUrl: './pineapple.jpg' },
    { text: 'Melon', id: '8', imgUrl: './melon.jpg' },
    { text: 'Lemon', id: '9', imgUrl: './lemon.jpg' },
];

var listViewInstance = new ej.lists.ListView({
    dataSource: fruitsdata,
    headerTemplate: '<div class="headerContainer"><span class="fruitHeader">Fruits</span><button id="search"></button><button id="add"></button><button id="sort"></button></div>',
    showHeader: true,
    actionComplete: renderHeaderButtons
});

listViewInstance.appendTo('#element');

function renderHeaderButtons() {
    ['search', 'sort', 'add'].forEach((item) => {
        new ej.buttons.Button({ iconCss: `e-icons e-${item}-icon`, cssClass: 'e-small e-round', isPrimary: true }, `#${item}`)
    });
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 for ListView </title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Essential JS 2 for ListView UI Control">
    <meta name="author" content="Syncfusion">
    <link href="index.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-base/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-lists/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-buttons/styles/material.css" rel="stylesheet">
    <script src="https://cdn.syncfusion.com/ej2/28.2.3/dist/ej2.min.js" type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id="container">
        <div id="element"></div>
    </div>

    <script>
        var ele = document.getElementById('container');
        if (ele) {
            ele.style.visibility = "visible";
        }   
    </script>
    <script src="index.js" type="text/javascript"></script>
    <style>
        #element {
            display: block;
            max-width: 353px;
            margin: auto;
            border: 1px solid #dddddd;
            border-radius: 3px;
        }

        #element .e-list-header {
            padding: 0;
        }

        #element .headerContainer {
            width: 350px;
            height: 48px;
            line-height: 48px;
            background: rgb(2, 120, 215);
            color: white;
            margin-bottom: 3px;
        }

        .headerContainer .fruitHeader {
            margin-left: 20px;
            font-weight: 500;
            font-size: 22px;
        }

        .headerContainer #add,
        .headerContainer #sort,
        .headerContainer #search {
            float: right;
            margin-right: 15px;
            margin-top: 7px;
            background: white;
            color: black
        }

        .headerContainer .e-search-icon::before {
            content: '\e961';
            color: lightslategray;
        }


        .headerContainer .e-add-icon::before {
            content: '\e823';
        }

        .headerContainer .e-sort-icon::before {
            content: '\e840';
        }
    </style>
</body>

</html>
#container {
    visibility: hidden;
}

#loader {
  color: #008cff;
  height: 40px;
  width: 30%;
  position: absolute;
  font-family: 'Helvetica Neue','calibiri';
  font-size: 14px;
  top: 45%;
  left: 45%;
}

Template

ListView items can be customized using the template property.

To customize list items in your application, set your customized template string to the template property.

let listviewInstance: ListView = new ListView({
     data: listData,
     template: '<div class="list-item"><span>${text}</span></div>',
})

We provided the following built-in CSS classes to customize the list items. Refer to the following table.

CSS class Description
e-list-template, e-list-wrapper These classes are used to differentiate normal and template rendering, which are mandatory for template rendering. The e-list-template class should be added to the root of the ListView element and e-list-wrapper class should be added to the template element wrapper

new ListView({
dataSource: data,
cssClass: 'e-list-template',
template: '<div class="e-list-wrapper"></div>'}, '#list');
e-list-content This class is used to align list content and it should be added to the content element

<div class="e-list-wrapper">
<span class="e-list-content">ListItem</span>
</div>
e-list-avatar This class is used for avatar customization. It should be added to the template element wrapper. After adding it, we can customize our element with Avatar classes

<div class="e-list-wrappere-list-avatar">
<span class="e-avatar e-avatar-circle">MR</span>
<span class="e-list-content">ListItem</span>
</div>
e-list-avatar-right This class is used to align avatar to right side of the list item. It should be added to the template element wrapper. After adding it, we can customize our element with Avatar classes

<div class="e-list-wrappere-list-avatar-right">
<span class="e-list-content">ListItem</span>
<span class="e-avatar e-avatar-circle">MR</span>
</div>
e-list-badge This class is used for badge customization .It should be added to the template element wrapper. After adding it, we can customize our element with Badge classes

<div class="e-list-wrappere-list-badge">
<span class="e-list-content">ListItem</span>
<span class="e-badge e-badge-primary">MR</span>
</div>
e-list-multi-line This class is used for multi-line customization. It should be added to the template element wrapper. After adding it, we can customize List item’s header and description

<div class="e-list-wrappere-list-multi-line">
<span class="e-list-content">ListItem</span>
</div>
e-list-item-header This class is used to align a list header and it should be added to the header element along with the multi-line class

<div class="e-list-wrappere-list-multi-line">
<span class="e-list-item-header">ListItem Header</span>
<span class="e-list-content">ListItem</span>
</div>

In the following example, we have customized list items with built-in CSS classes.

var template = '<div class="e-list-wrapper e-list-multi-line e-list-avatar">' +
    '${if(avatar!=="")}' +
    '<span class="e-avatar e-avatar-circle">${avatar}</span>' +
    '${else}' +
    '<span class="${pic} e-avatar e-avatar-circle"> </span>' +
    '${/if}' +
    '<span class="e-list-item-header">${text}</span>' +
    '<span class="e-list-content">${contact}</span>' +
    '</div>';

//Define an array of JSON data
var dataSource = [
    { text: "Jenifer", contact: "(206) 555-985774", id: "1", avatar: "", pic: "pic01" },
    { text: "Amenda", contact: "(206) 555-3412", id: "2", avatar: "A", pic: "" },
    { text: "Isabella", contact: "(206) 555-8122", id: "4", avatar: "", pic: "pic02" },
    { text: "William", contact: "(206) 555-9482", id: "5", avatar: "W", pic: "" }
];
// Initialize ListView control
var listObj = new ej.lists.ListView({
    //Set defined data to dataSource property
    dataSource: dataSource,
    //Map the appropriate columns to fields property
    fields: { text: "text" },
    cssClass: 'e-list-template',
    //set width of ListView
    width: "350px",
    //enable ListView header
    showHeader: true,
    //set header title
    headerTitle: "Contacts",
    //Set customized template
    template: template,
    sortOrder: "Ascending"
});
//Render initialized ListView control
listObj.appendTo("#List");
<!DOCTYPE html>
<html lang="en">

<head>
  <title>Essential JS 2 for ListView </title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="description" content="Essential JS 2 for ListView UI Control">
  <meta name="author" content="Syncfusion">
  <link href="index.css" rel="stylesheet">
  <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-base/styles/material.css" rel="stylesheet">
  <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-lists/styles/material.css" rel="stylesheet">
  <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-layouts/styles/material.css" rel="stylesheet">
  <script src="https://cdn.syncfusion.com/ej2/28.2.3/dist/ej2.min.js" type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
  <div id="container">
    <div id="List" tabindex="1"></div>
  </div>

  <script>
    var ele = document.getElementById('container');
    if (ele) {
      ele.style.visibility = "visible";
    }   
  </script>
  <script src="index.js" type="text/javascript"></script>
  <style>
    #List {
      margin: 0 auto;
      font-size: 15px;
      border: 1px solid #ccc;
    }

    .pic01 {
      background-image: url("https://ej2.syncfusion.com/demos/src/grid/images/1.png");
    }

    .pic02 {
      background-image: url("https://ej2.syncfusion.com/demos/src/grid/images/3.png");
    }

    .pic03 {
      background-image: url("https://ej2.syncfusion.com/demos/src/grid/images/5.png");
    }

    .pic04 {
      background-image: url("https://ej2.syncfusion.com/demos/src/grid/images/2.png");
    }

    #List .e-list-item:nth-child(1) .e-avatar {
      background-color: #039be5;
    }

    #List .e-list-item:nth-child(2) .e-avatar {
      background-color: #e91e63;
    }

    #List .e-list-item:nth-child(6) .e-avatar {
      background-color: #009688;
    }

    #List .e-list-item:nth-child(8) .e-avatar {
      background-color: #0088;
    }
  </style>
</body>

</html>
#container {
  visibility: hidden;
}

#loader {
  color: #008cff;
  height: 40px;
  width: 30%;
  position: absolute;
  font-family: "Helvetica Neue", "calibiri";
  font-size: 14px;
  top: 45%;
  left: 45%;
}

Group template

The ListView group header can be customized using the groupTemplate property.

To customize the group template in your application, set your customized template string to the groupTemplate property.

let listviewInstance: ListView = new ListView({
     data: listData,
     groupTemplate: '<div class="group-header"><span>${items[0].category}</span></div>',
})

In the following example, we have grouped the ListView based on the category. The category of each list item should be mapped with the groupBy field of the data. We have also displayed the count of grouped list items in the group list header.

var template = '<div class="e-list-wrapper e-list-multi-line e-list-avatar">' +
    '<img class="e-avatar e-avatar-circle" src=${image} style="background:#BCBCBC" />' +
    '<span class="e-list-item-header">${Name}</span>' +
    '<span class="e-list-content">${contact}</span>' +
    '</div>';

//Define an array of JSON data
var dataSource = [
    { Name: 'Nancy', contact: '(206) 555-985774', id: '1', image: 'https://ej2.syncfusion.com/demos/src/grid/images/1.png', category: 'Experience' },
    { Name: 'Janet', contact: '(206) 555-3412', id: '2', image: 'https://ej2.syncfusion.com/demos/src/grid/images/3.png', category: 'Fresher' },
    { Name: 'Margaret', contact: '(206) 555-8122', id: '4', image: 'https://ej2.syncfusion.com/demos/src/grid/images/4.png', category: 'Experience' },
    { Name: 'Andrew ', contact: '(206) 555-9482', id: '5', image: 'https://ej2.syncfusion.com/demos/src/grid/images/2.png', category: 'Experience' },
    { Name: 'Steven', contact: '(71) 555-4848', id: '6', image: 'https://ej2.syncfusion.com/demos/src/grid/images/5.png', category: 'Fresher' },
    { Name: 'Michael', contact: '(71) 555-7773', id: '7', image: 'https://ej2.syncfusion.com/demos/src/grid/images/6.png', category: 'Experience' },
    { Name: 'Robert', contact: '(71) 555-5598', id: '8', image: 'https://ej2.syncfusion.com/demos/src/grid/images/7.png', category: 'Fresher' },
    { Name: 'Laura', contact: '(206) 555-1189', id: '9', image: 'https://ej2.syncfusion.com/demos/src/grid/images/8.png', category: 'Experience' },
];

// Initialize ListView control
var listObj = new ej.lists.ListView({

    //Set defined data to dataSource property
    dataSource: dataSource,

    width: 350,

    //Map the appropriate columns to fields property
    fields: { text: 'Name', groupBy: 'category' },
    cssClass: 'e-list-template',
    //Set customized template
    template: template,
    groupTemplate: '<div><span class="category">${items[0].category}</span> <span class="count"> ${items.length} Item(s)</span></div> '

});

//Render initialized ListView control
listObj.appendTo('#List');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>Essential JS 2 for ListView </title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="description" content="Essential JS 2 for ListView UI Control">
    <meta name="author" content="Syncfusion">
    <link href="index.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-base/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-lists/styles/material.css" rel="stylesheet">
    <link href="https://cdn.syncfusion.com/ej2/28.2.3/ej2-layouts/styles/material.css" rel="stylesheet">
    <script src="https://cdn.syncfusion.com/ej2/28.2.3/dist/ej2.min.js" type="text/javascript"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id="container">
        <div class="col-lg-12 control-section">

            <!-- ListView element -->
            <div id="List" tabindex="1">
            </div>
        </div>
    </div>

    <script>
        var ele = document.getElementById('container');
        if (ele) {
            ele.style.visibility = "visible";
        }   
    </script>
    <script src="index.js" type="text/javascript"></script>
    <style>
        #List {
            display: block;
            margin: auto;
            font-size: 15px;
            border: 1px solid;
            border-color: #ccc;
            width: 350px;
        }

        #List .e-list-group-item {
            height: 56px;
            line-height: 56px;
        }

        #List .count {
            float: right;
        }
    </style>
</body>

</html>
#container {
    visibility: hidden;
  }

  #loader {
    color: #008cff;
    height: 40px;
    left: 45%;
    position: absolute;
    top: 45%;
    width: 30%;
  }

We can also render other EJ2 controls in ListView templates by rendering that controls on actionComplete event. Refer to the below code snippet.

let listviewInstance: ListView = new ListView({
     data: listData,
     template: '<div><span>${text}</span><button id="delete"></button></div>',
     actionComplete: () => {
         new Button({iconCss: 'e-icons e-delete-icon' cssClass: 'e-small e-round', isPrimary: true }, '#delete')
     }
})