Coder Social home page Coder Social logo

iron-list's Introduction

Published on NPM Build status Published on webcomponents.org

<iron-list>

iron-list displays a virtual, 'infinite' list. The template inside the iron-list element represents the DOM to create for each list item. The items property specifies an array of list item data.

For performance reasons, not every item in the list is rendered at once; instead a small subset of actual template elements (enough to fill the viewport) are rendered and reused as the user scrolls. As such, it is important that all state of the list template be bound to the model driving it, since the view may be reused with a new model at any time. Particularly, any state that may change as the result of a user interaction with the list item must be bound to the model to avoid view state inconsistency.

Sizing iron-list

iron-list must either be explicitly sized, or delegate scrolling to an explicitly sized parent. By "explicitly sized", we mean it either has an explicit CSS height property set via a class or inline style, or else is sized by other layout means (e.g. the flex or fit classes).

Flexbox - jsbin

<style>
  :host {
    height: 100vh;
    display: flex;
    flex-direction: column;
  }

  iron-list {
    flex: 1;
  }
</style>
<app-toolbar>App name</app-toolbar>
<iron-list items="[[items]]">
  <template>
    <div>
      ...
    </div>
  </template>
</iron-list>

Explicit size - jsbin

<style>
  :host {
    display: block;
  }

  iron-list {
    height: 100vh; /* don't use % values unless the parent element is sized. */
  }
</style>
<iron-list items="[[items]]">
  <template>
    <div>
      ...
    </div>
  </template>
</iron-list>

Main document scrolling - jsbin

<head>
  <style>
    body {
      margin: 0;
    }
  </style>
</head>
<body>
  <iron-list scroll-target="document">
    <template>
      <div>
        ...
      </div>
    </template>
  </iron-list>
</body>

iron-list must be given a <template> which contains exactly one element. In the examples above we used a <div>, but you can provide any element (including custom elements).

Template model

List item templates should bind to template models of the following structure:

{
  index: 0,        // index in the item array
  selected: false, // true if the current item is selected
  tabIndex: -1,    // a dynamically generated tabIndex for focus management
  item: {}         // user data corresponding to items[index]
}

Alternatively, you can change the property name used as data index by changing the indexAs property. The as property defines the name of the variable to add to the binding scope for the array.

For example, given the following data array:

data.json
[
  {"name": "Bob"},
  {"name": "Tim"},
  {"name": "Mike"}
]

The following code would render the list (note the name property is bound from the model object provided to the template scope):

<iron-ajax url="data.json" last-response="{{data}}" auto></iron-ajax>
<iron-list items="[[data]]" as="item">
  <template>
    <div>
      Name: [[item.name]]
    </div>
  </template>
</iron-list>

Grid layout

iron-list supports a grid layout in addition to linear layout by setting the grid attribute. In this case, the list template item must have both fixed width and height (e.g. via CSS). Based on this, the number of items per row are determined automatically based on the size of the list viewport.

Accessibility

iron-list automatically manages the focus state for the items. It also provides a tabIndex property within the template scope that can be used for keyboard navigation. For example, users can press the up and down keys, as well as the left and right keys (the grid attribute is present), to move to focus between items in the list:

<iron-list items="[[data]]" as="item">
  <template>
    <div tabindex$="[[tabIndex]]">
      Name: [[item.name]]
    </div>
  </template>
</iron-list>

Styling

You can use the --iron-list-items-container mixin to style the container of items:

iron-list {
 --iron-list-items-container: {
    margin: auto;
  };
}

Resizing

iron-list lays out the items when it receives a notification via the iron-resize event. This event is fired by any element that implements IronResizableBehavior.

By default, elements such as iron-pages, paper-tabs or paper-dialog will trigger this event automatically. If you hide the list manually (e.g. you use display: none) you might want to implement IronResizableBehavior or fire this event manually right after the list became visible again. For example:

document.querySelector('iron-list').fire('iron-resize');

When should <iron-list> be used?

iron-list should be used when a page has significantly more DOM nodes than the ones visible on the screen. e.g. the page has 500 nodes, but only 20 are visible at a time. This is why we refer to it as a virtual list. In this case, a dom-repeat will still create 500 nodes which could slow down the web app, but iron-list will only create 20.

