@@ -134,8 +134,10 @@ model data that generated a given element. (There are also corresponding
134
134
To filter or sort the _ displayed_ items in your list, specify a ` filter ` or
135
135
` sort ` property on the ` dom-repeat ` (or both):
136
136
137
- * ` filter ` . Specifies a filter callback function following the standard
138
- ` Array ` [ ` filter ` ] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter ) API.
137
+ * ` filter ` . Specifies a filter callback function, that takes a single argument
138
+ (the item) and returns true to display the item, false to omit it.
139
+ (Note that this is ** similar** to the standard
140
+ ` Array ` [ ` filter ` ] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter ) API, but the callback only takes a single argument.)
139
141
* ` sort ` . Specifies a comparison function following the standard ` Array `
140
142
[ ` sort ` ] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort ) API.
141
143
@@ -166,6 +168,79 @@ Changing a `manager.type` field should now cause the list to be re-sorted:
166
168
167
169
this.set('employees.0.manager.type', 'engineer');
168
170
171
+ #### Dynamic sort and filter changes
172
+
173
+ The ` observe ` property lets you specify item sub-properties to
174
+ observe for filtering and sorting purposes. However, sometimes you want to
175
+ dynamically change the sort or filter based on another unrelated value. In
176
+ this case, you can use a computed binding to _ return_ a dynamic filter or
177
+ sort function when one or more dependent properties changes.
178
+
179
+ <dom-module id="employee-search">
180
+
181
+ <template>{% raw %}
182
+ <input value="{{searchString::change}}">
183
+ <template is="dom-repeat" items="{{employees}}" as="employee"
184
+ filter="{{matches(searchString)}}">
185
+ <div>{{employee.lastname}}, {{employee.firstname}}</div>
186
+ </template>{% endraw %}
187
+ </template>
188
+
189
+ <script>
190
+ Polymer({
191
+ is: "employee-search",
192
+ matches: function(string) {
193
+ if (!string) {
194
+ // if no search string, show all records
195
+ return function() { return true; }
196
+ } else {
197
+ // return a filter function for the current search string
198
+ string = string.toLowerCase();
199
+ return function(employee) {
200
+ var first = employee.firstname.toLowerCase();
201
+ var last = employee.lastname.toLowerCase();
202
+ return first.includes(string) ||
203
+ last.includes(string);
204
+ }
205
+ }
206
+ },
207
+ properties: {
208
+ employees: {
209
+ type: Array,
210
+ value: function() {
211
+ return [
212
+ { firstname: "Jack", lastname: "Aubrey" },
213
+ { firstname: "Anne", lastname: "Elliot" },
214
+ { firstname: "Stepehen", lastname: "Maturin" },
215
+ { firstname: "Emma", lastname: "Woodhouse" }
216
+ ]
217
+ }
218
+ }
219
+ }
220
+ });
221
+ </script>
222
+ </dom-module>
223
+
224
+ #### Filtering on array index
225
+
226
+ Because of the way {{site.project_title}} tracks arrays internally, the array
227
+ index isn't passed to the filter function. Looking up the array index for an
228
+ item is an O(n) operation. Doing so in a filter function could have
229
+ ** significant performance impact** .
230
+
231
+ If you want to look up the array index, you can use code like this:
232
+
233
+ filter: function(item) {
234
+ var index = this.items.indexOf(item);
235
+ ...
236
+ }
237
+
238
+ The filter function is called with the ` dom-repeat ` as the ` this ` value, so
239
+ you can access the original array as ` this.items ` and use it to look up the index.
240
+
241
+ This lookup returns the items index in the ** original** array, which may not match
242
+ the index of the array as displayed (filtered and sorted).
243
+
169
244
### Nesting dom-repeat templates {#nesting-templates}
170
245
171
246
When nesting multiple ` dom-repeat ` templates, you may want to access data
0 commit comments