1 <!-- 2 @license 3 Copyright (c) 2015 The Polymer Project Authors. All rights reserved. 4 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 6 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 7 Code distributed by Google as part of the polymer project is also 8 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 9 --> 10 11 <link rel="import" href="../polymer/polymer.html"> 12 <link rel="import" href="iron-selectable.html"> 13 14 <script> 15 /** @polymerBehavior Polymer.IronMultiSelectableBehavior */ 16 Polymer.IronMultiSelectableBehaviorImpl = { 17 properties: { 18 19 /** 20 * If true, multiple selections are allowed. 21 */ 22 multi: { 23 type: Boolean, 24 value: false, 25 observer: 'multiChanged' 26 }, 27 28 /** 29 * Gets or sets the selected elements. This is used instead of `selected` when `multi` 30 * is true. 31 */ 32 selectedValues: { 33 type: Array, 34 notify: true 35 }, 36 37 /** 38 * Returns an array of currently selected items. 39 */ 40 selectedItems: { 41 type: Array, 42 readOnly: true, 43 notify: true 44 }, 45 46 }, 47 48 observers: [ 49 '_updateSelected(selectedValues.splices)' 50 ], 51 52 /** 53 * Selects the given value. If the `multi` property is true, then the selected state of the 54 * `value` will be toggled; otherwise the `value` will be selected. 55 * 56 * @method select 57 * @param {string|number} value the value to select. 58 */ 59 select: function(value) { 60 if (this.multi) { 61 if (this.selectedValues) { 62 this._toggleSelected(value); 63 } else { 64 this.selectedValues = [value]; 65 } 66 } else { 67 this.selected = value; 68 } 69 }, 70 71 multiChanged: function(multi) { 72 this._selection.multi = multi; 73 }, 74 75 get _shouldUpdateSelection() { 76 return this.selected != null || 77 (this.selectedValues != null && this.selectedValues.length); 78 }, 79 80 _updateAttrForSelected: function() { 81 if (!this.multi) { 82 Polymer.IronSelectableBehavior._updateAttrForSelected.apply(this); 83 } else if (this._shouldUpdateSelection) { 84 this.selectedValues = this.selectedItems.map(function(selectedItem) { 85 return this._indexToValue(this.indexOf(selectedItem)); 86 }, this).filter(function(unfilteredValue) { 87 return unfilteredValue != null; 88 }, this); 89 } 90 }, 91 92 _updateSelected: function() { 93 if (this.multi) { 94 this._selectMulti(this.selectedValues); 95 } else { 96 this._selectSelected(this.selected); 97 } 98 }, 99 100 _selectMulti: function(values) { 101 if (values) { 102 var selectedItems = this._valuesToItems(values); 103 // clear all but the current selected items 104 this._selection.clear(selectedItems); 105 // select only those not selected yet 106 for (var i = 0; i < selectedItems.length; i++) { 107 this._selection.setItemSelected(selectedItems[i], true); 108 } 109 // Check for items, since this array is populated only when attached 110 if (this.fallbackSelection && this.items.length && !this._selection.get().length) { 111 var fallback = this._valueToItem(this.fallbackSelection); 112 if (fallback) { 113 this.selectedValues = [this.fallbackSelection]; 114 } 115 } 116 } else { 117 this._selection.clear(); 118 } 119 }, 120 121 _selectionChange: function() { 122 var s = this._selection.get(); 123 if (this.multi) { 124 this._setSelectedItems(s); 125 } else { 126 this._setSelectedItems([s]); 127 this._setSelectedItem(s); 128 } 129 }, 130 131 _toggleSelected: function(value) { 132 var i = this.selectedValues.indexOf(value); 133 var unselected = i < 0; 134 if (unselected) { 135 this.push('selectedValues',value); 136 } else { 137 this.splice('selectedValues',i,1); 138 } 139 }, 140 141 _valuesToItems: function(values) { 142 return (values == null) ? null : values.map(function(value) { 143 return this._valueToItem(value); 144 }, this); 145 } 146 }; 147 148 /** @polymerBehavior */ 149 Polymer.IronMultiSelectableBehavior = [ 150 Polymer.IronSelectableBehavior, 151 Polymer.IronMultiSelectableBehaviorImpl 152 ]; 153 154 </script> 155