@websy/websy-designs 1.2.5 → 1.2.7

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.
@@ -16,6 +16,7 @@
16
16
  WebsyLegend
17
17
  WebsyMap
18
18
  WebsyKPI
19
+ WebsyIcons
19
20
  WebsyPDFButton
20
21
  Switch
21
22
  WebsyTemplate
@@ -23,8 +24,9 @@
23
24
  ButtonGroup
24
25
  WebsyUtils
25
26
  Pager
27
+ ResponsiveText
26
28
  */
27
-
29
+ import WebsyDesignsQlikPlugins from '@websy/websy-designs-qlik-plugin/dist/websy-designs-qlik-plugin-es6'
28
30
  /* global XMLHttpRequest fetch ENV */
29
31
  class APIService {
30
32
  constructor (baseUrl = '', options = {}) {
@@ -203,16 +205,20 @@ class WebsyDatePicker {
203
205
  this.currentselection = []
204
206
  this.validDates = []
205
207
  this.validYears = []
208
+ this.validHours = []
206
209
  this.customRangeSelected = true
207
210
  this.shiftPressed = false
208
211
  const DEFAULTS = {
209
212
  defaultRange: 0,
210
213
  allowClear: true,
214
+ hideRanges: false,
211
215
  minAllowedDate: this.floorDate(new Date(new Date((new Date().setFullYear(new Date().getFullYear() - 1))).setDate(1))),
212
216
  maxAllowedDate: this.floorDate(new Date((new Date()))),
213
217
  minAllowedYear: 1970,
214
218
  maxAllowedYear: new Date().getFullYear(),
215
219
  daysOfWeek: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
220
+ monthsOfYear: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
221
+ hours: new Array(24).fill(0).map((d, i) => ({text: (i < 10 ? '0' : '') + i + ':00', num: (1 / 24 * i)})),
216
222
  mode: 'date',
217
223
  monthMap: {
218
224
  0: 'Jan',
@@ -278,6 +284,30 @@ class WebsyDatePicker {
278
284
  label: 'Last 10 Years',
279
285
  range: [new Date().getFullYear() - 9, DEFAULTS.maxAllowedYear]
280
286
  }
287
+ ],
288
+ monthyear: [
289
+ {
290
+ label: 'All',
291
+ range: [DEFAULTS.minAllowedDate, DEFAULTS.maxAllowedDate]
292
+ },
293
+ {
294
+ label: 'Last 12 Months',
295
+ range: [this.floorDate(new Date(new Date(new Date().setDate(1)).setMonth(new Date().getMonth() - 12))), this.floorDate(new Date(new Date().setDate(1)))]
296
+ },
297
+ {
298
+ label: 'Last 18 Months',
299
+ range: [this.floorDate(new Date(new Date(new Date().setDate(1)).setMonth(new Date().getMonth() - 18))), this.floorDate(new Date(new Date().setDate(1)))]
300
+ },
301
+ {
302
+ label: 'Last 24 Months',
303
+ range: [this.floorDate(new Date(new Date(new Date().setDate(1)).setMonth(new Date().getMonth() - 24))), this.floorDate(new Date(new Date().setDate(1)))]
304
+ }
305
+ ],
306
+ hour: [
307
+ {
308
+ label: 'All',
309
+ range: ['00:00', '23:00']
310
+ }
281
311
  ]
282
312
  }
283
313
  this.options = Object.assign({}, DEFAULTS, options)
@@ -300,7 +330,7 @@ class WebsyDatePicker {
300
330
  document.addEventListener('keydown', this.handleKeyDown.bind(this))
301
331
  document.addEventListener('keyup', this.handleKeyUp.bind(this))
302
332
  let html = `
303
- <div class='websy-date-picker-container'>
333
+ <div class='websy-date-picker-container ${this.options.mode}'>
304
334
  <span class='websy-dropdown-header-label'>${this.options.label || 'Date'}</span>
305
335
  <div id="${this.elementId}_header" class='websy-date-picker-header ${this.options.allowClear === true ? 'allow-clear' : ''}'>
306
336
  <span id='${this.elementId}_selectedRange'>${this.options.ranges[this.options.mode][this.selectedRange].label}</span>
@@ -314,8 +344,8 @@ class WebsyDatePicker {
314
344
  html += `
315
345
  </div>
316
346
  <div id='${this.elementId}_mask' class='websy-date-picker-mask'></div>
317
- <div id='${this.elementId}_content' class='websy-date-picker-content'>
318
- <div class='websy-date-picker-ranges'>
347
+ <div id='${this.elementId}_content' class='websy-date-picker-content ${this.options.hideRanges === true ? 'hide-ranges' : ''}'>
348
+ <div class='websy-date-picker-ranges' >
319
349
  <ul id='${this.elementId}_rangelist'>
320
350
  ${this.renderRanges()}
321
351
  </ul>
@@ -351,11 +381,28 @@ class WebsyDatePicker {
351
381
  contentEl.classList.remove('active')
352
382
  if (confirm === true) {
353
383
  if (this.options.onChange) {
354
- if (this.customRangeSelected === true) {
355
- this.options.onChange(this.selectedRangeDates, true)
384
+ console.log('confirm', this.selectedRangeDates)
385
+ console.log('confirm', this.currentselection)
386
+ if (this.customRangeSelected === true) {
387
+ if (this.options.mode === 'hour') {
388
+ let hoursOut = []
389
+ for (let i = this.selectedRangeDates[0]; i < this.selectedRangeDates[1] + 1; i++) {
390
+ hoursOut.push(this.options.hours[i])
391
+ }
392
+ this.options.onChange(hoursOut, true)
393
+ }
394
+ else {
395
+ this.options.onChange(this.selectedRangeDates, true)
396
+ }
356
397
  }
357
398
  else {
358
- this.options.onChange(this.currentselection, false)
399
+ if (this.options.mode === 'hour') {
400
+ let hoursOut = this.selectedRangeDates.map(h => this.options.hours[h])
401
+ this.options.onChange(hoursOut, true)
402
+ }
403
+ else {
404
+ this.options.onChange(this.currentselection, false)
405
+ }
359
406
  }
360
407
  }
361
408
  this.updateRange()
@@ -420,7 +467,7 @@ class WebsyDatePicker {
420
467
  handleMouseDown (event) {
421
468
  if (this.shiftPressed === true && this.currentselection.length > 0) {
422
469
  this.mouseDownId = this.currentselection[this.currentselection.length - 1]
423
- this.selectDate(+event.target.id.split('_')[0])
470
+ this.selectDate(+event.target.id.split('_')[1])
424
471
  }
425
472
  else {
426
473
  this.mouseDown = true
@@ -433,7 +480,7 @@ class WebsyDatePicker {
433
480
  this.currentselection = []
434
481
  this.customRangeSelected = false
435
482
  }
436
- this.mouseDownId = +event.target.id.split('_')[0]
483
+ this.mouseDownId = +event.target.id.split('_')[1]
437
484
  this.selectDate(this.mouseDownId)
438
485
  }
439
486
  }
@@ -444,9 +491,9 @@ class WebsyDatePicker {
444
491
  if (event.target.classList.contains('websy-disabled-date')) {
445
492
  return
446
493
  }
447
- if (event.target.id.split('_')[0] !== this.mouseDownId) {
494
+ if (event.target.id.split('_')[1] !== this.mouseDownId) {
448
495
  this.dragging = true
449
- this.selectDate(+event.target.id.split('_')[0])
496
+ this.selectDate(+event.target.id.split('_')[1])
450
497
  }
451
498
  }
452
499
  }
@@ -468,7 +515,8 @@ class WebsyDatePicker {
468
515
  return
469
516
  }
470
517
  if (this.customRangeSelected === true) {
471
- console.log('if date selection', this.currentselection)
518
+ console.log('if date selection', this.currentselection)
519
+ console.log('if month selection', this.currentselection.map(d => new Date(d)))
472
520
  let diff
473
521
  if (this.options.mode === 'date') {
474
522
  diff = Math.floor((this.selectedRangeDates[this.selectedRangeDates.length - 1].getTime() - this.selectedRangeDates[0].getTime()) / this.oneDay)
@@ -482,6 +530,15 @@ class WebsyDatePicker {
482
530
  // diff += 1
483
531
  }
484
532
  }
533
+ else if (this.options.mode === 'monthyear') {
534
+ let yearDiff = (this.selectedRangeDates[this.selectedRangeDates.length - 1].getFullYear() - this.selectedRangeDates[0].getFullYear()) * 12
535
+ diff = Math.floor((this.selectedRangeDates[this.selectedRangeDates.length - 1].getMonth() - this.selectedRangeDates[0].getMonth())) + yearDiff
536
+ console.log('year diff', yearDiff)
537
+ console.log('diff', diff)
538
+ }
539
+ else if (this.options.mode === 'hour') {
540
+ diff = this.selectedRangeDates[this.selectedRangeDates.length - 1] - this.selectedRangeDates[0]
541
+ }
485
542
  for (let i = 0; i < diff + 1; i++) {
486
543
  let d
487
544
  let rangeStart
@@ -497,12 +554,31 @@ class WebsyDatePicker {
497
554
  rangeStart = this.selectedRangeDates[0]
498
555
  rangeEnd = this.selectedRangeDates[this.selectedRangeDates.length - 1]
499
556
  }
557
+ else if (this.options.mode === 'monthyear') {
558
+ d = new Date(this.selectedRangeDates[0].getTime()).setMonth(this.selectedRangeDates[0].getMonth() + i)
559
+ rangeStart = this.selectedRangeDates[0].getTime()
560
+ rangeEnd = this.selectedRangeDates[this.selectedRangeDates.length - 1].getTime()
561
+ }
562
+ else if (this.options.mode === 'hour') {
563
+ d = this.selectedRangeDates[0] + i
564
+ rangeStart = this.selectedRangeDates[0]
565
+ rangeEnd = this.selectedRangeDates[this.selectedRangeDates.length - 1]
566
+ }
500
567
  let dateEl
501
568
  if (this.options.mode === 'date') {
502
- dateEl = document.getElementById(`${d}_date`)
569
+ dateEl = document.getElementById(`${this.elementId}_${d}_date`)
503
570
  }
504
571
  else if (this.options.mode === 'year') {
505
- dateEl = document.getElementById(`${d}_year`)
572
+ dateEl = document.getElementById(`${this.elementId}_${d}_year`)
573
+ }
574
+ else if (this.options.mode === 'monthyear') {
575
+ console.log('d', d)
576
+ console.log(this.selectedRangeDates)
577
+ console.log(rangeStart, rangeEnd)
578
+ dateEl = document.getElementById(`${this.elementId}_${d}_monthyear`)
579
+ }
580
+ else if (this.options.mode === 'hour') {
581
+ dateEl = document.getElementById(`${this.elementId}_${d}_hour`)
506
582
  }
507
583
  if (dateEl) {
508
584
  dateEl.classList.add('selected')
@@ -519,10 +595,16 @@ class WebsyDatePicker {
519
595
  this.currentselection.forEach(d => {
520
596
  let dateEl
521
597
  if (this.options.mode === 'date') {
522
- dateEl = document.getElementById(`${d}_date`)
598
+ dateEl = document.getElementById(`${this.elementId}_${d}_date`)
523
599
  }
524
600
  else if (this.options.mode === 'year') {
525
- dateEl = document.getElementById(`${d}_year`)
601
+ dateEl = document.getElementById(`${this.elementId}_${d}_year`)
602
+ }
603
+ else if (this.options.mode === 'monthyear') {
604
+ dateEl = document.getElementById(`${this.elementId}_${d}_monthyear`)
605
+ }
606
+ else if (this.options.mode === 'hour') {
607
+ dateEl = document.getElementById(`${this.elementId}_${d}_hour`)
526
608
  }
527
609
  dateEl.classList.add('selected')
528
610
  dateEl.classList.add('first')
@@ -564,6 +646,9 @@ class WebsyDatePicker {
564
646
  let disabled = []
565
647
  this.validDates = []
566
648
  this.validYears = []
649
+ this.validHours = []
650
+ this.monthYears = {}
651
+ this.monthYearMonths = []
567
652
  if (disabledDates) {
568
653
  disabled = disabledDates.map(d => {
569
654
  if (this.options.mode === 'date') {
@@ -572,6 +657,12 @@ class WebsyDatePicker {
572
657
  else if (this.options.mode === 'year') {
573
658
  return d
574
659
  }
660
+ else if (this.options.mode === 'monthyear') {
661
+ //
662
+ }
663
+ else if (this.options.mode === 'hour') {
664
+ return d
665
+ }
575
666
  return d.getTime()
576
667
  })
577
668
  }
@@ -584,15 +675,34 @@ class WebsyDatePicker {
584
675
  else if (this.options.mode === 'year') {
585
676
  diff = (this.options.maxAllowedYear - this.options.minAllowedYear) + 1
586
677
  }
678
+ else if (this.options.mode === 'monthyear') {
679
+ diff = Math.ceil((this.options.maxAllowedDate.getTime() - this.options.minAllowedDate.getTime()) / this.oneDay) + 1
680
+ }
681
+ else if (this.options.mode === 'hour') {
682
+ diff = 24
683
+ }
587
684
  let months = {}
588
685
  let yearList = []
589
686
  for (let i = 0; i < diff; i++) {
590
- if (this.options.mode === 'date') {
687
+ if (this.options.mode === 'date' || this.options.mode === 'monthyear') {
591
688
  let d = this.floorDate(new Date(this.options.minAllowedDate.getTime() + (i * this.oneDay)))
592
689
  let monthYear = `${this.options.monthMap[d.getMonth()]} ${d.getFullYear()}`
593
690
  if (!months[monthYear]) {
594
691
  months[monthYear] = []
595
692
  }
693
+ if (!this.monthYears[d.getFullYear()]) {
694
+ this.monthYears[d.getFullYear()] = []
695
+ }
696
+ if (this.monthYearMonths.indexOf(`${d.getMonth()}-${d.getFullYear()}`) === -1) {
697
+ this.monthYearMonths.push(`${d.getMonth()}-${d.getFullYear()}`)
698
+ this.monthYears[d.getFullYear()].push({
699
+ date: new Date(d.setDate(1)),
700
+ month: this.options.monthMap[d.getMonth()],
701
+ monthNum: d.getMonth(),
702
+ year: d.getFullYear(),
703
+ id: d.setDate(1)
704
+ })
705
+ }
596
706
  if (disabled.indexOf(d.getTime()) === -1) {
597
707
  this.validDates.push(d.getTime())
598
708
  }
@@ -605,11 +715,21 @@ class WebsyDatePicker {
605
715
  this.validYears.push(d)
606
716
  }
607
717
  }
718
+ else if (this.options.mode === 'hour') {
719
+ //
720
+ }
608
721
  }
722
+ if (this.options.mode === 'hour') {
723
+ this.options.hours.forEach(h => {
724
+ if (disabled.indexOf(h.text) === -1) {
725
+ this.validHours.push(h)
726
+ }
727
+ })
728
+ }
609
729
  // check each range to see if it can be enabled
610
730
  for (let i = 0; i < this.options.ranges[this.options.mode].length; i++) {
611
731
  const r = this.options.ranges[this.options.mode][i]
612
- if (this.options.mode === 'date') {
732
+ if (this.options.mode === 'date' || this.options.mode === 'monthyear') {
613
733
  // check the first date
614
734
  if (this.validDates.indexOf(r.range[0].getTime()) !== -1) {
615
735
  r.disabled = false
@@ -649,6 +769,28 @@ class WebsyDatePicker {
649
769
  }
650
770
  }
651
771
  }
772
+ }
773
+ else if (this.options.mode === 'monthyear') {
774
+ //
775
+ }
776
+ else if (this.options.mode === 'hour') {
777
+ if (this.validDates.indexOf(r.range[0]) !== -1) {
778
+ r.disabled = false
779
+ }
780
+ else if (r.range[1]) {
781
+ if (this.validDates.indexOf(r.range[1]) !== -1) {
782
+ r.disabled = false
783
+ }
784
+ else {
785
+ // check the full range until a match is found
786
+ for (let i = r.range[0]; i <= r.range[1]; i++) {
787
+ if (this.validDates.indexOf(r.range[0] + i) !== -1) {
788
+ r.disabled = false
789
+ break
790
+ }
791
+ }
792
+ }
793
+ }
652
794
  }
653
795
  }
654
796
  let html = ''
@@ -674,7 +816,7 @@ class WebsyDatePicker {
674
816
  }
675
817
  html += paddedDays.join('')
676
818
  }
677
- html += months[key].map(d => `<li id='${d.id}_date' class='websy-dp-date ${d.disabled === true ? 'websy-disabled-date' : ''}'>${d.dayOfMonth}</li>`).join('')
819
+ html += months[key].map(d => `<li id='${this.elementId}_${d.id}_date' class='websy-dp-date ${d.disabled === true ? 'websy-disabled-date' : ''}'>${d.dayOfMonth}</li>`).join('')
678
820
  html += `
679
821
  </ul>
680
822
  </div>
@@ -687,7 +829,31 @@ class WebsyDatePicker {
687
829
  yearList.reverse()
688
830
  }
689
831
  html += `<div id='${this.elementId}_dateList' class='websy-dp-date-list'><ul>`
690
- html += yearList.map(d => `<li id='${d.id}_year' class='websy-dp-date websy-dp-year ${d.disabled === true ? 'websy-disabled-date' : ''}'>${d.year}</li>`).join('')
832
+ html += yearList.map(d => `<li id='${this.elementId}_${d.id}_year' class='websy-dp-date websy-dp-year ${d.disabled === true ? 'websy-disabled-date' : ''}'>${d.year}</li>`).join('')
833
+ html += `</ul></div>`
834
+ }
835
+ else if (this.options.mode === 'monthyear') {
836
+ html += `<div id='${this.elementId}_dateList' class='websy-dp-monthyear-container'>`
837
+ for (const year in this.monthYears) {
838
+ html += `
839
+ <ul>
840
+ <li>${year}</li>
841
+ `
842
+ if (this.monthYears[year][0].monthNum > 0) {
843
+ let paddedMonths = []
844
+ for (let i = 0; i < this.monthYears[year][0].monthNum; i++) {
845
+ paddedMonths.push(`<li>&nbsp;</li>`)
846
+ }
847
+ html += paddedMonths.join('')
848
+ }
849
+ html += this.monthYears[year].map(d => `<li id='${this.elementId}_${d.id}_monthyear' data-year='${d.year}' class='websy-dp-date websy-dp-monthyear'>${d.month}</li>`).join('')
850
+ html += `</ul>`
851
+ }
852
+ html += `</div>`
853
+ }
854
+ else if (this.options.mode === 'hour') {
855
+ html += `<div id='${this.elementId}_dateList' class='websy-dp-date-list'><ul>`
856
+ html += this.options.hours.map(h => `<li id='${this.elementId}_${+h.text.split(':')[0]}_hour' data-hour='${h.text}' class='websy-dp-date websy-dp-hour'>${h.text}</li>`).join('')
691
857
  html += `</ul></div>`
692
858
  }
693
859
  return html
@@ -701,16 +867,22 @@ class WebsyDatePicker {
701
867
  if (this.selectedRangeDates[0]) {
702
868
  let el
703
869
  if (this.options.mode === 'date') {
704
- el = document.getElementById(`${this.selectedRangeDates[0].getTime()}_date`)
870
+ el = document.getElementById(`${this.elementId}_${this.selectedRangeDates[0].getTime()}_date`)
705
871
  }
706
872
  else if (this.options.mode === 'year') {
707
873
  if (this.options.sortDirection === 'desc') {
708
- el = document.getElementById(`${this.selectedRangeDates[this.selectedRangeDates.length - 1]}_year`)
874
+ el = document.getElementById(`${this.elementId}_${this.selectedRangeDates[this.selectedRangeDates.length - 1]}_year`)
709
875
  }
710
876
  else {
711
- el = document.getElementById(`${this.selectedRangeDates[0]}_year`)
877
+ el = document.getElementById(`${this.elementId}_${this.selectedRangeDates[0]}_year`)
712
878
  }
713
879
  }
880
+ else if (this.options.mode === 'monthyear') {
881
+ //
882
+ }
883
+ else if (this.options.mode === 'hour') {
884
+ //
885
+ }
714
886
  const parentEl = document.getElementById(`${this.elementId}_dateList`)
715
887
  if (el && parentEl) {
716
888
  parentEl.scrollTo(0, el.offsetTop)
@@ -731,19 +903,33 @@ class WebsyDatePicker {
731
903
  this.currentselection.splice(0, 0, timestamp)
732
904
  }
733
905
  this.customRangeSelected = true
906
+ console.log('current selection', this.currentselection)
734
907
  }
735
908
  else {
736
- this.currentselection.push(timestamp)
909
+ let index = this.currentselection.indexOf(timestamp)
910
+ if (index !== -1) {
911
+ this.currentselection.splice(index, 1)
912
+ }
913
+ else {
914
+ this.currentselection.push(timestamp)
915
+ }
737
916
  this.currentselection.sort((a, b) => a - b)
738
917
  this.customRangeSelected = false
739
918
  }
740
919
  }
741
- if (this.options.mode === 'date') {
920
+ if (this.options.mode === 'date' || this.options.mode === 'monthyear') {
742
921
  this.selectedRangeDates = [new Date(this.currentselection[0]), new Date(this.currentselection[1] || this.currentselection[0])]
922
+ console.log('selected range', this.selectedRangeDates)
743
923
  }
744
924
  else if (this.options.mode === 'year') {
745
925
  this.selectedRangeDates = [this.currentselection[0], this.currentselection[1] || this.currentselection[0]]
746
926
  }
927
+ else if (this.options.mode === 'monthyear') {
928
+ //
929
+ }
930
+ else if (this.options.mode === 'hour') {
931
+ this.selectedRangeDates = [this.currentselection[0], this.currentselection[1] || this.currentselection[0]]
932
+ }
747
933
  // if (this.currentselection.length === 2) {
748
934
  // this.currentselection = []
749
935
  // }
@@ -790,7 +976,7 @@ class WebsyDatePicker {
790
976
  this.updateRange()
791
977
  }
792
978
  setDateBounds (range) {
793
- if (['All Dates', 'All Years'].indexOf(this.options.ranges[this.options.mode][0].label) !== -1) {
979
+ if (['All Dates', 'All Years', 'All'].indexOf(this.options.ranges[this.options.mode][0].label) !== -1) {
794
980
  this.options.ranges[this.options.mode][0].range = [range[0], range[1] || range[0]]
795
981
  }
796
982
  if (this.options.mode === 'date') {
@@ -800,6 +986,14 @@ class WebsyDatePicker {
800
986
  else if (this.options.mode === 'year') {
801
987
  this.options.minAllowedYear = range[0]
802
988
  this.options.maxAllowedYear = range[1] || range[0]
989
+ }
990
+ else if (this.options.mode === 'monthyear') {
991
+ this.options.minAllowedDate = range[0]
992
+ this.options.maxAllowedDate = range[1] || range[0]
993
+ }
994
+ else if (this.options.mode === 'hour') {
995
+ this.options.minAllowedHour = range[0]
996
+ this.options.maxAllowedHour = range[1] || range[0]
803
997
  }
804
998
  }
805
999
  updateRange () {
@@ -815,6 +1009,15 @@ class WebsyDatePicker {
815
1009
  else if (this.options.mode === 'year') {
816
1010
  return d
817
1011
  }
1012
+ else if (this.options.mode === 'monthyear') {
1013
+ if (!d.getMonth) {
1014
+ d = new Date(d)
1015
+ }
1016
+ return `${this.options.monthMap[d.getMonth()]} ${d.getFullYear()}`
1017
+ }
1018
+ else if (this.options.mode === 'hour') {
1019
+ return d
1020
+ }
818
1021
  })
819
1022
  let start = list[0]
820
1023
  let end = ''
@@ -824,6 +1027,10 @@ class WebsyDatePicker {
824
1027
  else {
825
1028
  start = `${list.length} selected`
826
1029
  }
1030
+ if (this.options.mode === 'hour') {
1031
+ start = this.options.hours[start].text
1032
+ end = `${this.customRangeSelected === true ? ' - ' : ''}${this.options.hours[list[list.length - 1]].text}`
1033
+ }
827
1034
  range = { label: `${start}${end}` }
828
1035
  }
829
1036
  else {
@@ -861,7 +1068,8 @@ class WebsyDropdown {
861
1068
  disabled: false,
862
1069
  minSearchCharacters: 2,
863
1070
  showCompleteSelectedList: false,
864
- closeAfterSelection: true
1071
+ closeAfterSelection: true,
1072
+ customActions: []
865
1073
  }
866
1074
  this.options = Object.assign({}, DEFAULTS, options)
867
1075
  if (this.options.items.length > 0) {
@@ -887,7 +1095,7 @@ class WebsyDropdown {
887
1095
  const headerLabel = this.selectedItems.map(s => this.options.items[s].label || this.options.items[s].value).join(this.options.multiValueDelimiter)
888
1096
  const headerValue = this.selectedItems.map(s => this.options.items[s].value || this.options.items[s].label).join(this.options.multiValueDelimiter)
889
1097
  let html = `
890
- <div id='${this.elementId}_container' class='websy-dropdown-container ${this.options.disabled ? 'disabled' : ''} ${this.options.disableSearch !== true ? 'with-search' : ''} ${this.options.style}'>
1098
+ <div id='${this.elementId}_container' class='websy-dropdown-container ${this.options.disabled ? 'disabled' : ''} ${this.options.disableSearch !== true ? 'with-search' : ''} ${this.options.style} ${this.options.customActions.length > 0 ? 'with-actions' : ''}'>
891
1099
  <div id='${this.elementId}_header' class='websy-dropdown-header ${this.selectedItems.length === 1 ? 'one-selected' : ''} ${this.options.allowClear === true ? 'allow-clear' : ''}'>
892
1100
  <svg class='search' width="20" height="20" viewBox="0 0 512 512"><path d="M221.09,64A157.09,157.09,0,1,0,378.18,221.09,157.1,157.1,0,0,0,221.09,64Z" style="fill:none;stroke:#000;stroke-miterlimit:10;stroke-width:32px"/><line x1="338.29" y1="338.29" x2="448" y2="448" style="fill:none;stroke:#000;stroke-linecap:round;stroke-miterlimit:10;stroke-width:32px"/></svg>
893
1101
  <span id='${this.elementId}_headerLabel' class='websy-dropdown-header-label'>${this.options.label}</span>
@@ -905,6 +1113,24 @@ class WebsyDropdown {
905
1113
  <div id='${this.elementId}_mask' class='websy-dropdown-mask'></div>
906
1114
  <div id='${this.elementId}_content' class='websy-dropdown-content'>
907
1115
  `
1116
+ if (this.options.customActions.length > 0) {
1117
+ html += `
1118
+ <div class='websy-dropdown-action-container'>
1119
+ <button class='websy-dropdown-action-button'>
1120
+ <svg xmlns="http://www.w3.org/2000/svg" width="30" height="30" viewBox="0 0 512 512">><circle cx="256" cy="256" r="32" style="fill:none;stroke:#000;stroke-miterlimit:10;stroke-width:32px"/><circle cx="416" cy="256" r="32" style="fill:none;stroke:#000;stroke-miterlimit:10;stroke-width:32px"/><circle cx="96" cy="256" r="32" style="fill:none;stroke:#000;stroke-miterlimit:10;stroke-width:32px"/></svg>
1121
+ </button>
1122
+ <ul id='${this.elementId}_actionContainer'>
1123
+ `
1124
+ this.options.customActions.forEach((a, i) => {
1125
+ html += `
1126
+ <li class='websy-dropdown-custom-action' data-index='${i}'>${a.label}</li>
1127
+ `
1128
+ })
1129
+ html += `
1130
+ </ul>
1131
+ </div>
1132
+ `
1133
+ }
908
1134
  if (this.options.disableSearch !== true) {
909
1135
  html += `
910
1136
  <input id='${this.elementId}_search' class='websy-dropdown-search' placeholder='${this.options.searchPlaceholder || 'Search'}'>
@@ -966,6 +1192,10 @@ class WebsyDropdown {
966
1192
  const maskEl = document.getElementById(`${this.elementId}_mask`)
967
1193
  const contentEl = document.getElementById(`${this.elementId}_content`)
968
1194
  const scrollEl = document.getElementById(`${this.elementId}_itemsContainer`)
1195
+ const actionEl = document.getElementById(`${this.elementId}_actionContainer`)
1196
+ if (actionEl) {
1197
+ actionEl.classList.remove('active')
1198
+ }
969
1199
  const el = document.getElementById(this.elementId)
970
1200
  if (el) {
971
1201
  el.style.zIndex = ''
@@ -1006,6 +1236,18 @@ class WebsyDropdown {
1006
1236
  const el = document.getElementById(`${this.elementId}_container`)
1007
1237
  el.classList.toggle('search-open')
1008
1238
  }
1239
+ else if (event.target.classList.contains('websy-dropdown-custom-action')) {
1240
+ const actionIndex = +event.target.getAttribute('data-index')
1241
+ if (this.options.customActions[actionIndex] && this.options.customActions[actionIndex].fn) {
1242
+ this.options.customActions[actionIndex].fn()
1243
+ }
1244
+ }
1245
+ else if (event.target.classList.contains('websy-dropdown-action-button')) {
1246
+ const el = document.getElementById(`${this.elementId}_actionContainer`)
1247
+ if (el) {
1248
+ el.classList.toggle('active')
1249
+ }
1250
+ }
1009
1251
  }
1010
1252
  handleKeyUp (event) {
1011
1253
  if (event.target.classList.contains('websy-dropdown-search')) {
@@ -1518,6 +1760,46 @@ class WebsyForm {
1518
1760
  }
1519
1761
  }
1520
1762
 
1763
+ /* global include */
1764
+ const WebsyIcons = {
1765
+ 'search-icon': `
1766
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
1767
+ viewBox="0 0 500 500" xml:space="preserve">
1768
+ <path d="M481.4,468.6c-17.2-17.2-34.4-34.4-51.6-51.6c-27.4-27.4-54.8-54.8-82.2-82.2c-4.8-4.8-9.5-9.5-14.3-14.3
1769
+ c29.4-32.5,47.4-75.5,47.4-122.7C380.7,97,298.7,15,197.9,15S15,97,15,197.9s82,182.9,182.9,182.9c47.2,0,90.3-18,122.7-47.4
1770
+ c15.7,15.7,31.4,31.4,47.1,47.1c27.4,27.4,54.8,54.8,82.2,82.2c6.3,6.3,12.5,12.5,18.8,18.8C476.8,489.6,489.6,476.8,481.4,468.6z
1771
+ M35,197.9C35,108.1,108.1,35,197.9,35s162.9,73.1,162.9,162.9s-73.1,162.9-162.9,162.9S35,287.7,35,197.9z"/>
1772
+ </svg>
1773
+
1774
+ `,
1775
+ 'bag-icon': `
1776
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
1777
+ viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
1778
+ <path d="M456.6,472.3H43.4c-5.3,0-10.2-2.1-13.7-6c-3.6-3.9-5.2-9.2-4.5-14.4l37-285.4c1.2-9,9-15.9,18.2-15.9h339.2
1779
+ c9.2,0,17,6.8,18.2,15.8l37,285.4c0.7,5.2-1,10.5-4.5,14.4l0,0C466.8,470.1,461.9,472.3,456.6,472.3z M46.5,451.2h407l-36.3-279.6
1780
+ H82.8L46.5,451.2z"/>
1781
+ <g>
1782
+ <path d="M361.3,157.1C357.3,94.8,308.4,46,249.9,46c-28,0-54.8,11.1-75.4,31.4c-20.7,20.3-33.5,47.9-35.9,77.8l-21.5-1.6
1783
+ c2.8-34.8,17.7-67.1,42.1-91C183.9,38.3,216.1,25,249.9,25c34.2,0,66.6,13.6,91.5,38.3c24.5,24.3,39.2,57.2,41.5,92.5L361.3,157.1z
1784
+ "/>
1785
+ </g>
1786
+ </svg>
1787
+
1788
+ `,
1789
+ 'user-icon': `
1790
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
1791
+ viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
1792
+ <g>
1793
+ <path d="M248,260.5c-62,0-112.5-52.8-112.5-117.7S186,25,248,25s112.5,52.8,112.5,117.7S310,260.5,248,260.5z M248,45.9
1794
+ c-51,0-92.5,43.4-92.5,96.8s41.5,96.8,92.5,96.8c51,0,92.5-43.4,92.5-96.8S299,45.9,248,45.9z"/>
1795
+ </g>
1796
+ <path d="M45,475C45,475,45,475,45,475c0-118.3,92-214.5,205-214.5c113,0,205,96.2,205,214.5c0,0,0,0,0,0h20c0,0,0,0,0,0
1797
+ c0-62.9-23.4-122-65.9-166.5c-42.5-44.5-99-69-159.1-69s-116.6,24.5-159.1,69C48.4,353,25,412.1,25,475c0,0,0,0,0,0H45z"/>
1798
+ </svg>
1799
+
1800
+ `
1801
+ }
1802
+
1521
1803
  class WebsyLoadingDialog {
1522
1804
  constructor (elementId, options) {
1523
1805
  this.options = Object.assign({}, options)
@@ -2141,6 +2423,250 @@ class WebsyPubSub {
2141
2423
  }
2142
2424
  }
2143
2425
 
2426
+ class ResponsiveText {
2427
+ constructor (elementId, options) {
2428
+ const DEFAULTS = {
2429
+ textAlign: 'center',
2430
+ verticalAlign: 'flex-end',
2431
+ wrapText: false
2432
+ }
2433
+ this.options = Object.assign({}, DEFAULTS, options)
2434
+ this.elementId = elementId
2435
+ this.canvas = document.createElement('canvas')
2436
+ window.addEventListener('resize', () => this.render())
2437
+ const el = document.getElementById(this.elementId)
2438
+ if (el) {
2439
+ this.render()
2440
+ }
2441
+ }
2442
+ css (element, property) {
2443
+ return window.getComputedStyle(element, null).getPropertyValue(property)
2444
+ }
2445
+ render (text) {
2446
+ if (typeof text !== 'undefined') {
2447
+ this.options.text = text
2448
+ }
2449
+ if (this.options.text) {
2450
+ let wrappingRequired = false
2451
+ const el = document.getElementById(this.elementId)
2452
+ let cx = this.canvas.getContext('2d')
2453
+ let f = 0
2454
+ let fits = false
2455
+ // let el = document.getElementById(`${layout.qInfo.qId}_responsiveInner`)
2456
+ let height = el.clientHeight
2457
+ if (typeof this.options.maxHeight === 'string' && this.options.maxHeight.indexOf('%') !== -1) {
2458
+ let p = +this.options.maxHeight.replace('%', '')
2459
+ if (!isNaN(p)) {
2460
+ this.options.maxHeight = Math.floor(height * (p / 100))
2461
+ }
2462
+ }
2463
+ else if (
2464
+ typeof this.options.maxHeight === 'string' &&
2465
+ this.options.maxHeight.indexOf('px') !== -1
2466
+ ) {
2467
+ this.options.maxHeight = +this.options.maxHeight.replace('px', '')
2468
+ }
2469
+ if (typeof this.options.minHeight === 'string' && this.options.minHeight.indexOf('%') !== -1) {
2470
+ let p = +this.options.minHeight.replace('%', '')
2471
+ if (!isNaN(p)) {
2472
+ this.options.minHeight = Math.floor(height * (p / 100))
2473
+ }
2474
+ }
2475
+ else if (
2476
+ typeof this.options.minHeight === 'string' &&
2477
+ this.options.minHeight.indexOf('px') !== -1
2478
+ ) {
2479
+ this.options.minHeight = +this.options.minHeight.replace('px', '')
2480
+ }
2481
+
2482
+ const fontFamily = this.css(el, 'font-family')
2483
+ const fontWeight = this.css(el, 'font-weight')
2484
+ let allowedWidth = el.clientWidth
2485
+ if (allowedWidth === 0) {
2486
+ // check for a max-width property
2487
+ if (
2488
+ el.style.maxWidth &&
2489
+ el.style.maxWidth !== 'auto'
2490
+ ) {
2491
+ if (el.parentElement.clientWidth > 0) {
2492
+ let calc = el.style.maxWidth
2493
+ if (calc.indexOf('calc') !== -1) {
2494
+ // this logic currently only handles calc statements using % and px
2495
+ // and only + or - formulas
2496
+ calc = calc.replace('calc(', '').replace(')', '')
2497
+ calc = calc.split(' ')
2498
+ if (calc[0].indexOf('px') !== -1) {
2499
+ allowedWidth = calc[0].replace('px', '')
2500
+ }
2501
+ else if (calc[0].indexOf('%') !== -1) {
2502
+ allowedWidth = el.parentElement.clientWidth * (+calc[0].replace('%', '') / 100)
2503
+ }
2504
+ if (calc[2] && calc[4]) {
2505
+ // this means we have an operator and a second value
2506
+ // handle -
2507
+ if (calc[2] === '-') {
2508
+ if (calc[4].indexOf('px') !== -1) {
2509
+ allowedWidth -= +calc[4].replace('px', '')
2510
+ }
2511
+ }
2512
+ if (calc[2] === '+') {
2513
+ if (calc[4].indexOf('px') !== -1) {
2514
+ allowedWidth += +calc[4].replace('px', '')
2515
+ }
2516
+ }
2517
+ }
2518
+ }
2519
+ else if (calc.indexOf('px') !== -1) {
2520
+ allowedWidth = +calc.replace('px', '')
2521
+ }
2522
+ else if (calc.indexOf('%') !== -1) {
2523
+ allowedWidth =
2524
+ el.parentElement.clientWidth *
2525
+ (+calc.replace('%', '') / 100)
2526
+ }
2527
+ }
2528
+ }
2529
+ }
2530
+ // console.log('max height', this.options.maxHeight);
2531
+ let innerElHeight = el.clientHeight
2532
+ while (fits === false) {
2533
+ f++
2534
+ cx.font = `${fontWeight} ${f}px ${fontFamily}`
2535
+ let measurements = cx.measureText(this.options.text)
2536
+ // add support for safari where some elements end up with zero height
2537
+ if (navigator.userAgent.indexOf('Safari') !== -1) {
2538
+ // get the closest parent that has a height
2539
+ let heightFound = false
2540
+ let currEl = el
2541
+ while (heightFound === false) {
2542
+ if (currEl.clientHeight > 0) {
2543
+ innerElHeight = currEl.clientHeight
2544
+ heightFound = true
2545
+ }
2546
+ else if (currEl.parentNode) {
2547
+ currEl = currEl.parentNode
2548
+ }
2549
+ else {
2550
+ // prevent the loop from running indefinitely
2551
+ heightFound = true
2552
+ }
2553
+ }
2554
+ }
2555
+ if (typeof this.options.maxHeight !== 'undefined' && f === this.options.maxHeight) {
2556
+ f = this.options.maxHeight
2557
+ height = measurements.actualBoundingBoxAscent
2558
+ fits = true
2559
+ }
2560
+ else if (
2561
+ measurements.width > allowedWidth ||
2562
+ measurements.actualBoundingBoxAscent >= innerElHeight
2563
+ ) {
2564
+ f--
2565
+ height = measurements.actualBoundingBoxAscent
2566
+ fits = true
2567
+ }
2568
+ }
2569
+ if (this.options.minHeight === '') {
2570
+ this.options.minHeight = undefined
2571
+ }
2572
+ if (typeof this.options.minHeight !== 'undefined') {
2573
+ if (this.options.minHeight > f && this.options.wrapText === true) {
2574
+ // we run the process again but this time separating the words onto separate lines
2575
+ // this currently only supports wrapping onto 2 lines
2576
+ wrappingRequired = true
2577
+ fits = false
2578
+ f = this.options.minHeight
2579
+ let spaceCount = this.options.text.match(/ /g)
2580
+ if (spaceCount && spaceCount.length > 0) {
2581
+ spaceCount = spaceCount.length
2582
+ let words = this.options.text.split(' ')
2583
+ while (fits === false) {
2584
+ f++
2585
+ cx.font = `${fontWeight} ${f}px ${fontFamily}`
2586
+ for (let i = spaceCount; i > 0; i--) {
2587
+ let fitsCount = 0
2588
+ let lines = [
2589
+ words.slice(0, i).join(' '),
2590
+ words.slice(i, words.length).join(' ')
2591
+ ]
2592
+ let longestLine = lines.reduce(
2593
+ (a, b) => (a.length > b.length ? a : b),
2594
+ ''
2595
+ )
2596
+ // lines.forEach(l => {
2597
+ let measurements = cx.measureText(longestLine)
2598
+ // add support for safari where some elements end up with zero height
2599
+ if (navigator.userAgent.indexOf('Safari') !== -1) {
2600
+ // get the closest parent that has a height
2601
+ let heightFound = false
2602
+ let currEl = el
2603
+ while (heightFound === false) {
2604
+ if (currEl.clientHeight > 0) {
2605
+ innerElHeight = currEl.clientHeight
2606
+ heightFound = true
2607
+ }
2608
+ else if (currEl.parentNode) {
2609
+ currEl = currEl.parentNode
2610
+ }
2611
+ else {
2612
+ // prevent the loop from running indefinitely
2613
+ heightFound = true
2614
+ }
2615
+ }
2616
+ }
2617
+ if (typeof this.options.maxHeight !== 'undefined' && f === this.options.maxHeight) {
2618
+ f = this.options.maxHeight
2619
+ height = measurements.actualBoundingBoxAscent
2620
+ fits = true
2621
+ break
2622
+ }
2623
+ else if (
2624
+ measurements.width > allowedWidth ||
2625
+ measurements.actualBoundingBoxAscent >=
2626
+ (innerElHeight / 2) * 0.75
2627
+ ) {
2628
+ f--
2629
+ height = measurements.actualBoundingBoxAscent
2630
+ fits = true
2631
+ break
2632
+ }
2633
+ // })
2634
+ }
2635
+ }
2636
+ }
2637
+ if (typeof this.options.minHeight !== 'undefined' && this.options.minHeight > f) {
2638
+ f = this.options.minHeight
2639
+ }
2640
+ }
2641
+ else if (this.options.minHeight > f) {
2642
+ f = this.options.minHeight
2643
+ }
2644
+ }
2645
+ let spanHeight = Math.min(innerElHeight, height)
2646
+ el.innerHTML = `
2647
+ <div
2648
+ class='websy-responsive-text'
2649
+ style='
2650
+ justify-content: ${this.options.verticalAlign};
2651
+ font-size: ${f}px;
2652
+ font-weight: ${fontWeight || 'normal'};
2653
+ '
2654
+ >
2655
+ <span
2656
+ style='
2657
+ white-space: ${this.options.wrapText === true ? 'normal' : 'nowrap'};
2658
+ height: ${Math.floor(wrappingRequired === true ? spanHeight * ((1 * 1) / 3) * 2 : spanHeight)}px;
2659
+ line-height: ${Math.ceil(wrappingRequired === true ? f * 1.2 : spanHeight)}px;
2660
+ justify-content: ${this.options.textAlign};
2661
+ text-align: ${this.options.textAlign};
2662
+ '
2663
+ >${this.options.text}</span>
2664
+ </div>
2665
+ `
2666
+ }
2667
+ }
2668
+ }
2669
+
2144
2670
  /* global WebsyDesigns */
2145
2671
  class WebsyResultList {
2146
2672
  constructor (elementId, options) {
@@ -3929,7 +4455,9 @@ class WebsyTable2 {
3929
4455
  handleGlobalMouseUp (event) {
3930
4456
  this.scrolling = false
3931
4457
  const el = document.getElementById(this.elementId)
3932
- el.classList.remove('scrolling')
4458
+ if (el) {
4459
+ el.classList.remove('scrolling')
4460
+ }
3933
4461
  }
3934
4462
  handleMouseUp (event) {
3935
4463
  this.scrolling = false
@@ -5649,7 +6177,7 @@ class WebsyMap {
5649
6177
  const el = document.getElementById(this.elementId)
5650
6178
  if (el) {
5651
6179
  if (typeof d3 === 'undefined') {
5652
- console.error('d3 library has not been loaded')
6180
+ // console.error('d3 library has not been loaded')
5653
6181
  }
5654
6182
  if (typeof L === 'undefined') {
5655
6183
  console.error('Leaflet library has not been loaded')
@@ -5935,7 +6463,12 @@ const WebsyDesigns = {
5935
6463
  ButtonGroup,
5936
6464
  WebsySwitch: Switch,
5937
6465
  Pager,
5938
- Switch
6466
+ Switch,
6467
+ ResponsiveText,
6468
+ WebsyResponsiveText: ResponsiveText,
6469
+ QlikPlugin: WebsyDesignsQlikPlugins,
6470
+ Icons: WebsyIcons,
6471
+ WebsyIcons
5939
6472
  }
5940
6473
 
5941
6474
  WebsyDesigns.service = new WebsyDesigns.APIService('')