Virtual List

    Virtual List allows to render lists with huge amount of elements without loss of performance. And it is fully compatible with all Framework7 components which work with lists such as Search Bar, Infinite Scroll, Pull To Refresh, Swipeouts (swipe-to-delete) and Sortable.

    Virtual List Layout

    Virtual List HTML layout is pretty simple, it is almost the same as for usual List View with only difference: you need to leave it empty:

    <!-- Virtual List -->
    <div class="list virtual-list">
      <!-- keep it empty -->
    </div>

    Where:

    • virtual-list - required additional class on any list block that uses Virtual List

    Virtual List App Methods

    Now, when we have list's HTML, we need to initialize it. We need to use required App method:

    app.virtualList.create(parameters)- initialize virtual list with parameters

    • parameters - object - object with virtual list parameters. Required.
    • Method returns initialized Virtual List instance

    app.virtualList.destroy(el)- destroy Virtual List instance

    • el - HTMLElement or string (with CSS Selector) or object. Virtual List element or Virtual List instance to destroy.

    app.virtualList.get(el)- get Virtual List instance by HTML element

    • el - HTMLElement or string (with CSS Selector). Virtual List element.

    Method returns Virtual List's instance

    Note that Virtual List container (list block element) should be in DOM on a moment of initialization.

    Virtual List Parameters

    Let's look on list of all available parameters:

    Parameter Type Default Description
    el HTMLElement
    string
    Target List Block element. In case of string - CSS selector of list block element
    ul HTMLElement
    string
    List element <ul> inside of List block.
    createUl boolean true Will automatically create <ul> element inside of Virtual List block. If disabled, then virtual list can be used on any block element without ul > li structure
    items array Array with list items
    rowsBefore number Amount of rows (items) to be rendered before current screen scroll position. By default it is equal to double amount of rows (items) that fit to screen
    rowsAfter number Amount of rows (items) to be rendered after current screen scroll position. By default it is equal to the amount of rows (items) that fit to screen
    cols number 1 Number of items per row. Doesn't compatible when using Virtual List with dynamic height
    height number or function(item) If number - list item height in px. If function then function should return item height. By default equals to 44 for iOS theme and 48 for MD theme
    itemTemplate string
    function
    Template7 string template or Template7 compiled template that used to render single item. Template should contain full HTML layout for single item, including wrapping <li></li> tags
    renderItem function(item) This optional function allows to use custom function to render item HTML. It could be used instead of template parameter
    renderExternal function(renderParameters) This optional function allows to render DOM items using some custom method. Useful in case it is used (e.g.) with Vue/React plugin to pass DOM rendering and manipulation to Vue/React. renderParameters conaints object with the following properties: fromIndex, toIndex, listHeight, topPosition, items
    emptyTemplate string Defines list item template for the case if empty data passed
    dynamicHeightBufferSize number 1 This parameter allows to control buffer size on Virtual Lists with dynamic height (when height parameter is function) as a buffer size multiplier
    cache boolean true Disable or enable DOM cache for already rendered list items. In this case each item will be rendered only once and all futher manipulations will be with DOM element. It is useful if your list items have some user interaction elements (like form elements or swipe outs) or could be modified
    updatableScroll boolean Is the current device updates and handles scroll events during scroll. By default (if not specified) it is "false" for all iOS devices with iOS version less than 8.
    setListHeight boolean true Will set height on list block if enabled
    showFilteredItemsOnly boolean false Option to show filtered items only set by `filter()` method
    Searchbar
    searchByItem function(query, item, index) Search function that will be used by Searchbar, it receives search query, item itself and item index. If item matches to search query you need to return true, otherwise this function should return false
    searchAll function(query, items) Search function that will be used by Searchbar, it receives search query and array with all items. You need to loop through items and return array with indexes of matched items

    Virtual List Methods & Properties

    So to create Virtual List we have to call:

    var virtualList = app.virtualList.create({ /* parameters */ })

    After we initialize Virtual List we have its initialized instance in variable (like virtualList variable in example above) with helpful methods and properties:

    Properties
    virtualList.items Array with items
    virtualList.filteredItems Array with filtered items (after using ".filterItems" method)
    virtualList.domCache Object with cached dom items
    virtualList.params Parameters passed on list initialization
    virtualList.el Virtual list target list block element
    virtualList.$el Dom7 instance of target list block element
    virtualList.pageContentEl Parent "page-content" element
    virtualList.$pageContentEl Dom7 instance of parent "page-content" element
    virtualList.currentFromIndex Index number of currently first rendered item
    virtualList.currentToIndex Index number of currently last rendered item
    virtualList.reachEnd Boolean property. Equals true if the currently last rendered item is the last item of all specified items
    Methods
    virtualList.filterItems(indexes); Filter virtual list by passing array with indexes of items to show
    virtualList.resetFilter(); Disable filter and display all items again
    virtualList.appendItem(item); Append item to virtual list
    virtualList.appendItems(items); Append array with items to virtual list
    virtualList.prependItem(item); Prepend item to virtual list
    virtualList.prependItems(items); Prepend array with items to virtual list
    virtualList.replaceItem(index, items); Replace item at specified index with the new one
    virtualList.replaceAllItems(items); Replace all items with arrays of new items
    virtualList.moveItem(oldIndex, newIndex); Move virtual item from oldIndex to newIndex
    virtualList.insertItemBefore(index, item); Insert new item before item with specified index
    virtualList.deleteItem(index); Delete item at specified index
    virtualList.deleteItems(indexes); Delete items at specified array of indexes
    virtualList.deleteAllItems(); Delete all items
    virtualList.clearCache(); Clear virtual list cached DOM elements
    virtualList.destroy(); Destory initialized virtual list and detach all events
    virtualList.update(); Update virtual list, including recalculation of list sizes and re-rendering of virtual list
    virtualList.scrollToItem(index); Scroll Virtual List to specified item by its index number

    Virtual List Events

    Virtual List will fire the following events on app and virtual list instance:

    Virtual List instance emits events on both self instance and app instance. App instance events has same names prefixed with vl.

    Event Target Arguments Description
    itemBeforeInsert virutalList virtualList, itemEl, item Event will be triggered before item will be added to virtual document fragment
    vlItemBeforeInsert app
    itemsBeforeInsert virutalList virtualList, fragment Event will be triggered after current DOM list will be removed and before new document will be inserted
    vlItemsBeforeInsert app
    beforeClear virutalList virtualList, fragment Event will be triggered before current DOM list will be removed and replaced with new document fragment
    vlBeforeClear app
    itemsAfterInsert virutalList virtualList, fragment Event will be triggered after new document fragment with items inserted
    vlItemsAfterInsert app

    Examples

    <div class="page">
      <div class="navbar">
        <div class="navbar-inner sliding">
          <div class="title">Virtual List</div>
          <div class="subnavbar">
            <form data-search-container=".virtual-list" data-search-item="li" data-search-in=".item-title" class="searchbar searchbar-init">
              <div class="searchbar-inner">
                <div class="searchbar-input-wrap">
                  <input type="search" placeholder="Search"/>
                  <i class="searchbar-icon"></i>
                  <span class="input-clear-button"></span>
                </div>
                <span class="searchbar-disable-button">Cancel</span>
              </div>
            </form>
          </div>
        </div>
      </div>
      <div class="searchbar-backdrop"></div>
      <div class="page-content">
        <div class="list simple-list searchbar-not-found">
          <ul>
            <li>Nothing found</li>
          </ul>
        </div>
        <div class="list virtual-list media-list searchbar-found"></div>
      </div>
    </div>
    var app = new Framework7();
    
    // Dummy items array
    var items = [];
    for (var i = 1; i <= 10000; i++) {
      items.push({
        title: 'Item ' + i,
        subtitle: 'Subtitle ' + i
      });
    }
    
    var virtualList = app.virtualList.create({
      // List Element
      el: '.virtual-list',
      // Pass array with items
      items: items,
      // Custom search function for searchbar
      searchAll: function (query, items) {
        var found = [];
        for (var i = 0; i < items.length; i++) {
          if (items[i].title.toLowerCase().indexOf(query.toLowerCase()) >= 0 || query.trim() === '') found.push(i);
        }
        return found; //return array with mathced indexes
      },
      // List item Template7 template
      itemTemplate:
        '<li>' +
          '<a href="#" class="item-link item-content">' +
            '<div class="item-inner">' +
              '<div class="item-title-row">' +
                '<div class="item-title">{{title}}</div>' +
              '</div>' +
              '<div class="item-subtitle">{{subtitle}}</div>' +
            '</div>' +
          '</a>' +
        '</li>',
      // Item height
      height: app.theme === 'ios' ? 63 : 73,
    });