-
Notifications
You must be signed in to change notification settings - Fork 5
/
vaadin-multi-select-list-mixin.html
127 lines (113 loc) · 3.49 KB
/
vaadin-multi-select-list-mixin.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<!--
@license
Copyright (c) 2019 Vaadin Ltd.
This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
-->
<link rel="import" href="vaadin-list-mixin.html">
<script>
/**
* @namespace Vaadin
*/
window.Vaadin = window.Vaadin || {};
/**
* A mixin for `nav` elements, facilitating multiple selection of childNodes.
*
* @polymerMixin
* @memberof Vaadin
* @mixes Vaadin.ListMixin
*/
Vaadin.MultiSelectListMixin = superClass => class VaadinMultiSelectListMixin extends Vaadin.ListMixin(superClass) {
static get properties() {
return {
/**
* Specifies that multiple options can be selected at once.
*/
multiple: {
type: Boolean,
value: false,
reflectToAttribute: true,
observer: '_multipleChanged'
},
/**
* Array of indexes of the items selected in the items array
* Note: Not updated when used in single selection mode.
* @type {string[] | null | undefined}
*/
selectedValues: {
type: Array,
notify: true,
value: function() {
return [];
}
}
};
}
static get observers() {
return [
`_enhanceMultipleItems(items, multiple, selected, selectedValues, selectedValues.*)`
];
}
/** @protected */
ready() {
// Should be attached before click listener in list-mixin
this.addEventListener('click', e => this._onMultipleClick(e));
super.ready();
}
/** @private */
_enhanceMultipleItems(items, multiple, selected, selectedValues) {
if (!items || !multiple) {
return;
}
if (selectedValues) {
const selectedItems = selectedValues.map(selectedId => items[selectedId]);
items.forEach(item => item.selected = selectedItems.indexOf(item) !== -1);
}
this._scrollToLastSelectedItem();
}
/** @private */
_scrollToLastSelectedItem() {
const lastSelectedItem = this.selectedValues.slice(-1)[0];
if (lastSelectedItem && !lastSelectedItem.disabled) {
this._scrollToItem(lastSelectedItem);
}
}
/**
* @param {!MouseEvent} event
* @protected
*/
_onMultipleClick(event) {
const item = this._filterItems(event.composedPath())[0];
const idx = item && !item.disabled ? this.items.indexOf(item) : -1;
if (idx < 0 || !this.multiple) {
return;
}
event.preventDefault();
if (this.selectedValues.indexOf(idx) !== -1) {
this.selectedValues = this.selectedValues.filter(v => v !== idx);
} else {
this.selectedValues = this.selectedValues.concat(idx);
}
}
/** @private */
_multipleChanged(value, oldValue) {
// Changing from multiple to single selection, clear selection.
if (!value && oldValue) {
this.selectedValues = [];
this.items.forEach(item => item.selected = false);
}
// Changing from single to multiple selection, add selected to selectedValues.
if (value && !oldValue && this.selected !== undefined) {
this.push('selectedValues', this.selected);
this.selected = undefined;
}
}
/**
* Fired when the selection is changed.
* Not fired in single selection mode.
*
* @event selected-values-changed
* @param {Object} detail
* @param {Object} detail.value the array of indexes of the items selected in the items array.
*/
};
</script>