• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<!--
2@license
3Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
4This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
5The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
7Code distributed by Google as part of the polymer project is also
8subject 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