Search results

Customize Nested ListView as BreadCrumbs in JavaScript ListView control

08 May 2023 / 5 minutes to read

ListView header can be customized using headerTemplate property. Here We customized the header of nested ListView as BreadCrumbs with headerTemplate property . i.e while navigating to child data of a list item, the header data is customized with the selected data path. For example, the header of nested ListView is Continent. While selecting a list item(Asia) then the header will be customized as Continent>Asia.

  • This customization achieved while front and back navigations of list items with actionComplete event of ListView.
  • On actionComplete we append the selected text in header element.
  • And in back navigation, we removed the last appended span from header template

And also we can able to navigate the desired child level by clicking list items appended in the customized header. For example, let consider header of nested ListView is Continent>Asia>India. If we want to navigate to Continent level of ListView, then we can click the Continent in Header

N> In each navigation we have calculated the appended span tag length in calculateLevelForElements method to update header.

Source
Preview
index.ts
index.html
index.css
Copied to clipboard
import { ListView } from '@syncfusion/ej2-lists';

//define the array of JSON
let continent: { [key: string]: Object }[] = [
{
    'text': 'Asia',
    'id': '01',
    'category': 'Continent',
    'child': [{
        'text': 'India',
        'id': '1',
        'category': 'Asia',
        'child': [{
            'text': 'Delhi',
            'id': '1001',
            'category': 'India',
        },
        {
            'text': 'Kashmir',
            'id': '1002',
            'category': 'India',
        },
        {
            'text': 'Goa',
            'id': '1003',
            'category': 'India',
        },
        ]
    },
    {
        'text': 'China',
        'id': '2',
        'category': 'Asia',
        'child': [{
            'text': 'Zhejiang',
            'id': '2001',
            'category': 'China',
        },
        {
            'text': 'Hunan',
            'id': '2002',
            'category': 'China',
        },
        {
            'text': 'Shandong',
            'id': '2003',
            'category': 'China',
        }]
    }]
},

{
    'text': 'North America',
    'id': '02',
    'category': 'Continent',
    'child': [{
        'text': 'USA',
        'id': '3',
        'category': 'North America',
        'child': [{
            'text': 'California',
            'id': '3001',
            'category': 'USA',
        },
        {
            'text': 'New York',
            'id': '3002',
            'category': 'USA',
        },
        {
            'text': 'Florida',
            'id': '3003',
            'category': 'USA',
        }]
    },
    {
        'text': 'Canada',
        'id': '4',
        'category': 'North America',
        'child': [{
            'text': 'Ontario',
            'id': '4001',
            'category': 'Canada',
        },
        {
            'text': 'Alberta',
            'id': '4002',
            'category': 'Canada',
        },
        {
            'text': 'Manitoba',
            'id': '4003',
            'category': 'Canada',
        }]
    }]
},

{
    'text': 'Europe',
    'id': '03',
    'category': 'Continent',
    'child': [{
        'text': 'Germany',
        'id': '5',
        'category': 'Europe',
        'child': [{
            'text': 'Berlin',
            'id': '5001',
            'category': 'Germany',
        },
        {
            'text': 'Bavaria',
            'id': '5002',
            'category': 'Germany',
        },
        {
            'text': 'Hesse',
            'id': '5003',
            'category': 'Germany',
        }]
    }, {
        'text': 'France',
        'id': '6',
        'category': 'Europe',
        'child': [{
            'text': 'Paris',
            'id': '6001',
            'category': 'France',
        },
        {
            'text': 'Lyon',
            'id': '6002',
            'category': 'France',
        },
        {
            'text': 'Marseille',
            'id': '6003',
            'category': 'France',
        }]
    }]
},
{
    'text': 'Australia',
    'id': '04',
    'category': 'Continent',
    'child': [{
        'text': 'Australia',
        'id': '7',
        'category': 'Australia',
        'child': [{
            'text': 'Sydney',
            'id': '7001',
            'category': 'Australia',
        },
        {
            'text': 'Melbourne',
            'id': '7002',
            'category': 'Australia',
        },
        {
            'text': 'Brisbane',
            'id': '7003',
            'category': 'Australia',
        }]
    }, {
        'text': 'New Zealand',
        'id': '8',
        'category': 'Australia',
        'child': [{
            'text': 'Milford Sound',
            'id': '8001',
            'category': 'New Zealand',
        },
        {
            'text': 'Tongariro National Park',
            'id': '8002',
            'category': 'New Zealand',
        },
        {
            'text': 'Fiordland National Park',
            'id': '8003',
            'category': 'New Zealand',
        }]
    }]
},
{
    'text': 'Africa',
    'id': '05',
    'category': 'Continent',
    'child': [{
        'text': 'Morocco',
        'id': '9',
        'category': 'Africa',
        'child': [{
            'text': 'Rabat',
            'id': '9001',
            'category': 'Morocco',
        },
        {
            'text': 'Toubkal',
            'id': '9002',
            'category': 'Morocco',
        },
        {
            'text': 'Todgha Gorge',
            'id': '9003',
            'category': 'Morocco',
        }]
    }, {
        'text': 'South Africa',
        'id': '10',
        'category': 'Africa',
        'child': [{
            'text': 'Cape Town',
            'id': '10001',
            'category': 'South Africa',
        },
        {
            'text': 'Pretoria',
            'id': '10002',
            'category': 'South Africa',
        },
        {
            'text': 'Bloemfontein',
            'id': '10003',
            'category': 'South Africa',
        }]
    }]
}
];

