I am looking to sort data in an iron-list (and also sort items as they are added into the data array).
Sample (unsorted) json data:
[
{"name": "Zebra"},
{"name": "Alligator"},
{"name": "Lion"}
]
I have tried using the indexAs
property to sort an iron-list
as follows but the API isn't clear how to use it:
<iron-ajax url="./data.json" last-response="{{data}}" auto></iron-ajax>
<iron-list items="[[data]]" as="item" index-as="name" class="fit">
<template>
<div>
Name: <span>[[item.name]]</span>
</div>
</template>
</iron-list>
I'm not exactly sure if there's more native Polymer way to do this, but it's not too complex to build the sorting logic yourself.
The idea is to listen to the response
event, sort the data from the service and then bind the items
of the iron-list
to the sortedData
.
You will need to add on-response="_onResponseReceived"
to your iron-ajax
. And then it's just a matter of sorting the returned data.
_onResponseReceived: function () {
this.sortedData = this.data.sort(this._compare);
},
_compare: function (a, b) {
if (a.name < b.name)
return -1;
if (a.name > b.name)
return 1;
return 0;
}
Of course the iron-list
now needs to be updated to
<iron-list items="[[sortedData]]" ...>
With Polymer 1.2.4 if you want to sort an iron-list
in a dynamic fashion you can also take advantage of this.querySelector('iron-list').notifyResize();
to force a refresh after you update the sortedItems
array in your observer. This is a hack but if you don't do this unfortunately polymer doesn't refresh the list for you. Let's sort by id
or name
our items:
<template>
<paper-icon-button icon="expand-more" on-tap="_sortItems" sort-option="id"></paper-icon-button>
<paper-icon-button icon="expand-more" on-tap="_sortItems" sort-option="name"></paper-icon-button>
<iron-list items="[[sortedItems]]">
<template>
<p>[[item.name]]<p>
</template>
</iron-list>
</template>
...
properties: {
...
sortByTerm: {
type: String,
value: 'id'
},
sortByOrder: {
type: Number,
value: -1 // Descending order
},
},
observers: [
'sortingObserver(items.*, sortByTerm, sortByOrder)'
],
sortingObserver: function(items, sortByTerm, sortByOrder) {
var sortedItems = [],
validSortingOptions = ['id', 'name'];
if (validSortingOptions.indexOf(sortByTerm) != -1) {
sortedItems = items.base.sort(this._computeSort(sortByTerm, sortByOrder));
} else {
sortedItems = items.base;
}
this.set('sortedItems', sortedItems);
this.querySelector('iron-list').notifyResize();
},
_computeSort: function(property, order) {
return function(a, b) {
if (a[property] === b[property]) {
return 0;
}
return (order * (a[property] > b[property] ? 1 : -1));
};
},
_sortItems: function(e) {
var sortByTerm = e.currentTarget.getAttribute('sort-option');
this.set('sortByTerm', sortByTerm);
},
...