@lemonadejs/dropdown 3.1.3 → 3.1.6

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.js CHANGED
@@ -20,17 +20,22 @@ if (!Modal && typeof (require) === 'function') {
20
20
  // Default row height
21
21
  let defaultRowHeight = 24;
22
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) {
23
+ /**
24
+ * Compare two arrays to see if contains exact the same elements
25
+ * @param {number|number[]} a1
26
+ * @param {number|number[]} a2
27
+ */
28
+ const compareValues = function (a1, a2) {
29
+ if (! a1 || ! a2) {
30
+ return false;
31
+ }
32
+ if (! Array.isArray(a1) || ! Array.isArray(a2)) {
33
+ if (a1 === a2) {
34
+ return true;
35
+ } else {
31
36
  return false;
32
37
  }
33
-
38
+ } else {
34
39
  let i = a1.length;
35
40
  if (i !== a2.length) {
36
41
  return false;
@@ -40,9 +45,11 @@ if (!Modal && typeof (require) === 'function') {
40
45
  return false;
41
46
  }
42
47
  }
43
- return true;
44
48
  }
49
+ return true;
50
+ }
45
51
 
52
+ const lazyLoading = function(self) {
46
53
  /**
47
54
  * Get the position from top of a row by its index
48
55
  * @param item
@@ -132,7 +139,7 @@ if (!Modal && typeof (require) === 'function') {
132
139
  }
133
140
 
134
141
  // Update visible rows
135
- if (reset || ! compareArray(rows, self.result)) {
142
+ if (reset || ! compareValues(rows, self.result)) {
136
143
  // Render the items
137
144
  self.result = rows;
138
145
  // Adjust scroll height
@@ -237,73 +244,24 @@ if (!Modal && typeof (require) === 'function') {
237
244
 
238
245
  const Dropdown = function () {
239
246
  let self = this;
247
+ // Internal value controllers
240
248
  let value = [];
249
+ // Cursor
241
250
  let cursor = null;
242
-
251
+ // Control events
252
+ let ignoreEvents = false;
253
+ // Default widht
243
254
  if (! self.width) {
244
255
  self.width = 260;
245
256
  }
246
-
247
257
  // Lazy loading global instance
248
258
  let lazyloading = null;
249
-
259
+ // Custom events defined by the user
250
260
  let onload = self.load;
251
261
  let onchange = self.onchange;
252
262
 
253
- const setData = function() {
254
- // Estimate width
255
- let width = self.width;
256
- // Re-order to make sure groups are in sequence
257
- if (self.data && self.data.length) {
258
- self.data.sort((a, b) => {
259
- // Compare groups
260
- if (a.group && b.group) {
261
- return a.group.localeCompare(b.group);
262
- }
263
- return 0;
264
- });
265
- let group = '';
266
- // Define group headers
267
- self.data.map((v) => {
268
- // Compare groups
269
- if (v && v.group && v.group !== group) {
270
- v.header = true;
271
- group = v.group;
272
- }
273
- });
274
- // Width && values
275
- self.data.map(function (s) {
276
- // Estimated width of the element
277
- if (s.text) {
278
- width = Math.max(width, s.text.length * 8);
279
- }
280
- });
281
- }
282
- // Adjust the width
283
- let w = self.input.offsetWidth;
284
- if (width < w) {
285
- width = w;
286
- }
287
- // Estimated with based on the text
288
- if (self.width < width) {
289
- self.width = width;
290
- }
291
- self.el.style.width = self.width + 'px';
292
- // Height
293
- self.height = 400;
294
- // Animation for mobile
295
- if (document.documentElement.clientWidth < 800) {
296
- self.animation = true;
297
- }
298
- // Data to be listed
299
- self.rows = self.data;
300
- // Set the initial value
301
- if (typeof(self.value) !== 'undefined') {
302
- setValue(self.value);
303
- }
304
- }
305
-
306
- const setCursor = function(index) {
263
+ // Cursor controllers
264
+ const setCursor = function(index, force) {
307
265
  let item = self.rows[index];
308
266
 
309
267
  if (typeof(item) !== 'undefined') {
@@ -312,7 +270,7 @@ if (!Modal && typeof (require) === 'function') {
312
270
  // Set visual indication
313
271
  item.cursor = true;
314
272
  // Go to the item on the scroll in case the item is not on the viewport
315
- if (! (item.el && item.el.parentNode)) {
273
+ if (! (item.el && item.el.parentNode) || force === true) {
316
274
  // Goto method
317
275
  self.goto(item);
318
276
  }
@@ -371,6 +329,55 @@ if (!Modal && typeof (require) === 'function') {
371
329
  setCursor(cursor);
372
330
  }
373
331
 
332
+ const setData = function() {
333
+ // Estimate width
334
+ let width = self.width;
335
+ // Re-order to make sure groups are in sequence
336
+ if (self.data && self.data.length) {
337
+ self.data.sort((a, b) => {
338
+ // Compare groups
339
+ if (a.group && b.group) {
340
+ return a.group.localeCompare(b.group);
341
+ }
342
+ return 0;
343
+ });
344
+ let group = '';
345
+ // Define group headers
346
+ self.data.map((v) => {
347
+ // Compare groups
348
+ if (v && v.group && v.group !== group) {
349
+ v.header = true;
350
+ group = v.group;
351
+ }
352
+ });
353
+ // Width && values
354
+ self.data.map(function (s) {
355
+ // Estimated width of the element
356
+ if (s.text) {
357
+ width = Math.max(width, s.text.length * 8);
358
+ }
359
+ });
360
+ }
361
+ // Adjust the width
362
+ let w = self.input.offsetWidth;
363
+ if (width < w) {
364
+ width = w;
365
+ }
366
+ // Estimated with based on the text
367
+ if (self.width < width) {
368
+ self.width = width;
369
+ }
370
+ self.el.style.width = self.width + 'px';
371
+ // Height
372
+ self.height = 400;
373
+ // Animation for mobile
374
+ if (document.documentElement.clientWidth < 800) {
375
+ self.animation = true;
376
+ }
377
+ // Data to be listed
378
+ self.rows = self.data;
379
+ }
380
+
374
381
  const updateLabel = function() {
375
382
  if (value && value.length) {
376
383
  self.input.textContent = value.filter(v => v.selected).map(i => i.text).join('; ');
@@ -396,7 +403,7 @@ if (!Modal && typeof (require) === 'function') {
396
403
  value = [];
397
404
 
398
405
  if (Array.isArray(self.data)) {
399
- self.data.map(function (s) {
406
+ self.data.map(function(s) {
400
407
  // Select values
401
408
  if (newValue.indexOf(s.value) !== -1) {
402
409
  s.selected = true;
@@ -412,7 +419,7 @@ if (!Modal && typeof (require) === 'function') {
412
419
 
413
420
  // Component onchange
414
421
  if (typeof(onchange) === 'function') {
415
- onchange(self, self.value);
422
+ onchange(self, value);
416
423
  }
417
424
  }
418
425
 
@@ -443,10 +450,18 @@ if (!Modal && typeof (require) === 'function') {
443
450
  // Clear input
444
451
  self.input.textContent = '';
445
452
  }
446
- // Update label
447
- updateLabel();
448
- // Update value
449
- self.value = getValue();
453
+
454
+ // Current value
455
+ let newValue = getValue();
456
+
457
+ // If that is different from the component value
458
+ if (! compareValues(newValue, self.value)) {
459
+ self.value = newValue;
460
+ } else {
461
+ // Update label
462
+ updateLabel();
463
+ }
464
+
450
465
  // Identify the new state of the dropdown
451
466
  self.state = false;
452
467
 
@@ -459,13 +474,14 @@ if (!Modal && typeof (require) === 'function') {
459
474
  self.state = true;
460
475
  // Value
461
476
  let v = value[value.length-1];
477
+ // Make sure goes back to the top of the scroll
478
+ if (self.container.parentNode.scrollTop > 0) {
479
+ self.container.parentNode.scrollTop = 0;
480
+ }
462
481
  // Move to the correct position
463
482
  if (v) {
464
483
  // Mark the position of the cursor to the same element
465
- setCursor(self.rows.indexOf(v));
466
- } else {
467
- // Go to begin of the data
468
- self.rows = self.data;
484
+ setCursor(self.rows.indexOf(v), true);
469
485
  }
470
486
  // Prepare search field
471
487
  if (self.autocomplete) {
@@ -482,6 +498,46 @@ if (!Modal && typeof (require) === 'function') {
482
498
  }
483
499
  }
484
500
 
501
+
502
+ self.add = async function(e) {
503
+ if (! self.input.textContent) {
504
+ return false;
505
+ }
506
+
507
+ e.preventDefault();
508
+
509
+ // New item
510
+ let s = {
511
+ text: self.input.textContent,
512
+ value: self.input.textContent,
513
+ }
514
+
515
+ // Event
516
+ if (typeof(self.onbeforeinsert) === 'function') {
517
+ let elClass = self.el.classList;
518
+ elClass.add('lm-dropdown-loading');
519
+ let ret = await self.onbeforeinsert(self, s);
520
+ elClass.remove('lm-dropdown-loading');
521
+ if (ret === false) {
522
+ return;
523
+ } else if (ret) {
524
+ s = ret;
525
+ }
526
+ }
527
+
528
+ // Process the data
529
+ self.data.push(s);
530
+ // Select the new item
531
+ self.select(e, s);
532
+ // Close dropdown
533
+ self.close();
534
+
535
+ // Event
536
+ if (typeof(self.oninsert) === 'function') {
537
+ self.oninsert(self, s);
538
+ }
539
+ }
540
+
485
541
  self.search = function(e) {
486
542
  if (self.state && self.autocomplete) {
487
543
  // Filter options
@@ -516,7 +572,7 @@ if (!Modal && typeof (require) === 'function') {
516
572
  }
517
573
  }
518
574
 
519
- self.toggle = function(e) {
575
+ self.toggle = function() {
520
576
  if (self.modal) {
521
577
  if (self.modal.closed) {
522
578
  self.open();
@@ -527,16 +583,20 @@ if (!Modal && typeof (require) === 'function') {
527
583
  }
528
584
 
529
585
  self.click = function(e) {
530
- let x;
531
- if (e.changedTouches && e.changedTouches[0]) {
532
- x = e.changedTouches[0].clientX;
586
+ if (self.autocomplete) {
587
+ let x;
588
+ if (e.changedTouches && e.changedTouches[0]) {
589
+ x = e.changedTouches[0].clientX;
590
+ } else {
591
+ x = e.clientX;
592
+ }
593
+ if (e.target.offsetWidth - (x - e.target.offsetLeft) < 20) {
594
+ self.toggle();
595
+ } else {
596
+ self.open();
597
+ }
533
598
  } else {
534
- x = e.clientX;
535
- }
536
- if (e.target.offsetWidth - (x - e.target.offsetLeft) < 20) {
537
599
  self.toggle();
538
- } else {
539
- self.open();
540
600
  }
541
601
  }
542
602
 
@@ -604,6 +664,10 @@ if (!Modal && typeof (require) === 'function') {
604
664
  lazyloading = lazyLoading(self);
605
665
  // Process the data
606
666
  setData();
667
+ // Se value
668
+ if (self.value) {
669
+ setValue(self.value);
670
+ }
607
671
  // Focus out of the component
608
672
  self.el.addEventListener('focusout', function(e) {
609
673
  if (self.modal) {
@@ -647,7 +711,7 @@ if (!Modal && typeof (require) === 'function') {
647
711
  }
648
712
  }
649
713
  });
650
-
714
+ // Custom event by the developer
651
715
  if (typeof(onload) === 'function') {
652
716
  onload(self);
653
717
  }
@@ -658,6 +722,7 @@ if (!Modal && typeof (require) === 'function') {
658
722
  setValue(self.value);
659
723
  } else if (prop === 'data') {
660
724
  setData();
725
+ self.value = null;
661
726
  }
662
727
 
663
728
  if (typeof(lazyloading) === 'function') {
@@ -681,46 +746,7 @@ if (!Modal && typeof (require) === 'function') {
681
746
  e.preventDefault();
682
747
  }
683
748
 
684
- self.add = async function(e) {
685
- if (! self.input.textContent) {
686
- return false;
687
- }
688
-
689
- e.preventDefault();
690
-
691
- // New item
692
- let s = {
693
- text: self.input.textContent,
694
- value: self.input.textContent,
695
- }
696
-
697
- // Event
698
- if (typeof(self.onbeforeinsert) === 'function') {
699
- let elClass = self.el.classList;
700
- elClass.add('lm-dropdown-loading');
701
- let ret = await self.onbeforeinsert(self, s);
702
- elClass.remove('lm-dropdown-loading');
703
- if (ret === false) {
704
- return;
705
- } else if (ret) {
706
- s = ret;
707
- }
708
- }
709
-
710
- // Process the data
711
- self.data.push(s);
712
- // Select the new item
713
- self.select(e, s);
714
- // Close dropdown
715
- self.close();
716
-
717
- // Event
718
- if (typeof(self.oninsert) === 'function') {
719
- self.oninsert(self, s);
720
- }
721
- }
722
-
723
- return `<div class="lm-dropdown" data-insert="{{self.insert}}" data-type="{{self.type}}" data-state="{{self.state}}" :value="self.value">
749
+ return `<div class="lm-dropdown" data-insert="{{self.insert}}" data-type="{{self.type}}" data-state="{{self.state}}" :value="self.value" :data="self.data">
724
750
  <div class="lm-dropdown-header">
725
751
  <div class="lm-dropdown-input" onpaste="self.onpaste" oninput="self.search" onfocus="self.open" onmousedown="self.click" placeholder="{{self.placeholder}}" :ref="self.input" tabindex="0"></div>
726
752
  <div class="lm-dropdown-add" onmousedown="self.add"></div>
package/dist/style.css CHANGED
@@ -63,7 +63,7 @@
63
63
 
64
64
  .lm-dropdown-add {
65
65
  position: absolute;
66
- padding: 10px;
66
+ padding: 12px;
67
67
  right: 20px;
68
68
  display: none;
69
69
  }
package/package.json CHANGED
@@ -14,10 +14,10 @@
14
14
  "javascript plugins"
15
15
  ],
16
16
  "dependencies": {
17
- "lemonadejs": "^4.0.7",
17
+ "lemonadejs": "^4.1.0",
18
18
  "@lemonadejs/modal": "^2.7.1"
19
19
  },
20
20
  "main": "dist/index.js",
21
21
  "types": "dist/index.d.ts",
22
- "version": "3.1.3"
22
+ "version": "3.1.6"
23
23
  }