Virtual List elements removed when nearby block element added/removed

Hello, I’m having an issue with Virtual List when hiding/showing a block element in the same page by changing the state it causes the Virtual List content to disappear.

So far I have figured out that it only happens with block elements, so if you change the element to span for example it will not remove items in the list.

Also, if you manually hide/show the same block in the DOM via console it does not remove the elements, its only when you do it via $setState() so I think its losing the state of the elements in the Virtual List.

Is this a known limitation? Is there any workaround to this? Even when I use position: absolute div to hide/show it has the same issue.

Thanks for any help!

Example video with code below: https://www.dropbox.com/s/ape03u6agtyjifr/Screen%20Recording%202020-09-25%20at%208.30.03%20AM.mov?dl=0

Here is an example component:

<template>
  <div class="page" data-name="home">
    <!-- Top Navbar -->
    <div class="navbar">
      <div class="navbar-bg"></div>
      <div class="navbar-inner">
        <div class="title">Test Virtuallist</div>
      </div>
    </div>

    <div class="page-content">
      <div>
        <a @click='toggle'>
          toggle div hide/show
        </a>
      </div>

      {{#if show}}
      <div>
        when this is hidden/shown it removes all elements virtuallist
      </div>
      {{/if}}

      <div>
        <div class="list virtual-list media-list searchbar-found"></div>
      </div>
    </div>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        show: true
      }
    },
    methods: {
      toggle() {
        let self = this
        self.$setState({
          show: !self.show
        })
      }
    },
    mounted() {
      let self = this;
      let app = self.$app;

      // 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 : (app.theme === 'md' ? 73 : 46),
      });
    }
  }
</script>

You are removing it, not hiding. Add proper unique keys so VDOM knows it is a different elements:

      {{#if show}}
      <div key="some-block">
        when this is hidden/shown it removes all elements virtuallist
      </div>
      {{/if}}

      <div key="virtual-list-block">
        <div class="list virtual-list media-list searchbar-found"></div>
      </div>

Thanks Vladimir, that solves the issue :+1:

Also adding id to the div solves it as well.

1 Like