However, having an iron-list does not mean that you should load all the data at once. For example, if you have a million records in the database, it is better split the data into pages so you can bring in a page at a time. The page could contain 500 items, and iron-list might only render 20.

See: Documentation, Demo.

Usage

Installation

npm install --save @polymer/iron-list

In a Polymer 3 element

import {PolymerElement, html} from '@polymer/polymer';
import '@polymer/iron-list/iron-list.js';

class SampleElement extends PolymerElement {
  static get template() {
    return html`
      <style>
        :host {
          display: block;
        }

        iron-list {
          height: 100vh; /* don't use % values unless the parent element is sized. */
        }
      </style>
      <iron-list items="[[items]]">
        <template>
          <div>
            ...
          </div>
        </template>
      </iron-list>
    `;
  }
}
customElements.define('sample-element', SampleElement);

Contributing

If you want to send a PR to this element, here are the instructions for running the tests and demo locally:

Installation

git clone https://github.com/PolymerElements/iron-list
cd iron-list
npm install
npm install -g polymer-cli

Running the demo locally

polymer serve --npm
open http://127.0.0.1:<port>/demo/

Running the tests

polymer test --npm

iron-list's People

Contributors

albertofdzm avatar aomarks avatar benhjt avatar bicknellr avatar blasten avatar chuckh avatar danbeam avatar dependabot[bot] avatar dfreedm avatar dlmma avatar e111077 avatar flamenco avatar frank707 avatar frankiefu avatar freshp86 avatar hcarmona avatar josheverett avatar jshcrowthe avatar keanulee avatar kevinpschaaf avatar m4b avatar notwaldorf avatar pradiprv avatar rictic avatar tedium-bot avatar tjsavage avatar tlyttelton avatar valdrinkoshi avatar web-padawan avatar westbrook avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iron-list's Issues

Item dynamic height changes are not properly recalculated (Expand/Collapse)

Hi,

I tried filling the iron-list with expandable items. (45px when collapsed, 345px when expanded)

When I expand an item, it overlaps the items below instead of pushing them further.

Only when I scroll, then the items below are getting pushed further.

Also, when one of the item is expanded, I start having white spaces on bottom and top when scrolling.

Thanks

The list hijacks the scroller even when not visible

When the iron-list is hidden for some reason (e.g. is a page within an iron-pages component), and the scroller is not its immediate parent (it is set manually), nothing will stop the list from hijacking the scroller, even if something else is filling the scroller (e.g. another page is currently selected).

Modifying the following iron-list method fixes the problem:

    _scrollHandler: function() {
      if (this.offsetHeight > 0) {
        this._refresh();
      }
    },

Only seeing 20 items

I seem to be only seeing the first 20 items in the list, however the scroll will go down further to where more items should be but there is only white space.

<iron-ajax url="./data.json" last-response="{{data}}" auto></iron-ajax>
<iron-list id="my-list" items="[[data]]" as="item" flex>
<template>
  <div class="row" >
    <p>[[item.message]]</p>
    <div class="divider"></div>
  </div>
</template>
</iron-list>

Scroller should be a public property

The list is a bit inflexible as to where it can be placed in the hierarchy right now. It expects a scroller as its immediate parent, which might not be the case (e.g. it might be within an iron-pages, which is within something else, which is within a paper-header-panel). When that is the case, one has to manually set the _scroller property.

Sort items

Could somebody please document the recommended way to have items sorted?

When should I use iron-list and when dom-repeat?

For what kinds of list should I use iron-list instead of dom-repeat? Or should I use dom-repeat at all? Well, the syntax is very similar:

<iron-list items="[[data]]" as="item">
  <template>
    <div>
      Name: <span>[[item.name]]</span>
    </div>
  </template>
</iron-list>

against

<template is="dom-repeat" items="[[data]]">
  <div>
    Name: <span>[[item.name]]</span>
  </div>
</template>

I know that iron-list optimizes things like scrolling (doesn't it reuse list items?), but does that matter with a list size under 50? Or is the content important โ€“ are images better handled by iron-list? Or is iron-list "simply better", and I should use it always where I can?

Thanks for your answers ;-)

