@lemonadejs/dropdown 3.5.0 → 3.6.0

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
  });
@@ -523,6 +576,27 @@ if (!Modal && typeof (require) === 'function') {
523
576
  }
524
577
  }
525
578
 
579
+ const loadData = function(result) {
580
+ // Loading controls
581
+ lazyloading = lazyLoading(self);
582
+ // Loading new data from a remote source
583
+ if (result) {
584
+ result.forEach((v) => {
585
+ self.data.push(v);
586
+ });
587
+ }
588
+ // Process the data
589
+ setData();
590
+ // Set value
591
+ if (typeof(self.value) !== 'undefined') {
592
+ setValue(self.value, true);
593
+ }
594
+ // Custom event by the developer
595
+ if (typeof(onload) === 'function') {
596
+ onload(self);
597
+ }
598
+ }
599
+
526
600
  self.add = async function (e) {
527
601
  if (!self.input.textContent) {
528
602
  return false;
@@ -550,11 +624,11 @@ if (!Modal && typeof (require) === 'function') {
550
624
  }
551
625
 
552
626
  // Process the data
553
- data.push(s);
627
+ data.unshift(s);
554
628
  // Select the new item
555
629
  self.select(e, s);
556
630
  // Close dropdown
557
- self.close();
631
+ self.search();
558
632
 
559
633
  // Event
560
634
  if (typeof (self.oninsert) === 'function') {
@@ -562,17 +636,16 @@ if (!Modal && typeof (require) === 'function') {
562
636
  }
563
637
  }
564
638
 
565
- self.search = function (e) {
639
+ self.search = function () {
566
640
  if (self.state && self.autocomplete) {
567
641
  // Filter options
568
642
  let temp;
569
- if (! self.input.textContent) {
570
- temp = self.data;
643
+ let value = self.input.textContent.toLowerCase()
644
+ if (! value) {
645
+ temp = data;
571
646
  } else {
572
- temp = self.data.filter(item => {
573
- return item.selected === true ||
574
- (item.text.toLowerCase().includes(self.input.textContent.toLowerCase())) ||
575
- (item.group && item.group.toLowerCase().includes(self.input.textContent.toLowerCase()));
647
+ temp = data.filter(item => {
648
+ return item.selected === true || (item.text.toLowerCase().includes(value)) || (item.group && item.group.toLowerCase().includes(value));
576
649
  });
577
650
  }
578
651
  // Cursor
@@ -637,7 +710,11 @@ if (!Modal && typeof (require) === 'function') {
637
710
  }
638
711
  } else {
639
712
  if (value[0] === s) {
640
- s.selected = !s.selected;
713
+ if (self.allowempty === false) {
714
+ s.selected = true;
715
+ } else {
716
+ s.selected = !s.selected;
717
+ }
641
718
  } else {
642
719
  if (value[0]) {
643
720
  value[0].selected = false;
@@ -655,14 +732,6 @@ if (!Modal && typeof (require) === 'function') {
655
732
  }
656
733
  }
657
734
 
658
- self.getGroup = function () {
659
- if (this.group && this.header) {
660
- return this.group;
661
- } else {
662
- return '';
663
- }
664
- }
665
-
666
735
  self.onload = function () {
667
736
  if (self.type !== "inline") {
668
737
  // Create modal instance
@@ -685,32 +754,9 @@ if (!Modal && typeof (require) === 'function') {
685
754
  self.input.remove();
686
755
  }
687
756
 
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
- }
757
+ // Default width
758
+ self.el.style.width = self.width + 'px';
705
759
 
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
760
  // Focus out of the component
715
761
  self.el.addEventListener('focusout', function (e) {
716
762
  if (self.modal) {
@@ -721,6 +767,7 @@ if (!Modal && typeof (require) === 'function') {
721
767
  }
722
768
  }
723
769
  });
770
+
724
771
  // Key events
725
772
  self.el.addEventListener('keydown', function (e) {
726
773
  if (! self.modal.closed) {
@@ -763,9 +810,16 @@ if (!Modal && typeof (require) === 'function') {
763
810
  }
764
811
  }
765
812
  });
766
- // Custom event by the developer
767
- if (typeof (onload) === 'function') {
768
- onload(self);
813
+
814
+ // Load remote data
815
+ if (self.url) {
816
+ fetch(self.url, {
817
+ headers: {
818
+ 'Content-Type': 'text/json',
819
+ }
820
+ }).then(r => r.json()).then(loadData);
821
+ } else {
822
+ loadData();
769
823
  }
770
824
  }
771
825
 
@@ -809,7 +863,7 @@ if (!Modal && typeof (require) === 'function') {
809
863
  <div class="lm-dropdown-content">
810
864
  <div>
811
865
  <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}}">
866
+ <div class="lm-dropdown-item" onclick="self.parent.select" data-cursor="{{self.cursor}}" data-selected="{{self.selected}}" data-group="{{self.header}}">
813
867
  <div><img :src="self.image" /><span>{{self.text}}</span></div>
814
868
  </div>
815
869
  </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.0"
23
23
  }