@lemonadejs/dropdown 3.5.0 → 3.6.1

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 CHANGED
@@ -45,6 +45,8 @@ declare namespace Dropdown {
45
45
  insert?: boolean;
46
46
  /** Specifies the URL for fetching the data. */
47
47
  url?: string;
48
+ /** Allow empty. Default: true */
49
+ allowempty?: boolean;
48
50
  /** Event handler for value changes */
49
51
  onchange?: (obj: object, newValue: string|number) => void;
50
52
  /** Event handler for when the dropdown is ready */
package/dist/index.js CHANGED
@@ -242,16 +242,79 @@ if (!Modal && typeof (require) === 'function') {
242
242
  }
243
243
  }
244
244
 
245
- const Dropdown = function (html) {
245
+ const getAttributeName = function(prop) {
246
+ if (prop.substring(0,1) === ':') {
247
+ prop = prop.substring(1);
248
+ } else if (prop.substring(0,3) === 'lm-') {
249
+ prop = prop.substring(3);
250
+ }
251
+ return prop.toLowerCase();
252
+ }
253
+
254
+ const extractFromHtml = function(element) {
255
+ let data = [];
256
+ // Content
257
+ for (let i = 0; i < element.children.length; i++) {
258
+ let e = element.children[i];
259
+ let item = {
260
+ text: e.textContent || e.getAttribute('title'),
261
+ value: e.getAttribute('value'),
262
+ }
263
+ if (item.value == null) {
264
+ item.value = item.text;
265
+ }
266
+ data.push(item);
267
+ }
268
+
269
+ return data;
270
+ }
271
+
272
+ const extract = function(children) {
273
+ let data = [];
274
+
275
+ if (this.tagName) {
276
+ data = extractFromHtml(this);
277
+ // Remove all elements
278
+ this.textContent = '';
279
+ } else {
280
+ // Get data
281
+ if (typeof(children) === 'string') {
282
+ // Version 4
283
+ let d = document.createElement('div');
284
+ d.innerHTML = children;
285
+ data = extractFromHtml(d);
286
+ } else if (children && children.length) {
287
+ // Version 5
288
+ children.forEach((v) => {
289
+ let item = {}
290
+ v.props.forEach((prop) => {
291
+ item[getAttributeName(prop.name)] = prop.value;
292
+ });
293
+ if (! item.text) {
294
+ item.text = v.children[0]?.props[0]?.value || '';
295
+ }
296
+ data.push(item);
297
+ });
298
+ // Block children
299
+ children.length = 0;
300
+ }
301
+ }
302
+
303
+ return data;
304
+ }
305
+
306
+ const Dropdown = function (children) {
246
307
  let self = this;
308
+ // Data
309
+ let data = [];
247
310
  // Internal value controllers
248
311
  let value = [];
249
312
  // Cursor
250
313
  let cursor = null;
251
314
  // Control events
252
315
  let ignoreEvents = false;
253
- // Default widht
254
- if (!self.width) {
316
+ // Default width
317
+ if (! self.width) {
255
318
  self.width = 260;
256
319
  }
257
320
  // Lazy loading global instance
@@ -261,22 +324,12 @@ if (!Modal && typeof (require) === 'function') {
261
324
  if (! Array.isArray(self.data)) {
262
325
  self.data = [];
263
326
  }
264
- let data = JSON.parse(JSON.stringify(self.data));
265
-
266
- if (html) {
267
- let select = document.createElement('select');
268
- select.innerHTML = html.trim();
269
- for (let i = 0; i < select.children.length; i++) {
270
- let option = select.children[i];
271
- if (option.tagName === 'OPTION') {
272
- let text = option.textContent;
273
- let value = option.getAttribute('value');
274
- if (value === null) {
275
- value = text;
276
- }
277
- self.data.push({ text: text, value: value });
278
- }
279
- }
327
+
328
+ let d = extract.call(this, children);
329
+ if (d) {
330
+ d.forEach((v) => {
331
+ self.data.push(v)
332
+ })
280
333
  }
281
334
 
282
335
  // Custom events defined by the user
@@ -371,7 +424,7 @@ if (!Modal && typeof (require) === 'function') {
371
424
  data.map((v) => {
372
425
  // Compare groups
373
426
  if (v && v.group && v.group !== group) {
374
- v.header = true;
427
+ v.header = v.group;
375
428
  group = v.group;
376
429
  }
377
430
  });
@@ -384,15 +437,19 @@ if (!Modal && typeof (require) === 'function') {
384
437
  });
385
438
  }
386
439
  // Adjust the width
387
- let w = self.input.offsetWidth;
388
- if (width < w) {
389
- width = w;
390
- }
391
- // Estimated with based on the text
392
- if (self.width < width) {
393
- self.width = width;
440
+ if (typeof(self.width) === 'undefined') {
441
+ let w = self.input.offsetWidth;
442
+ if (width < w) {
443
+ width = w;
444
+ }
445
+ // Estimated with based on the text
446
+ if (self.width < width) {
447
+ self.width = width;
448
+ }
449
+ self.el.style.width = self.width + 'px';
394
450
  }
395
- self.el.style.width = self.width + 'px';
451
+ // Min width for the container
452
+ self.container.parentNode.style.minWidth = self.width + 'px';
396
453
  // Height
397
454
  self.height = 400;
398
455
  // Animation for mobile
@@ -523,6 +580,27 @@ if (!Modal && typeof (require) === 'function') {
523
580
  }
524
581
  }
525
582
 
583
+ const loadData = function(result) {
584
+ // Loading controls
585
+ lazyloading = lazyLoading(self);
586
+ // Loading new data from a remote source
587
+ if (result) {
588
+ result.forEach((v) => {
589
+ self.data.push(v);
590
+ });
591
+ }
592
+ // Process the data
593
+ setData();
594
+ // Set value
595
+ if (typeof(self.value) !== 'undefined') {
596
+ setValue(self.value, true);
597
+ }
598
+ // Custom event by the developer
599
+ if (typeof(onload) === 'function') {
600
+ onload(self);
601
+ }
602
+ }
603
+
526
604
  self.add = async function (e) {
527
605
  if (!self.input.textContent) {
528
606
  return false;
@@ -550,11 +628,11 @@ if (!Modal && typeof (require) === 'function') {
550
628
  }
551
629
 
552
630
  // Process the data
553
- data.push(s);
631
+ data.unshift(s);
554
632
  // Select the new item
555
633
  self.select(e, s);
556
634
  // Close dropdown
557
- self.close();
635
+ self.search();
558
636
 
559
637
  // Event
560
638
  if (typeof (self.oninsert) === 'function') {
@@ -562,17 +640,19 @@ if (!Modal && typeof (require) === 'function') {
562
640
  }
563
641
  }
564
642
 
565
- self.search = function (e) {
643
+ self.search = function () {
566
644
  if (self.state && self.autocomplete) {
567
645
  // Filter options
568
646
  let temp;
569
- if (! self.input.textContent) {
570
- temp = self.data;
647
+ let value = self.input.textContent.toLowerCase()
648
+ if (! value) {
649
+ temp = data;
571
650
  } else {
572
- temp = self.data.filter(item => {
651
+ temp = data.filter(item => {
573
652
  return item.selected === true ||
574
- (item.text.toLowerCase().includes(self.input.textContent.toLowerCase())) ||
575
- (item.group && item.group.toLowerCase().includes(self.input.textContent.toLowerCase()));
653
+ (item.text.toLowerCase().includes(value)) ||
654
+ (item.group && item.group.toLowerCase().includes(value)) ||
655
+ (item.keywords.toLowerCase().includes(value));
576
656
  });
577
657
  }
578
658
  // Cursor
@@ -637,7 +717,11 @@ if (!Modal && typeof (require) === 'function') {
637
717
  }
638
718
  } else {
639
719
  if (value[0] === s) {
640
- s.selected = !s.selected;
720
+ if (self.allowempty === false) {
721
+ s.selected = true;
722
+ } else {
723
+ s.selected = !s.selected;
724
+ }
641
725
  } else {
642
726
  if (value[0]) {
643
727
  value[0].selected = false;
@@ -655,14 +739,6 @@ if (!Modal && typeof (require) === 'function') {
655
739
  }
656
740
  }
657
741
 
658
- self.getGroup = function () {
659
- if (this.group && this.header) {
660
- return this.group;
661
- } else {
662
- return '';
663
- }
664
- }
665
-
666
742
  self.onload = function () {
667
743
  if (self.type !== "inline") {
668
744
  // Create modal instance
@@ -685,32 +761,11 @@ if (!Modal && typeof (require) === 'function') {
685
761
  self.input.remove();
686
762
  }
687
763
 
688
- if (self.url && data.length === 0) {
689
- const xhr = new XMLHttpRequest();
690
-
691
- xhr.onreadystatechange = function () {
692
- if (xhr.readyState === 4) {
693
- if (xhr.status === 200) {
694
- data = JSON.parse(xhr.responseText);
695
- } else {
696
- console.error('Failed to fetch data. Status code: ' + xhr.status);
697
- }
698
- }
699
- };
700
-
701
- xhr.open('GET', self.url, true);
702
- xhr.setRequestHeader('Content-Type', 'text/json')
703
- xhr.send();
704
- }
764
+ // Default width
765
+ self.el.style.width = self.width + 'px';
766
+ // Container
767
+ self.container.parentNode.style.minWidth = self.width + 'px';
705
768
 
706
- // Loading controls
707
- lazyloading = lazyLoading(self);
708
- // Process the data
709
- setData();
710
- // Set value
711
- if (typeof (self.value) !== 'undefined') {
712
- setValue(self.value, true);
713
- }
714
769
  // Focus out of the component
715
770
  self.el.addEventListener('focusout', function (e) {
716
771
  if (self.modal) {
@@ -721,6 +776,7 @@ if (!Modal && typeof (require) === 'function') {
721
776
  }
722
777
  }
723
778
  });
779
+
724
780
  // Key events
725
781
  self.el.addEventListener('keydown', function (e) {
726
782
  if (! self.modal.closed) {
@@ -763,9 +819,16 @@ if (!Modal && typeof (require) === 'function') {
763
819
  }
764
820
  }
765
821
  });
766
- // Custom event by the developer
767
- if (typeof (onload) === 'function') {
768
- onload(self);
822
+
823
+ // Load remote data
824
+ if (self.url) {
825
+ fetch(self.url, {
826
+ headers: {
827
+ 'Content-Type': 'text/json',
828
+ }
829
+ }).then(r => r.json()).then(loadData);
830
+ } else {
831
+ loadData();
769
832
  }
770
833
  }
771
834
 
@@ -809,8 +872,8 @@ if (!Modal && typeof (require) === 'function') {
809
872
  <div class="lm-dropdown-content">
810
873
  <div>
811
874
  <div :loop="self.result" :ref="self.container" :rows="self.rows">
812
- <div class="lm-dropdown-item" onclick="self.parent.select" data-cursor="{{self.cursor}}" data-selected="{{self.selected}}" data-group="{{self.parent.getGroup}}">
813
- <div><img :src="self.image" /><span>{{self.text}}</span></div>
875
+ <div class="lm-dropdown-item" onclick="self.parent.select" data-cursor="{{self.cursor}}" data-selected="{{self.selected}}" data-group="{{self.header}}">
876
+ <div><img :src="self.image" /> <div>{{self.text}}</div></div>
814
877
  </div>
815
878
  </div>
816
879
  </div>
package/dist/style.css CHANGED
@@ -55,6 +55,10 @@
55
55
  border-radius: 2px;
56
56
  }
57
57
 
58
+ .lm-dropdown-input > br {
59
+ display: none;
60
+ }
61
+
58
62
  .lm-dropdown-input:focus {
59
63
  outline: 2px solid var(--lm-border-outline, #000);
60
64
  outline-offset: -1px;
@@ -148,7 +152,11 @@
148
152
  margin-right: 6px;
149
153
  }
150
154
 
151
- .lm-dropdown-item > div > img[src=''] {
155
+ .lm-dropdown-item > div > img:not([src]) {
156
+ display: none;
157
+ }
158
+
159
+ .lm-dropdown-item > div > img[src=""] {
152
160
  display: none;
153
161
  }
154
162
 
package/package.json CHANGED
@@ -15,9 +15,9 @@
15
15
  ],
16
16
  "dependencies": {
17
17
  "lemonadejs": "^4.3.3",
18
- "@lemonadejs/modal": "^3.2.0"
18
+ "@lemonadejs/modal": "^3.3.0"
19
19
  },
20
20
  "main": "dist/index.js",
21
21
  "types": "dist/index.d.ts",
22
- "version": "3.5.0"
22
+ "version": "3.6.1"
23
23
  }