Items with a 'title' property raise an illegal invocation exception

Apparently accessing the 'title' property of a TemplateInstance raises an exception, at least in Chrome.

Here's a minimal repro:

<!doctype html>
<html>
<head>
  <title>iron-list title crash</title>

  <base href="http://polygit.org/polymer+:master/components/">

  <script src="webcomponentsjs/webcomponents-lite.js"></script>
  <link rel="import" href="polymer/polymer.html">
  <link rel="import" href="iron-list/iron-list.html">

  <dom-module id="x-app">
    <template>
      <iron-list items="[[data]]">
        <template></template>
      </iron-list>
    </template>
  </dom-module>

  <script>
    Polymer({
      is: 'x-app',
      properties: {
        data: {
          value: function() { return [{title: 'I break things'}] }
        }
      },
    });
  </script>
</head>
<body unresolved>

  <x-app></x-app>

</body>
</html>

jsbin link: http://jsbin.com/qobitotiwi/edit?html,output

Array set to size NaN

On Chromium I am seeing errors that arise in _increasePoolIfNeeded when this._physicalSize and this._optPhysicalSize are equal to each other. var missingItems gets set to NaN (from 0 * 1.2 / this._physicalAverage) and the NaN cascades on through to this._createPool. Doing:
if (this._physicalSize >= this._optPhysicalSize)
seems to fix the problem in Chrome, but it caused test failures in all the other browsers. Unfortunately I don't have a good test setup with all the browsers, etc. yet so this may be as far I get on this one.

dom-repeat template not being picked up in a iron-list template

<iron-list items="[[data]]" as="item">
    <template>
        <template is="dom-repeat" items="[[item.columns]]">
            <div>test</div>
        </template>
    </template>
</iron-list>

In this above case, data is an array, each object of it having a columns property which is again an array. The inner dom-repeat template doesn't pick up the inner array. Nothing is displayed.

Release 1.0.3 is broken

During initialization, the list calls selector.clearSelection(). It seems that array-selector hasn't been initialized yet, as that method doesn't exist. Either that, or iron-list depends on a yet unreleased version of polymer, and that hasn't been reflected in the bower.json file.

Need to increase physical item pool on resize

Currently resize does not trigger a check to see if more physical items are needed. This may be required if the list is initially rendered while hidden and receives a resize event when it becomes showing, as well as the more general case of the list getting larger and needing more items.

Rendering issue with hidden lists and data-binding

Problem

Iron-list is not rendering when using polymer data binding inside of neon-animated-pages. So far, I've found that if I trigger data-source to re-fetch the data (internally using iron-ajax), that the list then renders correctly. I can navigate to other pages and come back and it will still work (after the initial fix).

Solutions

If I refresh the page and data is cached, it will render the current iron-list. But, after navigating to a new list and the new list is empty (the list items' skeletons are all rendered on top of each other).

Manually calling _render() on the list also works; however, it only fixes the iron-list currently being displayed. Ex.) One button calls render on all iron-lists, but only the currently displayed one is fixed, the process must be repeated on each page.

Thoughts

It feels like there is some timing issue between iron-lists data-binding receiving the notification about data-available, and rendering when hidden/detached.

Example
<paper-drawer-panel>
<paper-header-panel>
.....
<neon-animated-pages>
  <data-source data="[[list]]"></data-source>
  <data-source2 data="[[list2]]"></data-source>
  <neon-animatable>
    <x-element data="[[list]]"></element>
  </neon-animatable>
  <neon-animatable>
    <x-element2 data="[[list2]]"></element>
  </neon-animatable>
</neon-animated-pages>
<dom-module id="x-element">
  <iron-list items="[[data]]"></iron-list>
</dom-module>
...
properties: {
  data: Object,
}
Versions

Iron-List Commit #221f11d9eacd8e3ef8c0c28c3423e8e5dea413d1
Linux Chrome 44.0.2403.125 (Official Build) (64-bit)

list without fit does not scroll to top on item change

@blasten I have another polymer puzzle for you ;)

