Home | History | Annotate | Download | only in iron-selector
      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