let text:string, backBtn:HTMLElement, title, headerElement, hasChild = false;

//Initialize ListView component
let listviewInstance = new ListView({
  //set the data to dataSource property
  dataSource: continent,
  // map the groupBy field with category column
  fields: { tooltip: "text" },
  headerTemplate: '<div class="header-content"><span>Continent</span></div>',
  showHeader: true,
  select: onSelect,
  actionComplete: onComplete
});
//Render initialized ListView
listviewInstance.appendTo("#listview");

backBtn = document.querySelector(".e-but-back") as HTMLElement;
title = document.querySelector(".header-content");
title.addEventListener("click", navigateBack);

function onSelect(e:any) {
  text = e.text;
  hasChild = !e.item.classList.contains("e-has-child");
}

function onComplete() {
  if (!hasChild) {
headerElement = document.querySelector(".header-content").innerHTML;
title = document.querySelector(".nested-header .header-content");
if (headerElement && text != undefined) {
  // Create element with new clicked item in header
  let element = document.createElement("span");
  element.textContent = ` > ${text}`;
  title.appendChild(element);

  // Recalcualte levels, Since an element is added
  calculateLevelForElements();
}
  }
}

backBtn.addEventListener("click", function () {
  let elements = document.querySelectorAll(
".nested-header .header-content span"
  );
  elements[elements.length - 1].remove();

  // Recalcualte levels, Since an element is removed
  calculateLevelForElements();

  if (backBtn.style.display == "none") {
hasChild = false;
  } else {
hasChild = true;
  }
});

// Calculate level for each header element
function calculateLevelForElements() {
  let elements = document.querySelectorAll(
".nested-header .header-content span"
  );
  let index = 0;
  for (let i = elements.length - 1; i >= 0; i--) {
(elements[index] as any).level = i;
index++;
  }
}

// Navigate back event handler based on element's level
function navigateBack(event:any) {
  if (event.target && event.target.level) {
for (let i = 0; i <= event.target.level; i++) {
  backBtn.click();
}
  }
}
Copied to clipboard
<!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="//cdn.syncfusion.com/ej2/21.2.3/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-lists/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-buttons/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id="container">
        <div id="listview"></div>
    </div>
</body>

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

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

.e-listview .e-list-icon {
  height: 24px;
  width: 30px;
}
.e-listview .e-list-header .e-headertemplate-text.nested-header {
  display: block !important;
}
.e-list-header .e-text {
  display: none;
}
.folder {
  background-repeat: no-repeat;
  background-image: url("https://ej2.syncfusion.com/javascript/demos/src/listview/images/file_icons.png");
  background-position: -5px -466px;
  background-size: 302%;
}

.file {
  background-repeat: no-repeat;
  background-image: url("https://ej2.syncfusion.com/javascript/demos/src/listview/images/file_icons.png");
  background-position: -5px -151px;
  background-size: 302%;
}
#listview {
  max-width: 500px;
  margin: auto;
  border: 1px solid #dddddd;
  border-radius: 3px;
}
.header-content span {
  cursor: pointer;
}