So, I think i've narrowed down the problem I mentioned in #21 to a list that:

  1. does not have the fit class,
  2. and/or, very complicated nested cases where an iron list is fit inside a paper header which is inside another paper header which is inside a drawer.

I don't have a working sample of 2., but it's a pretty common case, especially in any large app. But I suspect that if 1. gets fixed, then 2. will be resolved (if it isn't I'll submit another issue).

Without fit, does not scroll to top

You can see this effect here (only works in Chrome), if you scroll down to the bottom or middle, and repeatedly touch the list item buttons, which causes the list's items to be changed from 100 to 200, or 200 to 100.

If you simply change the list to have class=fit it works as expected, namely, on item change it scrolls to the top of the list.

The code is available at that url, but I'll put it inline here as well:

<dom-module id="computed-list">
  <style>
  :host {
    @apply(--layout-fit);
  }
    iron-list {
      margin: 16px;
    }
  </style>
  <template>
    <!-- add class="fit" and works fine, scrolls to top correctly, etc. -->
    <iron-list id="list" items="[[_items]]">
      <template>
        <paper-button raised on-tap="_changeItems">[[item]]</paper-button>
      </template>
    </iron-list>
  </template>
  <script>
  (function() {
    Polymer({
      is: 'computed-list',

      properties: {
        _selected: {
          type: Number,
          value: 0
        },
        _items: {
          computed: '_computeItems(_selected)'
        }
      },
      _changeItems: function() {
        this._selected = (this._selected + 1) % 2;
      },
      _computeItems:function (selected){
        var i = 200;
        if (selected % 2 === 0) {
          i = 200;
        } else {
          i = 100;
        }
        var tmp = [];
        while (i--) {
          tmp.push(i);
        }
        console.log('item count: ', tmp.length);
        return tmp;
      }
    });
  })();
  </script>
</dom-module>

Cannot reference properties outside of 'item' scope.

Core-list allowed references to properties and functions of the parent object. So, for example, I had a text input field whose input value is bound to a search property of the parent element. I would wire this search property into the list-item element and the child elements would highlight matching text.

With iron-list, whenever I try to reference any property outside of the item object or index, I get the following error: this.fire is not a function. I specifically created a new, text-only property and set default values and the issue persisted, so I am fairly confident that I isolated the cause.

Scroll from bottom

Specially for messaging/social apps IMO there should be a mode where the scrolling goes from the bottom up, like when you add a message everything else scrolls up.

dereferencing null scroller in updateViewportBoundaries

Just updated to Polymer 1.1. Got some iron-pages in visible, and invisible pages, and one of them throw inside updateViewportBoundaries.

Code flow that makes it throw:

  • _resizeHandler is getting called before attached.
  • updateViewportBoundaries calls window.getComputedStyle(this._scroller);
  • this._scroller is null, BAM!, there is a null exception.

"Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'."

Uncaught TypeError: Illegal invocationPolymer.Base._addFeature._applyConfig @ polymer.html:1647

The demo works fine using the code as shown on the front page. However, switching to my api starts to cause problems (Perhaps because of the nested resource?). Any thoughts?

I've used the following code:

<iron-ajax auto url="https://localhost:3000/foo/bar" handle-as="json" debounce-duration="300" last-response="{{ajaxResponse}}"></iron-ajax>

    <iron-list items="[[ajaxResponse.data]]" as="item">
      <template>
        <div>
          Name: <span>[[item.title]]</span>
        </div>
      </template>
    </iron-list>

I have an api returning:

{data: [
   {
      "title":"expedite strategic technologies",
      "id":1
   },
   {
      "title":"foo strategic technologies",
      "id":2
   }
]}

And get this stacktrace:

