<!-- @license Copyright (c) 2015 The Polymer Project Authors. All rights reserved. This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as part of the polymer project is also subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt --> <link rel="import" href="../polymer/polymer.html"> <link rel="import" href="iron-selectable.html"> <script> /** @polymerBehavior Polymer.IronMultiSelectableBehavior */ Polymer.IronMultiSelectableBehaviorImpl = { properties: { /** * If true, multiple selections are allowed. */ multi: { type: Boolean, value: false, observer: 'multiChanged' }, /** * Gets or sets the selected elements. This is used instead of `selected` when `multi` * is true. */ selectedValues: { type: Array, notify: true }, /** * Returns an array of currently selected items. */ selectedItems: { type: Array, readOnly: true, notify: true }, }, observers: [ '_updateSelected(selectedValues.splices)' ], /** * Selects the given value. If the `multi` property is true, then the selected state of the * `value` will be toggled; otherwise the `value` will be selected. * * @method select * @param {string|number} value the value to select. */ select: function(value) { if (this.multi) { if (this.selectedValues) { this._toggleSelected(value); } else { this.selectedValues = [value]; } } else { this.selected = value; } }, multiChanged: function(multi) { this._selection.multi = multi; }, get _shouldUpdateSelection() { return this.selected != null || (this.selectedValues != null && this.selectedValues.length); }, _updateAttrForSelected: function() { if (!this.multi) { Polymer.IronSelectableBehavior._updateAttrForSelected.apply(this); } else if (this._shouldUpdateSelection) { this.selectedValues = this.selectedItems.map(function(selectedItem) { return this._indexToValue(this.indexOf(selectedItem)); }, this).filter(function(unfilteredValue) { return unfilteredValue != null; }, this); } }, _updateSelected: function() { if (this.multi) { this._selectMulti(this.selectedValues); } else { this._selectSelected(this.selected); } }, _selectMulti: function(values) { if (values) { var selectedItems = this._valuesToItems(values); // clear all but the current selected items this._selection.clear(selectedItems); // select only those not selected yet for (var i = 0; i < selectedItems.length; i++) { this._selection.setItemSelected(selectedItems[i], true); } // Check for items, since this array is populated only when attached if (this.fallbackSelection && this.items.length && !this._selection.get().length) { var fallback = this._valueToItem(this.fallbackSelection); if (fallback) { this.selectedValues = [this.fallbackSelection]; } } } else { this._selection.clear(); } }, _selectionChange: function() { var s = this._selection.get(); if (this.multi) { this._setSelectedItems(s); } else { this._setSelectedItems([s]); this._setSelectedItem(s); } }, _toggleSelected: function(value) { var i = this.selectedValues.indexOf(value); var unselected = i < 0; if (unselected) { this.push('selectedValues',value); } else { this.splice('selectedValues',i,1); } }, _valuesToItems: function(values) { return (values == null) ? null : values.map(function(value) { return this._valueToItem(value); }, this); } }; /** @polymerBehavior */ Polymer.IronMultiSelectableBehavior = [ Polymer.IronSelectableBehavior, Polymer.IronMultiSelectableBehaviorImpl ]; </script>