Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: samples/third_party/todomvc/web/lib-elements/polymer-selector.html

Issue 182193002: [polymer] interop with polymer-element and polymer.js (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 <!--
2 Copyright 2013 The Polymer Authors. All rights reserved.
3 Use of this source code is governed by a BSD-style
4 license that can be found in the LICENSE file.
5 -->
6 <!--
7 /**
8 * @module Polymer Elements
9 */
10 /**
11 * polymer-selector is used to manage a list of elements that can be selected.
12 * The attribute "selected" indicates which item element is being selected.
13 * The attribute "multi" indicates if multiple items can be selected at once.
14 * Tapping on the item element would fire "polymer-activate" event. Use
15 * "polymer-select" event to listen for selection changes.
16 *
17 * Example:
18 *
19 * <polymer-selector selected="0">
20 * <div>Item 1</div>
21 * <div>Item 2</div>
22 * <div>Item 3</div>
23 * </polymer-selector>
24 *
25 * polymer-selector is not styled. So one needs to use "polymer-selected" CSS
26 * class to style the selected element.
27 *
28 * <style>
29 * .item.polymer-selected {
30 * background: #eee;
31 * }
32 * </style>
33 * ...
34 * <polymer-selector>
35 * <div class="item">Item 1</div>
36 * <div class="item">Item 2</div>
37 * <div class="item">Item 3</div>
38 * </polymer-selector>
39 *
40 * @class polymer-selector
41 */
42 /**
43 * Fired when an item's selection state is changed. This event is fired both
44 * when an item is selected or deselected. The `isSelected` detail property
45 * contains the selection state.
46 *
47 * @event polymer-select
48 * @param {Object} detail
49 * @param {boolean} detail.isSelected true for selection and false for deselec tion
50 * @param {Object} detail.item the item element
51 */
52 /**
53 * Fired when an item element is tapped.
54 *
55 * @event polymer-activate
56 * @param {Object} detail
57 * @param {Object} detail.item the item element
58 */
59 -->
60 <link rel="import" href="polymer-selection.html">
61
62 <polymer-element name="polymer-selector"
63 attributes="selected multi valueattr selectedClass selectedProperty selected Item selectedModel selectedIndex notap target itemsSelector activateEvent">
64 <template>
65 <polymer-selection id="selection" multi="{{multi}}" on-polymer-select="{{sel ectionSelect}}"></polymer-selection>
66 <content id="items" select="*"></content>
67 </template>
68 <script>
69 Polymer('polymer-selector', {
70 /**
71 * Gets or sets the selected element. Default to use the index
72 * of the item element.
73 *
74 * If you want a specific attribute value of the element to be
75 * used instead of index, set "valueattr" to that attribute name.
76 *
77 * Example:
78 *
79 * <polymer-selector valueattr="label" selected="foo">
80 * <div label="foo"></div>
81 * <div label="bar"></div>
82 * <div label="zot"></div>
83 * </polymer-selector>
84 *
85 * In multi-selection this should be an array of values.
86 *
87 * Example:
88 *
89 * <polymer-selector id="selector" valueattr="label" multi>
90 * <div label="foo"></div>
91 * <div label="bar"></div>
92 * <div label="zot"></div>
93 * </polymer-selector>
94 *
95 * this.$.selector.selected = ['foo', 'zot'];
96 *
97 * @attribute selected
98 * @type Object
99 * @default null
100 */
101 selected: null,
102 /**
103 * If true, multiple selections are allowed.
104 *
105 * @attribute multi
106 * @type boolean
107 * @default false
108 */
109 multi: false,
110 /**
111 * Specifies the attribute to be used for "selected" attribute.
112 *
113 * @attribute valueattr
114 * @type string
115 * @default 'name'
116 */
117 valueattr: 'name',
118 /**
119 * Specifies the CSS class to be used to add to the selected element.
120 *
121 * @attribute selectedClass
122 * @type string
123 * @default 'polymer-selected'
124 */
125 selectedClass: 'polymer-selected',
126 /**
127 * Specifies the property to be used to set on the selected element
128 * to indicate its active state.
129 *
130 * @attribute selectedProperty
131 * @type string
132 * @default 'active'
133 */
134 selectedProperty: 'active',
135 /**
136 * Returns the currently selected element. In multi-selection this returns
137 * an array of selected elements.
138 *
139 * @attribute selectedItem
140 * @type Object
141 * @default null
142 */
143 selectedItem: null,
144 /**
145 * In single selection, this returns the model associated with the
146 * selected element.
147 *
148 * @attribute selectedModel
149 * @type Object
150 * @default null
151 */
152 selectedModel: null,
153 /**
154 * In single selection, this returns the selected index.
155 *
156 * @attribute selectedIndex
157 * @type number
158 * @default -1
159 */
160 selectedIndex: -1,
161 /**
162 * The target element that contains items. If this is not set
163 * polymer-selector is the container.
164 *
165 * @attribute target
166 * @type Object
167 * @default null
168 */
169 target: null,
170 /**
171 * This can be used to query nodes from the target node to be used for
172 * selection items. Note this only works if the 'target' property is set.
173 *
174 * Example:
175 *
176 * <polymer-selector target="{{$.myForm}}" itemsSelector="input[type=r adio]"></polymer-selector>
177 * <form id="myForm">
178 * <label><input type="radio" name="color" value="red"> Red</label> <br>
179 * <label><input type="radio" name="color" value="green"> Green</lab el> <br>
180 * <label><input type="radio" name="color" value="blue"> Blue</label > <br>
181 * <p>color = {{color}}</p>
182 * </form>
183 *
184 * @attribute itemSelector
185 * @type string
186 * @default ''
187 */
188 itemsSelector: '',
189 /**
190 * The event that would be fired from the item element to indicate
191 * it is being selected.
192 *
193 * @attribute activateEvent
194 * @type string
195 * @default 'tap'
196 */
197 activateEvent: 'tap',
198 notap: false,
199 ready: function() {
200 this.activateListener = this.activateHandler.bind(this);
201 this.observer = new MutationObserver(this.updateSelected.bind(this));
202 if (!this.target) {
203 this.target = this;
204 }
205 },
206 get items() {
207 var nodes = this.target !== this ? (this.itemsSelector ?
208 this.target.querySelectorAll(this.itemsSelector) :
209 this.target.children) : this.$.items.getDistributedNodes();
210 return Array.prototype.filter.call(nodes || [], function(n) {
211 return n && n.localName !== 'template';
212 });
213 },
214 targetChanged: function(old) {
215 if (old) {
216 this.removeListener(old);
217 this.observer.disconnect();
218 }
219 if (this.target) {
220 this.addListener(this.target);
221 this.observer.observe(this.target, {childList: true});
222 }
223 },
224 addListener: function(node) {
225 node.addEventListener(this.activateEvent, this.activateListener);
226 },
227 removeListener: function(node) {
228 node.removeEventListener(this.activateEvent, this.activateListener);
229 },
230 get selection() {
231 return this.$.selection.getSelection();
232 },
233 selectedChanged: function() {
234 this.updateSelected();
235 },
236 updateSelected: function() {
237 this.validateSelected();
238 if (this.multi) {
239 this.clearSelection();
240 this.selected && this.selected.forEach(function(s) {
241 this.valueToSelection(s);
242 }, this);
243 } else {
244 this.valueToSelection(this.selected);
245 }
246 },
247 validateSelected: function() {
248 // convert to an array for multi-selection
249 if (this.multi && !Array.isArray(this.selected) &&
250 this.selected !== null && this.selected !== undefined) {
251 this.selected = [this.selected];
252 }
253 },
254 clearSelection: function() {
255 if (this.multi) {
256 this.selection.slice().forEach(function(s) {
257 this.$.selection.setItemSelected(s, false);
258 }, this);
259 } else {
260 this.$.selection.setItemSelected(this.selection, false);
261 }
262 this.selectedItem = null;
263 this.$.selection.clear();
264 },
265 valueToSelection: function(value) {
266 var item = (value === null || value === undefined) ?
267 null : this.items[this.valueToIndex(value)];
268 this.$.selection.select(item);
269 },
270 updateSelectedItem: function() {
271 this.selectedItem = this.selection;
272 },
273 selectedItemChanged: function() {
274 if (this.selectedItem) {
275 var t = this.selectedItem.templateInstance;
276 this.selectedModel = t ? t.model : undefined;
277 } else {
278 this.selectedModel = null;
279 }
280 this.selectedIndex = this.selectedItem ?
281 parseInt(this.valueToIndex(this.selected)) : -1;
282 },
283 valueToIndex: function(value) {
284 // find an item with value == value and return it's index
285 for (var i=0, items=this.items, c; (c=items[i]); i++) {
286 if (this.valueForNode(c) == value) {
287 return i;
288 }
289 }
290 // if no item found, the value itself is probably the index
291 return value;
292 },
293 valueForNode: function(node) {
294 return node[this.valueattr] || node.getAttribute(this.valueattr);
295 },
296 // events fired from <polymer-selection> object
297 selectionSelect: function(e, detail) {
298 this.updateSelectedItem();
299 if (detail.item) {
300 this.applySelection(detail.item, detail.isSelected)
301 }
302 },
303 applySelection: function(item, isSelected) {
304 if (this.selectedClass) {
305 item.classList.toggle(this.selectedClass, isSelected);
306 }
307 if (this.selectedProperty) {
308 item[this.selectedProperty] = isSelected;
309 }
310 },
311 // event fired from host
312 activateHandler: function(e) {
313 if (!this.notap) {
314 var i = this.findDistributedTarget(e.target, this.items);
315 if (i >= 0) {
316 var item = this.items[i];
317 var s = this.valueForNode(item) || i;
318 if (this.multi) {
319 if (this.selected) {
320 this.addRemoveSelected(s);
321 } else {
322 this.selected = [s];
323 }
324 } else {
325 this.selected = s;
326 }
327 this.asyncFire('polymer-activate', {item: item});
328 }
329 }
330 },
331 addRemoveSelected: function(value) {
332 var i = this.selected.indexOf(value);
333 if (i >= 0) {
334 this.selected.splice(i, 1);
335 } else {
336 this.selected.push(value);
337 }
338 this.valueToSelection(value);
339 },
340 findDistributedTarget: function(target, nodes) {
341 // find first ancestor of target (including itself) that
342 // is in nodes, if any
343 while (target && target != this) {
344 var i = Array.prototype.indexOf.call(nodes, target);
345 if (i >= 0) {
346 return i;
347 }
348 target = target.parentNode;
349 }
350 }
351 });
352 </script>
353 </polymer-element>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698