Uncaught TypeError: Illegal invocationPolymer.Base._addFeature._applyConfig @ polymer.html:1647
Polymer.Base._addFeature._afterClientsReady @ polymer.html:1642
Polymer.Base._addFeature._ready @ polymer-mini.html:62
Polymer.Base._addFeature._tryReady @ polymer-mini.html:52
Polymer.Templatizer._constructorImpl @ polymer.html:3233
TemplateInstance @ polymer.html:3071
Polymer.Templatizer.stamp @ polymer.html:3258
Polymer._itemsChanged @ iron-list.html:600
Polymer.Base.extend._complexObserverEffect @ polymer.html:1317
(anonymous function) @ polymer.html:1161
Polymer.Bind._modelApi._effectEffects @ polymer.html:1158
Polymer.Bind._modelApi._propertySetter @ polymer.html:1143
setter @ polymer.html:1219
Polymer.Base._addFeature._applyEffectValue @ polymer.html:1567
Polymer.Base.extend._annotationEffect @ polymer.html:1290
(anonymous function) @ polymer.html:1161
Polymer.Bind._modelApi._effectEffects @ polymer.html:1158
Polymer.Bind._modelApi._propertySetter @ polymer.html:1143
setter @ polymer.html:1219
(anonymous function) @ polymer.html:1259
Polymer.Base._addFeature._notifyListener @ polymer.html:1660
Polymer.Base._addFeature.fire @ polymer.html:1062
Polymer.Bind._modelApi._notifyChange @ polymer.html:1127
Polymer.Base.extend._notifyEffect @ polymer.html:1298
(anonymous function) @ polymer.html:1161
Polymer.Bind._modelApi._effectEffects @ polymer.html:1158
Polymer.Bind._modelApi._propertySetter @ polymer.html:1143
setter @ polymer.html:1219
Polymer._handleResponse @ iron-ajax.html:392

Google Chrome 43.0.2357.132 (Official Build) (64-bit)

changing items (hence list size) when fully scrolled causes problems

Very briefly, I've noticed that:

  1. If the user scrolls all the way down on a list,
  2. Then effects a new dataset/array change, which has a smaller amount of elements (and hence less height w.r.t the scroller)
  3. Then the list behaves "unusually"; in Chrome the scroller doesn't appear to move when the user clicks on it and they have to "scroll" all the way to the top for the list to show items again.

I can mock up a simple example if the above isn't sufficient

dom-change equivalent for iron-list

There doesn't seem to be an equivalent dom-change event (a la <template is="dom-repeat">) that's fired when iron-list has finished updating the list (i.e., after the items have changed, and the list is done rendering the first visible batch).

An event like dom-change would be nice.

The reason is I find myself sometimes needing to perform batch-like post-processing on the items after they're stamped/rendered.

Perhaps this is unrealistic or at odds with the intent of the component, but just bringing this up here to see if anyone else thinks similarly.

Re-rendering individual list items

I'm using iron-list to render a calendar where each item in the list is a month. Each month has its own array of days rendered using dom-repeat. A day is an object along the lines of {day: 1, active: false} with the active property indicating whether that day is the current date. A simplified version looks like this:

<iron-list items="{{months}}" as="month" index-as="monthIndex">
    <template>
        <div class="month">
            <template is="dom-repeat" items="{{month.days}}" as="day" index-as="day-index">
                <div class="day" active$="{{day.active}}">{{day.day}}</div>
            </template>
        </div>
    </template>
</iron-list>

months is a property of my custom element. When the date changes, I call this.months[monthIndex].days[dayIndex].active = true; When I inspect the months array, I can see that active property is true on the appropriate day object. However, the active attribute on the .day div doesn't get updated unless I scroll that month far out of the list and then back into view. Is there a way to re-render that one month div when one of its days changes? Is there a reason the active attribute isn't being updated?

1.0.0 MVP list

  • Fix position bugs if any
  • Fix data mutation bugs if any
  • Add unit tests
  • Add demos
  • Add docs

The _physicalCount never goes below its default value [20]

If you have less than 20 virtual items, rather than rendering only that count, the list will happily render all 20 physical items, even though the rest don't have any backing data. The extreme case is even more apparent, when the item count is actually 0.

The problem with the extreme case is that the items don't even have a hidden attribute. They are plainly visible.

iron-list dynamic change items, when each item is object

I don't sure is it an issue but i have problems with dynamic change of items content.

For example, I have an array of same objects with some fields and i put in iron-list as items.
In each item i show info from object, it works well.

