@lemonadejs/dropdown 3.0.4 → 3.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +57 -155
- package/dist/index.js +629 -332
- package/dist/react.js +36 -36
- package/dist/style.css +242 -178
- package/dist/vue.js +45 -45
- package/package.json +22 -23
package/dist/index.js
CHANGED
|
@@ -1,333 +1,630 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Implementar o page up and down
|
|
3
|
-
* botao reset e done
|
|
4
|
-
* traducoes
|
|
5
|
-
*/
|
|
6
|
-
if (!lemonade && typeof (require) === 'function') {
|
|
7
|
-
var lemonade = require('lemonadejs');
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
if (!Modal && typeof (require) === 'function') {
|
|
11
|
-
var Modal = require('@lemonadejs/modal');
|
|
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
|
-
// Go
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if (
|
|
278
|
-
self.
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
//
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Implementar o page up and down
|
|
3
|
+
* botao reset e done
|
|
4
|
+
* traducoes
|
|
5
|
+
*/
|
|
6
|
+
if (!lemonade && typeof (require) === 'function') {
|
|
7
|
+
var lemonade = require('lemonadejs');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (!Modal && typeof (require) === 'function') {
|
|
11
|
+
var Modal = require('@lemonadejs/modal');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
; (function (global, factory) {
|
|
15
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
16
|
+
typeof define === 'function' && define.amd ? define(factory) :
|
|
17
|
+
global.Dropdown = factory();
|
|
18
|
+
}(this, (function () {
|
|
19
|
+
|
|
20
|
+
// Default row height
|
|
21
|
+
let defaultRowHeight = 24;
|
|
22
|
+
|
|
23
|
+
const lazyLoading = function(self) {
|
|
24
|
+
/**
|
|
25
|
+
* Compare two arrays to see if contains exact the same elements
|
|
26
|
+
* @param {number[]} a1
|
|
27
|
+
* @param {number[]} a2
|
|
28
|
+
*/
|
|
29
|
+
const compareArray = function (a1, a2) {
|
|
30
|
+
if (! a1 || ! a2) {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let i = a1.length;
|
|
35
|
+
if (i !== a2.length) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
while (i--) {
|
|
39
|
+
if (a1[i] !== a2[i]) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get the position from top of a row by its index
|
|
48
|
+
* @param item
|
|
49
|
+
* @returns {number}
|
|
50
|
+
*/
|
|
51
|
+
const getRowPosition = function(item) {
|
|
52
|
+
// Position from top
|
|
53
|
+
let top = 0;
|
|
54
|
+
if (item) {
|
|
55
|
+
let items = self.rows;
|
|
56
|
+
if (items && items.length) {
|
|
57
|
+
let index = self.rows.indexOf(item);
|
|
58
|
+
// Go through the items
|
|
59
|
+
for (let j = 0; j < index; j++) {
|
|
60
|
+
top += items[j].height || defaultRowHeight;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return top;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const updateScroll = function() {
|
|
68
|
+
let items = self.rows;
|
|
69
|
+
if (items) {
|
|
70
|
+
// Before control
|
|
71
|
+
let before = true;
|
|
72
|
+
// Total of items in the container
|
|
73
|
+
let numOfItems = items.length;
|
|
74
|
+
// Position from top
|
|
75
|
+
let height = 0;
|
|
76
|
+
// Size of the adjustment
|
|
77
|
+
let size = 0;
|
|
78
|
+
// Go through the items
|
|
79
|
+
for (let j = 0; j < numOfItems; j++) {
|
|
80
|
+
let h = items[j].height || defaultRowHeight;
|
|
81
|
+
// Height
|
|
82
|
+
height += h;
|
|
83
|
+
// Start tracking all items as before
|
|
84
|
+
if (items[j] === self.result[0]) {
|
|
85
|
+
before = false;
|
|
86
|
+
}
|
|
87
|
+
// Adjustment
|
|
88
|
+
if (before) {
|
|
89
|
+
size += h;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Update height
|
|
93
|
+
scroll.style.height = height + 'px';
|
|
94
|
+
// Adjust scroll position
|
|
95
|
+
return size;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const getVisibleRows = function(reset) {
|
|
101
|
+
let items = self.rows;
|
|
102
|
+
if (items) {
|
|
103
|
+
let adjust;
|
|
104
|
+
// Total of items in the container
|
|
105
|
+
let numOfItems = items.length;
|
|
106
|
+
// Get the position from top
|
|
107
|
+
let y = el.scrollTop;
|
|
108
|
+
// Get the height
|
|
109
|
+
let h = y + (el.offsetHeight || self.height);
|
|
110
|
+
// Go through the items
|
|
111
|
+
let rows = [];
|
|
112
|
+
// Height
|
|
113
|
+
let height = 0;
|
|
114
|
+
// Go through all items
|
|
115
|
+
for (let j = 0; j < numOfItems; j++) {
|
|
116
|
+
if (items[j].visible !== false) {
|
|
117
|
+
// Height
|
|
118
|
+
let rowHeight = items[j].height || defaultRowHeight;
|
|
119
|
+
// Return on partial width
|
|
120
|
+
if (height + rowHeight > y && height < h) {
|
|
121
|
+
rows.push(items[j]);
|
|
122
|
+
}
|
|
123
|
+
height += rowHeight;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Update visible rows
|
|
128
|
+
if (reset || ! compareArray(rows, self.result)) {
|
|
129
|
+
// Render the items
|
|
130
|
+
self.result = rows;
|
|
131
|
+
// Adjust scroll height
|
|
132
|
+
let adjustScroll = reset;
|
|
133
|
+
// Adjust scrolling
|
|
134
|
+
for (let i = 0; i < rows.length; i++) {
|
|
135
|
+
// Item
|
|
136
|
+
let item = rows[i];
|
|
137
|
+
// Item height
|
|
138
|
+
let h = item.el.offsetHeight;
|
|
139
|
+
// Update row height
|
|
140
|
+
if (! item.height || h !== item.height) {
|
|
141
|
+
// Keep item height
|
|
142
|
+
item.height = h;
|
|
143
|
+
// Adjust total height
|
|
144
|
+
adjustScroll = true;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Update scroll if the height of one element has been changed
|
|
149
|
+
if (adjustScroll) {
|
|
150
|
+
// Adjust the scroll height
|
|
151
|
+
adjust = updateScroll();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Adjust position of the first element
|
|
156
|
+
let position = getRowPosition(self.result[0]);
|
|
157
|
+
let diff = position - el.scrollTop;
|
|
158
|
+
if (diff > 0) {
|
|
159
|
+
diff = 0;
|
|
160
|
+
}
|
|
161
|
+
self.container.style.top = diff + 'px';
|
|
162
|
+
|
|
163
|
+
return adjust;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Move the position to the top and re-render based on the scroll
|
|
169
|
+
* @param reset
|
|
170
|
+
*/
|
|
171
|
+
const render = function (reset) {
|
|
172
|
+
// Move scroll to the top
|
|
173
|
+
el.scrollTop = 0;
|
|
174
|
+
// Append first batch
|
|
175
|
+
getVisibleRows(reset);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Will adjust the items based on the scroll position offset
|
|
180
|
+
*/
|
|
181
|
+
self.adjustPosition = function(item) {
|
|
182
|
+
if (item.el) {
|
|
183
|
+
let h = item.el.offsetHeight;
|
|
184
|
+
let calc = item.el.offsetTop + h;
|
|
185
|
+
if (calc > el.offsetHeight) {
|
|
186
|
+
let size = calc - el.offsetHeight;
|
|
187
|
+
if (size < h) {
|
|
188
|
+
size = h;
|
|
189
|
+
}
|
|
190
|
+
el.scrollTop -= -1 * size;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Controls
|
|
196
|
+
const scrollControls = function() {
|
|
197
|
+
getVisibleRows(false);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Element for scrolling
|
|
201
|
+
let el = self.container.parentNode;
|
|
202
|
+
el.classList.add('lm-lazy');
|
|
203
|
+
// Div to represent the height of the content
|
|
204
|
+
const scroll = document.createElement('div');
|
|
205
|
+
scroll.classList.add('lm-lazy-scroll');
|
|
206
|
+
// Force the height and add scrolling
|
|
207
|
+
el.appendChild(scroll);
|
|
208
|
+
el.addEventListener('scroll', scrollControls);
|
|
209
|
+
el.addEventListener('wheel', scrollControls);
|
|
210
|
+
self.container.classList.add('lm-lazy-items');
|
|
211
|
+
|
|
212
|
+
self.goto = function(item) {
|
|
213
|
+
el.scrollTop = getRowPosition(item);
|
|
214
|
+
let adjust = getVisibleRows(false);
|
|
215
|
+
if (adjust) {
|
|
216
|
+
el.scrollTop += adjust;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return (prop) => {
|
|
221
|
+
if (prop === 'rows') {
|
|
222
|
+
render(true);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const Dropdown = function () {
|
|
228
|
+
let self = this;
|
|
229
|
+
let value = [];
|
|
230
|
+
let cursor = null;
|
|
231
|
+
|
|
232
|
+
if (! self.width) {
|
|
233
|
+
self.width = 260;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Lazy loading global instance
|
|
237
|
+
let lazyloading = null;
|
|
238
|
+
|
|
239
|
+
const setData = function() {
|
|
240
|
+
// Re-order to make sure groups are in sequence
|
|
241
|
+
self.data.sort((a, b) => {
|
|
242
|
+
// Compare groups
|
|
243
|
+
if (a.group && b.group) {
|
|
244
|
+
return a.group.localeCompare(b.group);
|
|
245
|
+
}
|
|
246
|
+
return 0;
|
|
247
|
+
});
|
|
248
|
+
let group = '';
|
|
249
|
+
// Define group headers
|
|
250
|
+
self.data.map((v) => {
|
|
251
|
+
// Compare groups
|
|
252
|
+
if (v.group && v.group !== group) {
|
|
253
|
+
v.header = true;
|
|
254
|
+
group = v.group;
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
// Estimate width
|
|
258
|
+
let width = self.width;
|
|
259
|
+
// Width && values
|
|
260
|
+
self.data.map(function (s) {
|
|
261
|
+
// Estimated width of the element
|
|
262
|
+
width = Math.max(width, s.text.length * 8);
|
|
263
|
+
});
|
|
264
|
+
// Adjust the width
|
|
265
|
+
let w = self.input.offsetWidth;
|
|
266
|
+
if (width < w) {
|
|
267
|
+
width = w;
|
|
268
|
+
}
|
|
269
|
+
// Estimated with based on the text
|
|
270
|
+
if (self.width < width) {
|
|
271
|
+
self.width = width;
|
|
272
|
+
}
|
|
273
|
+
self.el.style.width = self.width + 'px';
|
|
274
|
+
// Height
|
|
275
|
+
self.height = 400;
|
|
276
|
+
// Animation for mobile
|
|
277
|
+
if (document.documentElement.clientWidth < 800) {
|
|
278
|
+
self.animation = true;
|
|
279
|
+
}
|
|
280
|
+
// Data to be listed
|
|
281
|
+
self.rows = self.data;
|
|
282
|
+
// Set the initial value
|
|
283
|
+
if (typeof(self.value) !== 'undefined') {
|
|
284
|
+
setValue(self.value);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const setCursor = function(index) {
|
|
289
|
+
let item = self.rows[index];
|
|
290
|
+
if (typeof(item) !== 'undefined') {
|
|
291
|
+
// Set cursor number
|
|
292
|
+
cursor = index;
|
|
293
|
+
// Set visual indication
|
|
294
|
+
item.cursor = true;
|
|
295
|
+
// Go to the item on the scroll in case the item is not on the viewport
|
|
296
|
+
if (! item.el || ! item.el.parentNode) {
|
|
297
|
+
// Goto method
|
|
298
|
+
self.goto(item);
|
|
299
|
+
}
|
|
300
|
+
// Adjust cursor position
|
|
301
|
+
setTimeout(function() {
|
|
302
|
+
self.adjustPosition(item);
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
const removeCursor = function(reset) {
|
|
308
|
+
if (cursor !== null) {
|
|
309
|
+
if (typeof(self.rows[cursor]) !== 'undefined') {
|
|
310
|
+
self.rows[cursor].cursor = false;
|
|
311
|
+
}
|
|
312
|
+
if (reset) {
|
|
313
|
+
// Cursor is null
|
|
314
|
+
cursor = null;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const moveCursor = function(direction, jump) {
|
|
320
|
+
// Remove cursor
|
|
321
|
+
removeCursor();
|
|
322
|
+
// Last item
|
|
323
|
+
let last = self.rows.length - 1;
|
|
324
|
+
if (jump) {
|
|
325
|
+
if (direction < 0) {
|
|
326
|
+
cursor = 0;
|
|
327
|
+
} else {
|
|
328
|
+
cursor = last;
|
|
329
|
+
}
|
|
330
|
+
} else {
|
|
331
|
+
// Position
|
|
332
|
+
if (cursor === null) {
|
|
333
|
+
cursor = 0;
|
|
334
|
+
} else {
|
|
335
|
+
// Move previous
|
|
336
|
+
cursor = cursor + direction;
|
|
337
|
+
}
|
|
338
|
+
// Reach the boundaries
|
|
339
|
+
if (direction < 0) {
|
|
340
|
+
// Back to the last one
|
|
341
|
+
if (cursor < 0) {
|
|
342
|
+
cursor = last;
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
// Back to the first one
|
|
346
|
+
if (cursor > last) {
|
|
347
|
+
cursor = 0;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
// Add cursor
|
|
352
|
+
setCursor(cursor);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const updateLabel = function() {
|
|
356
|
+
if (value && value.length) {
|
|
357
|
+
self.input.textContent = value.filter(v => v.selected).map(i => i.text).join('; ');
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const setValue = function(v) {
|
|
362
|
+
// Values
|
|
363
|
+
let newValue;
|
|
364
|
+
if (! Array.isArray(v)) {
|
|
365
|
+
if (typeof(v) === 'string') {
|
|
366
|
+
newValue = v.split(';');
|
|
367
|
+
} else {
|
|
368
|
+
newValue = [v];
|
|
369
|
+
}
|
|
370
|
+
} else {
|
|
371
|
+
newValue = v;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// Width && values
|
|
375
|
+
value = [];
|
|
376
|
+
|
|
377
|
+
self.data.map(function(s) {
|
|
378
|
+
// Select values
|
|
379
|
+
if (newValue.indexOf(s.value) !== -1) {
|
|
380
|
+
s.selected = true;
|
|
381
|
+
value.push(s);
|
|
382
|
+
} else {
|
|
383
|
+
s.selected = false;
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
// Update label
|
|
388
|
+
updateLabel();
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const getValue = function() {
|
|
392
|
+
if (value && value.length) {
|
|
393
|
+
return value.filter(v => v.selected).map(i => i.value);
|
|
394
|
+
}
|
|
395
|
+
return [];
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
const onclose = function() {
|
|
399
|
+
// Cursor
|
|
400
|
+
removeCursor();
|
|
401
|
+
// Reset search
|
|
402
|
+
if (self.autocomplete && self.input.textContent) {
|
|
403
|
+
// Go to begin of the data
|
|
404
|
+
self.rows = self.data;
|
|
405
|
+
// Remove editable attribute
|
|
406
|
+
self.input.removeAttribute('contenteditable');
|
|
407
|
+
// Clear input
|
|
408
|
+
self.input.textContent = '';
|
|
409
|
+
}
|
|
410
|
+
// Update label
|
|
411
|
+
updateLabel();
|
|
412
|
+
// Update value
|
|
413
|
+
self.value = getValue();
|
|
414
|
+
// Identify the new state of the dropdown
|
|
415
|
+
self.state = false;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
const onopen = function() {
|
|
419
|
+
self.state = true;
|
|
420
|
+
// Value
|
|
421
|
+
let v = value[value.length-1];
|
|
422
|
+
// Cursor
|
|
423
|
+
removeCursor();
|
|
424
|
+
// Move to the correct position
|
|
425
|
+
if (v) {
|
|
426
|
+
// Go to the last item in the array of values
|
|
427
|
+
self.goto(v);
|
|
428
|
+
// Mark the position of the cursor to the same element
|
|
429
|
+
setCursor(self.rows.indexOf(v));
|
|
430
|
+
} else {
|
|
431
|
+
// Go to begin of the data
|
|
432
|
+
self.rows = self.data;
|
|
433
|
+
}
|
|
434
|
+
// Prepare search field
|
|
435
|
+
if (self.autocomplete) {
|
|
436
|
+
// Clear input
|
|
437
|
+
self.input.textContent = '';
|
|
438
|
+
// Editable
|
|
439
|
+
self.input.setAttribute('contenteditable', true);
|
|
440
|
+
// Focus on the item
|
|
441
|
+
self.input.focus();
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
self.search = function() {
|
|
446
|
+
if (self.state && self.autocomplete) {
|
|
447
|
+
// Filter options
|
|
448
|
+
let data;
|
|
449
|
+
if (! self.input.textContent) {
|
|
450
|
+
data = self.data;
|
|
451
|
+
} else {
|
|
452
|
+
data = self.data.filter(item => {
|
|
453
|
+
return item.selected === true ||
|
|
454
|
+
(item.text.toLowerCase().includes(self.input.textContent.toLowerCase())) ||
|
|
455
|
+
(item.group && item.group.toLowerCase().includes(self.input.textContent.toLowerCase()));
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
// Cursor
|
|
459
|
+
removeCursor(true);
|
|
460
|
+
// Update the data from the dropdown
|
|
461
|
+
self.rows = data;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
self.open = function () {
|
|
466
|
+
if (self.modal && self.modal.closed) {
|
|
467
|
+
self.modal.closed = false;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
self.close = function () {
|
|
472
|
+
// Close the modal
|
|
473
|
+
if (self.modal) {
|
|
474
|
+
self.modal.closed = true;
|
|
475
|
+
// Remove cursor
|
|
476
|
+
removeCursor(true);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
self.toggle = function() {
|
|
481
|
+
if (self.modal) {
|
|
482
|
+
if (self.modal.closed) {
|
|
483
|
+
self.open();
|
|
484
|
+
} else {
|
|
485
|
+
self.close();
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
self.select = function(e, s) {
|
|
491
|
+
if (s) {
|
|
492
|
+
if (self.multiple === true) {
|
|
493
|
+
let position = value.indexOf(s);
|
|
494
|
+
if (position === -1) {
|
|
495
|
+
value.push(s);
|
|
496
|
+
s.selected = true;
|
|
497
|
+
} else {
|
|
498
|
+
value.splice(position, 1);
|
|
499
|
+
s.selected = false;
|
|
500
|
+
}
|
|
501
|
+
} else {
|
|
502
|
+
if (value[0] === s) {
|
|
503
|
+
s.selected = !s.selected;
|
|
504
|
+
} else {
|
|
505
|
+
if (value[0]) {
|
|
506
|
+
value[0].selected = false;
|
|
507
|
+
}
|
|
508
|
+
s.selected = true;
|
|
509
|
+
}
|
|
510
|
+
if (s.selected) {
|
|
511
|
+
value = [s];
|
|
512
|
+
} else {
|
|
513
|
+
value = [];
|
|
514
|
+
}
|
|
515
|
+
// Close the modal
|
|
516
|
+
self.close();
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
self.getGroup = function() {
|
|
522
|
+
if (this.group && this.header) {
|
|
523
|
+
return this.group;
|
|
524
|
+
} else {
|
|
525
|
+
return '';
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
self.onload = function () {
|
|
530
|
+
if (self.type !== "inline") {
|
|
531
|
+
// Create modal instance
|
|
532
|
+
self.modal = {
|
|
533
|
+
closed: true,
|
|
534
|
+
focus: false,
|
|
535
|
+
width: self.width,
|
|
536
|
+
'auto-close': false,
|
|
537
|
+
onopen: onopen,
|
|
538
|
+
onclose: onclose,
|
|
539
|
+
};
|
|
540
|
+
// Generate modal
|
|
541
|
+
Modal(self.el.children[1], self.modal);
|
|
542
|
+
} else {
|
|
543
|
+
// For inline dropdown
|
|
544
|
+
self.el.setAttribute('tabindex', 0);
|
|
545
|
+
// Remove search
|
|
546
|
+
self.input.remove();
|
|
547
|
+
}
|
|
548
|
+
// Loading controls
|
|
549
|
+
lazyloading = lazyLoading(self);
|
|
550
|
+
// Process the data
|
|
551
|
+
setData();
|
|
552
|
+
// Focus out of the component
|
|
553
|
+
self.el.addEventListener('focusout', function(e) {
|
|
554
|
+
if (self.modal) {
|
|
555
|
+
if (! (e.relatedTarget && self.el.contains(e.relatedTarget)) && !self.el.contains(e.relatedTarget)) {
|
|
556
|
+
if (! self.modal.closed) {
|
|
557
|
+
self.close();
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
})
|
|
562
|
+
// Key events
|
|
563
|
+
self.el.addEventListener('keydown', function(e) {
|
|
564
|
+
let prevent = false;
|
|
565
|
+
if (e.key === 'ArrowUp') {
|
|
566
|
+
moveCursor(-1);
|
|
567
|
+
prevent = true;
|
|
568
|
+
} else if (e.key === 'ArrowDown') {
|
|
569
|
+
moveCursor(1);
|
|
570
|
+
prevent = true;
|
|
571
|
+
} else if (e.key === 'Home') {
|
|
572
|
+
moveCursor(-1, true);
|
|
573
|
+
} else if (e.key === 'End') {
|
|
574
|
+
moveCursor(1, true);
|
|
575
|
+
} else if (e.key === 'Enter') {
|
|
576
|
+
self.select(e, self.rows[cursor]);
|
|
577
|
+
prevent = true;
|
|
578
|
+
} else {
|
|
579
|
+
if (e.keyCode === 32 && ! self.autocomplete) {
|
|
580
|
+
self.select(e, self.rows[cursor]);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
if (prevent) {
|
|
585
|
+
e.preventDefault();
|
|
586
|
+
e.stopImmediatePropagation();
|
|
587
|
+
}
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
self.onchange = function(prop) {
|
|
592
|
+
if (prop === 'value') {
|
|
593
|
+
setValue(self.value);
|
|
594
|
+
} else if (prop === 'data') {
|
|
595
|
+
setData();
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
if (typeof(lazyloading) === 'function') {
|
|
599
|
+
lazyloading(prop);
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
return `<div class="lm-dropdown" data-type="{{self.type}}" data-state="{{self.state}}">
|
|
604
|
+
<div class="lm-dropdown-header">
|
|
605
|
+
<div class="lm-dropdown-input" oninput="self.search" onfocus="self.open" placeholder="{{self.placeholder}}" :ref="self.input" tabindex="0"></div>
|
|
606
|
+
<button onclick="self.close" class="lm-dropdown-done">Done</button>
|
|
607
|
+
</div>
|
|
608
|
+
<div class="lm-dropdown-content">
|
|
609
|
+
<div>
|
|
610
|
+
<div :loop="self.result" :ref="self.container" :rows="self.rows">
|
|
611
|
+
<div class="lm-dropdown-item" onclick="self.parent.select" data-cursor="{{self.cursor}}" data-selected="{{self.selected}}" data-group="{{self.parent.getGroup}}">
|
|
612
|
+
<div><img :src="self.image" /><span>{{self.text}}</span></div>
|
|
613
|
+
</div>
|
|
614
|
+
</div>
|
|
615
|
+
</div>
|
|
616
|
+
</div>
|
|
617
|
+
</div>`;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
lemonade.setComponents({ Dropdown: Dropdown });
|
|
621
|
+
|
|
622
|
+
return function (root, options) {
|
|
623
|
+
if (typeof (root) === 'object') {
|
|
624
|
+
lemonade.render(Dropdown, root, options)
|
|
625
|
+
return options;
|
|
626
|
+
} else {
|
|
627
|
+
return Dropdown.call(this, root)
|
|
628
|
+
}
|
|
629
|
+
}
|
|
333
630
|
})));
|