But I need to edit some items, add or delete some text, when I do that nothing happens, iron-list
not re rendered, model of iron-list is updated after changes if I check this.$.list.items, I see that some fields of object in array were changed, but this new info not show in list, it show old info,
even this.$.list._update() doesn't help.

here is simple example
http://jsbin.com/pefecihayi/edit?html,console,output

Feature Backlog

  • Automatically adapting physicalItem count - p1 (Released in v1.0.1)
  • API to update the size of an item/subset of items - p1 (Released in v1.1.3)
  • Selection (single & multi) - p1 (Released in v1.1.0)
  • Grouping + dividers - p1
  • Grid - (Released in v1.3.0)
  • External scrollTarget (it currently works for paper-scroll-header-panel) (Released in v1.2.0)
    • Listen & measure on parent div
    • Measure offsetTop & take into account
  • Non-native scroller integration (Released in v1.2.0)
  • Accessibility (Released in v1.2.0)
  • Polymorphic templates
  • Swipable action sheets
  • Bottom-up mode
  • Horizontal mode
  • Drag-and-drop reordering

Problem with iron-list and paper-drawer-panel

Hello, i have a <paper-drawer-panel> with a <paper-header-panel drawer> for the side menu and a <paper-header-panel main> for the main window.

Inside <paper-header-panel main> i have a <paper-toolbar>.

On this <paper-toolbar> i have a <paper-button> with an <iron-ajax> calling a form to display in div#content on click.

On load i have an <iron-list> (copy/paste from demo1.html on iron-list documentation) which loads a json file (the one from the documentation).

<paper-drawer-panel force-narrow drawer-width="270px">
    <paper-header-panel drawer>
    ...
    </paper-header-panel>

    <paper-header-panel main>
        <paper-toolbar>
        ... //ajax button here
        </paper-toolbar>

        <div id="content">
            <x-app></x-app> //json file load
        </div>
    </paper-header-panel>
</paper-drawer-panel>

OK, it works. If i load page, list (json file appear), if i click on the button (ajax request), the form appear.

But if refresh (reload page), and i use the scrollbar to go to the end of the list, and next, click on the button (ajax request to load the form), nothing happen, no error on console, nothing. If i click another time (so, second time), the form loads.

In that case, (refresh, bottom with scrollbar, click), i need to click twice to load the form.

Now, if i remove <paper-drawer-panel>, like this:

    <paper-header-panel main>
        <paper-toolbar>
        ... //ajax button here
        </paper-toolbar>

        <div id="content">
            <x-app></x-app> //json file load
        </div>
    </paper-header-panel>

I haven't the problem, i can do what i want, refresh, scroll, click, it's ok.

So, maybe there is something wrong with iron-list/iron-ajax/paper-drawer-panel ?!

_updateMetrics called prematurely, causes Exception:

HTML below throws inside _increasePoolIfNeeded with:
Uncaught RangeError: Invalid array length iron-list:559
Reason is:
this._physicalAverage is 0
because:
this._updateMetrics got called before items measured have been attached to DOM, and offsetHeight of every physicalItem was 0 at time of measurement.
If I muck with the code, and make it not crash, items are displayed with proper height.
The stack before this._updateMetrics is
attached -> _render -> _update -> updateMetrics

To demonstrate the bug load:

<!doctype html>
<head>
<link rel="import" href="../iron-list/iron-list.html">
<link rel="import" href="../paper-scroll-header-panel/paper-scroll-header-panel.html">
<link rel="import" href="../paper-toolbar/paper-toolbar.html">
</head>
<body class="fullbleed">
  <paper-scroll-header-panel>
    <paper-toolbar>
      <div>Help</div>
      <div>Patients</div>
      <div>Search</div>
    </paper-toolbar>
    <section>
    <iron-list items='["a","b","c"]'>
      <template>
        <div>{{item}}</div>
      </template>
    </iron-list>
    </section>
  </paper-scroll-header-panel>
</body>

Hidden attribute doesn't work unless element is wrapped in a div.

The hidden attribute is not honored unless the element is wrapped in a div or another element. I know this sounds really strange, but I was able to duplicate the problem on the iron-list demo1 page.

For example, trying to set hidden as an HTML attribute or using JavaScript from within the element (in either the ready or attached callback) will fail with the following template HTML:

  <iron-list id="domain_list" height="40" style="overflow: scroll" items="[[matching]]" as="item">
    <template>
      <easy-reg-record hidden
        class="row">
      </easy-reg-record>
    </template>
  </iron-list>

But if you wrap easy-reg-record with a <div> tag, it will work.

adding items not possible

With a normal <template is="dom-repeat"> it is possible to update the list explicitly using .render(); but i don't see a way to do it with the <iron-list>. There is the private method ._update() which works but it's private and it also breaks if it's called too early.

My entire workaround is:

_updateList: function () {
    // workaround for https://github.com/PolymerElements/iron-list/issues/66
    var list = this.$.list;
    if (list._initRendered) {
        setTimeout(function () {
            list._update();
        }, 10);
    }
}

Iron-list doesn't update items during scrolling in PhoneGap app (iOS UIWebView)

The iron-list becomes empty as the user scrolls above/below the rendered items. The new items are only shown once the scrolling stops.
This seems to be caused by UIWebView not executing JavaScript during scrolling. Setting "-webkit-overflow-scrolling:auto" makes the iron-list update the items immediately but results in a very poor overall scrolling experience.

Min-height limits items.

The current system does not honor max-height settings, core-list did. I originally thought that this was a max-height problem, but the real culprit was a min-height height setting, this would restrict the list to only displaying 20 items.

Reversing the "get firstVisibleIndex()" function

Question,

Hi,

The get firstVisibleIndex() function in the iron-list.html file is great for getting the first visible item in the viewport.

Unfortunately i've been using Jquery all these years and my Js skills just starting to surface with Polymer.

How will one go about reversing that, getting the index id of the last item currently in the viewport?.

i.e a function called get lastVisibleIndex()

This will be helpful for pushing new items on the list as you have a virtual count of items to compare with and would be great for any screen size to record the bottom item rather than the top.

Thought to ask this question here rather than SO because these functions are inbuilt into iron-list.html file

Thanks

Setting iron-list to display: none destroys the list

Hi,

I noticed this issue

Setting the iron-list to display: none and back to display: "" seems to destroy the list.

This happens if i have scrolled down a bit on the list. If its at the Top then its ok.

The Reason why i need to do that is because i have a main iron-list and 2 more on dialog's

If the main iron-list is displayed and then i open a dialog, the dialog's iron-list scroll performance is very poor and i get flickers.

Setting the main list 500ms after i open the dialog to display: none fixes that issue but when i close the dialog and set the main list back to display: "" destroys it

I assume the main list requires a refresh

Is this possible, any other workarounds for the performance issue?

Device LG V400 tablet,
Android App wrapped in Latest Crosswalk

I tried putting the Dialog's list on the hardware layer

-webkit-transform: translateZ(0);
&
-webkit-transform: translate3d(0,0,0);

to see if it will help with the performance but no go , probably is already.

Thanks

Scrollbar appears behind element (safari)

When list items contain content that should appear behind the scroll bar (in our case bottom borders and on-hover background), the scrollbar appears behind the content.

This happens on Safari (8.0.7) but appears fine on Chrome.

bug

iron-list scrolling is laggy on iOS after first 20 items

I've have an iron-list element running buttery smooth on desktop but is very laggy on iOS simulator or device. If you scroll quickly on iOS the items jump back up and often white space is left until the scrollbar comes to a complete halt.

Polymer 1.0 iron-list project:
https://www.dropbox.com/s/oxihd7eddknbq5b/PolymerIronList.zip?dl=0
localhost setup: npm install && bower install then run with node server.js.

Sample iOS project to just build & run:
https://www.dropbox.com/s/w1xtjzyf53s4pfz/PolymerApp.zip?dl=0

Is this something with flex vs fit layout or a bug?

Poor scrolling performance on multiple iron lists

Hi,

If you have an iron-list on the main page and another on a dialog, once you open the dialog the scrolling performance is poor and you get flickers.

However, sliding up the main list or setting it to display:none; fixes the scrolling performance on the dialog.

would anyone know the reason why that happens. in regards to the poor scrolling performance?

people would want an iron-list on a dialog for Bookmarks, search list etc but as it stands the users would get a bad experience with scrolling flickers

Assuming its because the dialog has position:fixed; i'm wondering why when you set the main list to display:none; fixes the scrolling performance.

I thought maybe adding backface-visibility: hidden; to the dialog and/or iron-list may help, but it didn't.

Resolution in issue #39 is a workaround for now.

Thanks

This issue appears when using the following specs

Device - LG400 Tablet --- Os - Android Lollipop --- Android App with Crosswalk Embedding API

Problems with item update on scrolling when there is an elements in between of paper-scroll-header-pandel and iron-list

In medium large project there is need to put iron-list into the custom element. That produces spare elements in between of paper-scroll-header-panel and iron-list. Even just

produces problem: only first 20 elements are rendered, and then comes only white space.
If I add fit class to that intemediate
element, then first two list items are hidden behind the paper-toolbar.
Please try to play with
element by yourself in my jsbin: JS Bin on jsbin.com<script src="http://static.jsbin.com/js/embed.min.js?3.34.1"></script>
Please, help me solve that issue.

Anything equivalent to the old core-list.refresh(true) method?

I used the old .refresh(true) method to update the list whenever I made a change to a property of one of the items. I was hoping that the list would update an item whenever I did this.set('item.' + index + '.something', some_value), but that doesn't seem to be the case. So how do I force the list to refresh itself?

Container height is not set properly when iron-list is in flexbox container

My iron-list is sized inside a flex parent. So no explicit height but sized. The wrapper element is getting set to the full height of the scroll container (height: 28382px in the screenshot) instead of the height of the physical viewport. This causes the list not to regenerate on scroll.

screen shot 2015-08-22 at 10 15 55 am

My current workaround is to set the height of the list on attached:

attached: function() {
  this.$.ironlist.style.height = Polymer.dom(this).node.clientHeight + 'px';
},

Support paged data queries

For truly infinite lists, or even very large lists, it would be preferable to be able to query the server for a limited number of records. If a browser can display 5 records at a time, the application would probably still want to query a larger dataset - say 10 (displayable records + cached buffer).

  • When the user scrolls one or two records the iron-list component would just update the display (if required).
  • When the user scrolls close enough to the buffer, the component should fire an event which can be used to send an ajax request for the next page (might need to support scrolling up as well as down).
  • Applications might also want to be able to remove the pages of data which are well beyond the current scroll position.

Why must index be explicitly declared?

As per the docs, "List item templates should bind to template models of the following structure:"

{
    index: 0,     // data index for this item
    item: {       // user data corresponding to items[index]
        /* user item data  */
    }
}

Can you help me understand why the index must be explicitly provided to iron-list vs iron-list implicitly knowing and providing this data upon each rendered iteration?

Dynamic updates to list items not rendering properly

I think this may be the same as #12 but that one seems to be getting convoluted so thought I'd open up these easy to reproduce steps. You can update demo1.html with the following to see the problem:

Change:

<iron-ajax url="data/contacts.json" last-response="{{data}}" auto></iron-ajax>

to

<iron-ajax url="data/contacts.json" on-response="dataReceived" auto></iron-ajax>

and add the following function:

        dataReceived: function(e) {
          this.data = [];
          var data = e.detail.response;
          //adds 10 items to the list every 3 seconds
          while (data.length > 0) {
            var items = data.splice(0, 10);
            this.async(function(items) {
              items.forEach(function(item){
                this.push('data', item);
              }.bind(this));
            }.bind(this, items), (50-(data.length/10)) * 3000);
          }
        }

to the x-app element implementation.

The idea is that instead of adding all the items directly it adds 10 at a time every 3 seconds. To see the issue:

  1. Whenever new items are added scroll to the bottom of the list & wait for more items to be added.
  2. You'll see a slight jump when new items are added - then scroll down a bit more to reveal them.

Result:
For the first 20 items things are ok. After that though you end up with a lot of jank. Usually items don't appear right away but then they'll flash in after waiting a bit or moving the list around.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.