@websy/websy-designs 1.2.32 → 1.2.33

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.
@@ -11,6 +11,7 @@
11
11
  WebsyResultList
12
12
  WebsyTable
13
13
  WebsyTable2
14
+ WebsyTable3
14
15
  WebsyIcons
15
16
  WebsyChart
16
17
  WebsyChartTooltip
@@ -27,6 +28,7 @@
27
28
  WebsyLogin
28
29
  WebsySignup
29
30
  ResponsiveText
31
+ WebsyDragDrop
30
32
  Pager
31
33
  */
32
34
 
@@ -1410,7 +1412,11 @@ class WebsyDropdown {
1410
1412
  d.index = i
1411
1413
  }
1412
1414
  return d
1413
- })
1415
+ })
1416
+ const headerEl = document.getElementById(`${this.elementId}_header`)
1417
+ if (headerEl) {
1418
+ headerEl.classList[`${this.options.allowClear === true ? 'add' : 'remove'}`]('allow-clear')
1419
+ }
1414
1420
  const el = document.getElementById(`${this.elementId}_items`)
1415
1421
  if (el.childElementCount === 0) {
1416
1422
  this.render()
@@ -1731,10 +1737,11 @@ class WebsyDropdown {
1731
1737
  }
1732
1738
  }
1733
1739
  }
1734
- const item = this.options.items[index]
1740
+ // const item = this.options.items[index]
1741
+ const item = this._originalData[index] || this.options.items[index]
1735
1742
  this.updateHeader(item)
1736
1743
  if (item && this.options.onItemSelected) {
1737
- this.options.onItemSelected(item, this.selectedItems, this.options.items, this.options)
1744
+ this.options.onItemSelected(item, this.selectedItems, this._originalData || this.options.items, this.options)
1738
1745
  }
1739
1746
  if (this.options.closeAfterSelection === true) {
1740
1747
  this.close()
@@ -1742,6 +1749,278 @@ class WebsyDropdown {
1742
1749
  }
1743
1750
  }
1744
1751
 
1752
+ /* global WebsyDesigns GlobalPubSub */
1753
+ class WebsyDragDrop {
1754
+ constructor (elementId, options) {
1755
+ const DEFAULTS = {
1756
+ items: [],
1757
+ orientation: 'horizontal',
1758
+ dropPlaceholder: 'Drop item here'
1759
+ }
1760
+ this.busy = false
1761
+ this.options = Object.assign({}, DEFAULTS, options)
1762
+ this.elementId = elementId
1763
+ if (!elementId) {
1764
+ console.log('No element Id provided for Websy DragDrop')
1765
+ return
1766
+ }
1767
+ const el = document.getElementById(elementId)
1768
+ if (el) {
1769
+ el.innerHTML = `
1770
+ <div id='${this.elementId}_container' class='websy-drag-drop-container ${this.options.orientation}'>
1771
+ <div>
1772
+ </div>
1773
+ `
1774
+ el.addEventListener('click', this.handleClick.bind(this))
1775
+ el.addEventListener('dragstart', this.handleDragStart.bind(this))
1776
+ el.addEventListener('dragover', this.handleDragOver.bind(this))
1777
+ el.addEventListener('dragleave', this.handleDragLeave.bind(this))
1778
+ el.addEventListener('drop', this.handleDrop.bind(this))
1779
+ window.addEventListener('dragend', this.handleDragEnd.bind(this))
1780
+ }
1781
+ else {
1782
+ console.error(`No element found with ID ${this.elementId}`)
1783
+ }
1784
+ GlobalPubSub.subscribe(this.elementId, 'requestForDDItem', this.handleRequestForItem.bind(this))
1785
+ console.log('constructor dd')
1786
+ console.trace()
1787
+ GlobalPubSub.subscribe(this.elementId, 'add', this.addItem.bind(this))
1788
+ this.render()
1789
+ }
1790
+ addItem (data) {
1791
+ if (data.target === this.elementId && this.busy === false) {
1792
+ this.busy = true
1793
+ console.log('adding item to dd')
1794
+ // check that an item with the same id doesn't already exist
1795
+ let index = this.getItemIndex(data.item.id)
1796
+ if (index === -1) {
1797
+ this.options.items.splice(data.index, 0, data.item)
1798
+ const startEl = document.getElementById(`${this.elementId}start_item`)
1799
+ if (startEl) {
1800
+ if (this.options.items.length === 0) {
1801
+ startEl.classList.add('empty')
1802
+ }
1803
+ else {
1804
+ startEl.classList.remove('empty')
1805
+ }
1806
+ }
1807
+ if (this.options.onItemAdded) {
1808
+ this.options.onItemAdded()
1809
+ }
1810
+ }
1811
+ this.busy = false
1812
+ }
1813
+ }
1814
+ createItemHtml (elementId, index, item) {
1815
+ if (!item.id) {
1816
+ item.id = WebsyDesigns.Utils.createIdentity()
1817
+ }
1818
+ let html = `
1819
+ <div id='${item.id}_item' class='websy-dragdrop-item' draggable='true' data-id='${item.id}'>
1820
+ <div id='${item.id}_itemInner' class='websy-dragdrop-item-inner' data-id='${item.id}'>
1821
+ `
1822
+ if (item.component) {
1823
+ html += `<div id='${item.id}_component'></div>`
1824
+ }
1825
+ else {
1826
+ html += `${item.html || item.label || ''}`
1827
+ }
1828
+ html += `
1829
+ </div>
1830
+ <div id='${item.id}_dropZone' class='websy-drop-zone droppable' data-index='${item.id}' data-side='right' data-id='${item.id}' data-placeholder='${this.options.dropPlaceholder}'></div>
1831
+ </div>
1832
+ `
1833
+ return html
1834
+ }
1835
+ getItemIndex (id) {
1836
+ for (let i = 0; i < this.options.items.length; i++) {
1837
+ if (this.options.items[i].id === id) {
1838
+ return i
1839
+ }
1840
+ }
1841
+ return -1
1842
+ }
1843
+ handleClick (event) {
1844
+
1845
+ }
1846
+ handleDragStart (event) {
1847
+ this.draggedId = event.target.getAttribute('data-id')
1848
+ event.dataTransfer.effectAllowed = 'move'
1849
+ event.dataTransfer.setData('application/wd-item', JSON.stringify({el: event.target.id, id: this.elementId, itemId: this.draggedId}))
1850
+ console.log('drag start', event)
1851
+ event.target.style.opacity = 0.5
1852
+ this.dragging = true
1853
+ }
1854
+ handleDragOver (event) {
1855
+ console.log('drag over', event.target.classList)
1856
+ if (event.preventDefault) {
1857
+ event.preventDefault()
1858
+ }
1859
+ if (!event.target.classList.contains('droppable')) {
1860
+ return
1861
+ }
1862
+ event.target.classList.add('drag-over')
1863
+ }
1864
+ handleDragLeave (event) {
1865
+ console.log('drag leave', event.target.classList)
1866
+ if (!event.target.classList.contains('droppable')) {
1867
+ return
1868
+ }
1869
+ event.target.classList.remove('drag-over')
1870
+ // let side = event.target.getAttribute('data-side')
1871
+ // let id = event.target.getAttribute('data-id')
1872
+ // let droppedItem = this.options.items[id]
1873
+ // this.removeExpandedDrop(side, id, droppedItem)
1874
+ }
1875
+ handleDrop (event) {
1876
+ console.log('drag drop')
1877
+ console.log(event.dataTransfer.getData('application/wd-item'))
1878
+ const data = JSON.parse(event.dataTransfer.getData('application/wd-item'))
1879
+ if (event.preventDefault) {
1880
+ event.preventDefault()
1881
+ }
1882
+ if (!event.target.classList.contains('droppable')) {
1883
+ return
1884
+ }
1885
+ let side = event.target.getAttribute('data-side')
1886
+ let id = event.target.getAttribute('data-id')
1887
+ let index = this.getItemIndex(id)
1888
+ let draggedIndex = this.getItemIndex(data.id)
1889
+ let droppedItem = this.options.items[index]
1890
+ if (side === 'right') {
1891
+ index += 1
1892
+ }
1893
+ if (draggedIndex === -1) {
1894
+ console.log('requestForDDItem')
1895
+ GlobalPubSub.publish(data.id, 'requestForDDItem', {
1896
+ group: this.options.group,
1897
+ source: data.id,
1898
+ target: this.elementId,
1899
+ index,
1900
+ id: data.itemId
1901
+ })
1902
+ }
1903
+ else if (index > draggedIndex) {
1904
+ // insert and then remove
1905
+ this.options.items.splice(index, 0, droppedItem)
1906
+ this.options.items.splice(draggedIndex, 1)
1907
+ if (this.options.onOrderUpdated) {
1908
+ this.options.onOrderUpdated()
1909
+ }
1910
+ }
1911
+ else {
1912
+ // remove and then insert
1913
+ this.options.items.splice(draggedIndex, 1)
1914
+ this.options.items.splice(index, 0, droppedItem)
1915
+ if (this.options.onOrderUpdated) {
1916
+ this.options.onOrderUpdated()
1917
+ }
1918
+ }
1919
+ // this.removeExpandedDrop(side, id, droppedItem)
1920
+ // const draggedEl = document.getElementById(`${this.elementId}_${this.draggedId}_item`)
1921
+ const draggedEl = document.getElementById(data.el)
1922
+ const droppedEl = document.getElementById(`${id}_item`)
1923
+ if (draggedEl) {
1924
+ droppedEl.insertAdjacentElement('afterend', draggedEl)
1925
+ }
1926
+ let dragOverEl = droppedEl.querySelector('.drag-over')
1927
+ if (dragOverEl) {
1928
+ dragOverEl.classList.remove('drag-over')
1929
+ }
1930
+ }
1931
+ handleDragEnd (event) {
1932
+ console.log('drag end')
1933
+ event.target.style.opacity = 1
1934
+ this.draggedId = null
1935
+ this.dragging = false
1936
+ const startEl = document.getElementById(`${this.elementId}start_item`)
1937
+ if (startEl) {
1938
+ if (this.options.items.length === 0) {
1939
+ startEl.classList.add('empty')
1940
+ }
1941
+ else {
1942
+ startEl.classList.remove('empty')
1943
+ }
1944
+ }
1945
+ }
1946
+ handleRequestForItem (data) {
1947
+ if (data.group === this.options.group) {
1948
+ let index = this.getItemIndex(data.id)
1949
+ if (index !== -1) {
1950
+ let itemToAdd = this.options.items.splice(index, 1)
1951
+ GlobalPubSub.publish(data.target, 'add', {
1952
+ target: data.target,
1953
+ index: data.index,
1954
+ item: itemToAdd[0]
1955
+ })
1956
+ }
1957
+ }
1958
+ }
1959
+ measureItems () {
1960
+ const el = document.getElementById(`${this.elementId}_container`)
1961
+ this.options.items.forEach(d => {
1962
+
1963
+ })
1964
+ }
1965
+ // removeExpandedDrop (side, id, droppedItem) {
1966
+ // let dropEl
1967
+ // const dropImageEl = document.getElementById(`${id}_itemInner`)
1968
+ // // const placeholderEl = document.getElementById(`${this.elementId}_${id}_dropZonePlaceholder`)
1969
+ // if (side === 'left') {
1970
+ // dropEl = document.getElementById(`${this.elementId}_${id}_dropZoneLeft`)
1971
+ // dropImageEl.style.left = `0px`
1972
+ // }
1973
+ // else if (side === 'right') {
1974
+ // dropEl = document.getElementById(`${this.elementId}_${id}_dropZoneRight`)
1975
+ // }
1976
+ // else {
1977
+ // dropEl = document.getElementById(`${this.elementId}_${id}_dropZoneEnd`)
1978
+ // }
1979
+ // if (dropEl) {
1980
+ // const dropElSize = dropEl.getBoundingClientRect()
1981
+ // dropEl.style.width = `${(dropElSize.width / 2)}px`
1982
+ // dropEl.style.marginLeft = null
1983
+ // dropEl.style.border = null
1984
+ // }
1985
+ // if (placeholderEl) {
1986
+ // placeholderEl.classList.remove('active')
1987
+ // placeholderEl.style.left = null
1988
+ // placeholderEl.style.right = null
1989
+ // placeholderEl.style.width = null
1990
+ // placeholderEl.style.height = null
1991
+ // }
1992
+ // }
1993
+ removeItem (id) {
1994
+
1995
+ }
1996
+ render () {
1997
+ const el = document.getElementById(`${this.elementId}_container`)
1998
+ if (el) {
1999
+ this.measureItems()
2000
+ let html = `
2001
+ <div id='${this.elementId}start_item' class='websy-dragdrop-item ${this.options.items.length === 0 ? 'empty' : ''}' data-id='${this.elementId}start'>
2002
+ <div id='${this.elementId}start_dropZone' class='websy-drop-zone droppable' data-index='start' data-side='start' data-id='${this.elementId}start' data-placeholder='${this.options.dropPlaceholder}'></div>
2003
+ </div>
2004
+ `
2005
+ html += this.options.items.map((d, i) => this.createItemHtml(this.elementId, i, d)).join('')
2006
+ el.innerHTML = html
2007
+ this.options.items.forEach((item, i) => {
2008
+ if (item.component) {
2009
+ if (item.isQlikPlugin && WebsyDesigns.QlikPlugin[item.component]) {
2010
+ item.instance = new WebsyDesigns.QlikPlugin[item.component](`${item.id}_component`, item.options)
2011
+ }
2012
+ else if (WebsyDesigns[item.component]) {
2013
+ item.instance = new WebsyDesigns[item.component](`${item.id}_component`, item.options)
2014
+ }
2015
+ else {
2016
+ console.error(`Component ${item.component} not found.`)
2017
+ }
2018
+ }
2019
+ })
2020
+ }
2021
+ }
2022
+ }
2023
+
1745
2024
  /* global WebsyDesigns FormData grecaptcha ENVIRONMENT GlobalPubSub */
1746
2025
  class WebsyForm {
1747
2026
  constructor (elementId, options) {
@@ -2716,18 +2995,35 @@ class WebsyPubSub {
2716
2995
  this.elementId = elementId
2717
2996
  this.subscriptions = {}
2718
2997
  }
2719
- publish (method, data) {
2720
- if (this.subscriptions[method]) {
2721
- this.subscriptions[method].forEach(fn => {
2722
- fn(data)
2723
- })
2998
+ publish (id, method, data) {
2999
+ if (arguments.length === 3) {
3000
+ if (this.subscriptions[id] && this.subscriptions[id][method]) {
3001
+ this.subscriptions[id][method](data)
3002
+ }
3003
+ }
3004
+ else {
3005
+ if (this.subscriptions[method]) {
3006
+ this.subscriptions[method].forEach(fn => {
3007
+ fn(data)
3008
+ })
3009
+ }
2724
3010
  }
2725
3011
  }
2726
- subscribe (method, fn) {
2727
- if (!this.subscriptions[method]) {
2728
- this.subscriptions[method] = []
3012
+ subscribe (id, method, fn) {
3013
+ if (arguments.length === 3) {
3014
+ if (!this.subscriptions[id]) {
3015
+ this.subscriptions[id] = {}
3016
+ }
3017
+ if (!this.subscriptions[id][method]) {
3018
+ this.subscriptions[id][method] = fn
3019
+ }
3020
+ }
3021
+ else {
3022
+ if (!this.subscriptions[method]) {
3023
+ this.subscriptions[method] = []
3024
+ }
3025
+ this.subscriptions[method].push(fn)
2729
3026
  }
2730
- this.subscriptions[method].push(fn)
2731
3027
  }
2732
3028
  }
2733
3029
 
@@ -4881,7 +5177,12 @@ class WebsyTable2 {
4881
5177
  }
4882
5178
  }
4883
5179
  hideLoading () {
4884
- this.loadingDialog.hide()
5180
+ if (this.options.onLoading) {
5181
+ this.options.onLoading(false)
5182
+ }
5183
+ else {
5184
+ this.loadingDialog.hide()
5185
+ }
4885
5186
  }
4886
5187
  internalSort (column, colIndex) {
4887
5188
  this.options.columns.forEach((c, i) => {
@@ -4956,7 +5257,8 @@ class WebsyTable2 {
4956
5257
  class="tableHeaderField ${['asc', 'desc'].indexOf(c.sort) !== -1 ? 'sortable-column' : ''}"
4957
5258
  data-sort-index="${c.sortIndex || i}"
4958
5259
  data-index="${i}"
4959
- data-sort="${c.sort}"
5260
+ data-sort="${c.sort}"
5261
+ style="${c.style || ''}"
4960
5262
  >
4961
5263
  ${c.name}
4962
5264
  </div>
@@ -5058,7 +5360,12 @@ class WebsyTable2 {
5058
5360
  }
5059
5361
  }
5060
5362
  showLoading (options) {
5061
- this.loadingDialog.show(options)
5363
+ if (this.options.onLoading) {
5364
+ this.options.onLoading(true)
5365
+ }
5366
+ else {
5367
+ this.loadingDialog.show(options)
5368
+ }
5062
5369
  }
5063
5370
  getColumnParameters (values) {
5064
5371
  const tableEl = document.getElementById(`${this.elementId}_table`)
@@ -5122,6 +5429,555 @@ class WebsyTable2 {
5122
5429
  }
5123
5430
  }
5124
5431
 
5432
+ /* global WebsyDesigns */
5433
+ class WebsyTable3 {
5434
+ constructor (elementId, options) {
5435
+ this.elementId = elementId
5436
+ const DEFAULTS = {
5437
+ virtualScroll: false,
5438
+ showTotalsAbove: true,
5439
+ minHandleSize: 20,
5440
+ maxColWidth: '50%',
5441
+ allowPivoting: false
5442
+ }
5443
+ this.options = Object.assign({}, DEFAULTS, options)
5444
+ this.sizes = {}
5445
+ this.scrollDragging = false
5446
+ this.cellDragging = false
5447
+ this.vScrollRequired = false
5448
+ this.hScrollRequired = false
5449
+ this.pinnedColumns = 0
5450
+ this.startRow = 0
5451
+ this.endRow = 0
5452
+ this.startCol = 0
5453
+ this.endCol = 0
5454
+ this.mouseYStart = 0
5455
+ this.mouseYStart = 0
5456
+ if (!elementId) {
5457
+ console.log('No element Id provided for Websy Table')
5458
+ return
5459
+ }
5460
+ const el = document.getElementById(this.elementId)
5461
+ if (el) {
5462
+ let html = `
5463
+ <div id='${this.elementId}_tableContainer' class='websy-vis-table-3 ${this.options.paging === 'pages' ? 'with-paging' : ''} ${this.options.virtualScroll === true ? 'with-virtual-scroll' : ''}'>
5464
+ <!--<div class="download-button">
5465
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M16 11h5l-9 10-9-10h5v-11h8v11zm1 11h-10v2h10v-2z"/></svg>
5466
+ </div>-->
5467
+ <div id="${this.elementId}_tableInner" class="websy-table-inner-container">
5468
+ <table id="${this.elementId}_tableHeader" class="websy-table-header"></table>
5469
+ <table id="${this.elementId}_tableBody" class="websy-table-body"></table>
5470
+ <table id="${this.elementId}_tableFooter" class="websy-table-footer"></table>
5471
+ <div id="${this.elementId}_vScrollContainer" class="websy-v-scroll-container">
5472
+ <div id="${this.elementId}_vScrollHandle" class="websy-scroll-handle websy-scroll-handle-y"></div>
5473
+ </div>
5474
+ <div id="${this.elementId}_hScrollContainer" class="websy-h-scroll-container">
5475
+ <div id="${this.elementId}_hScrollHandle" class="websy-scroll-handle websy-scroll-handle-x"></div>
5476
+ </div>
5477
+ </div>
5478
+ <div id="${this.elementId}_errorContainer" class='websy-vis-error-container'>
5479
+ <div>
5480
+ <div id="${this.elementId}_errorTitle"></div>
5481
+ <div id="${this.elementId}_errorMessage"></div>
5482
+ </div>
5483
+ </div>
5484
+ <div id="${this.elementId}_dropdownContainer"></div>
5485
+ <div id="${this.elementId}_loadingContainer"></div>
5486
+ </div>
5487
+ `
5488
+ if (this.options.paging === 'pages') {
5489
+ html += `
5490
+ <div class="websy-table-paging-container">
5491
+ Show <div id="${this.elementId}_pageSizeSelector" class="websy-vis-page-selector"></div> rows
5492
+ <ul id="${this.elementId}_pageList" class="websy-vis-page-list"></ul>
5493
+ </div>
5494
+ `
5495
+ }
5496
+ el.innerHTML = html
5497
+ el.addEventListener('click', this.handleClick.bind(this))
5498
+ el.addEventListener('mousedown', this.handleMouseDown.bind(this))
5499
+ window.addEventListener('mousemove', this.handleMouseMove.bind(this))
5500
+ window.addEventListener('mouseup', this.handleMouseUp.bind(this))
5501
+ let scrollEl = document.getElementById(`${this.elementId}_tableBody`)
5502
+ if (scrollEl) {
5503
+ scrollEl.addEventListener('wheel', this.handleScrollWheel.bind(this))
5504
+ }
5505
+ this.loadingDialog = new WebsyDesigns.LoadingDialog(`${this.elementId}_loadingContainer`)
5506
+ this.render(this.options.data)
5507
+ }
5508
+ else {
5509
+ console.error(`No element found with ID ${this.elementId}`)
5510
+ }
5511
+ }
5512
+ set columns (columns) {
5513
+ this.options.columns = columns
5514
+ this.renderColumnHeaders()
5515
+ }
5516
+ set totals (totals) {
5517
+ this.options.totals = totals
5518
+ this.renderTotals()
5519
+ }
5520
+ appendRows (data) {
5521
+ this.hideError()
5522
+ let bodyEl = document.getElementById(`${this.elementId}_tableBody`)
5523
+ if (bodyEl) {
5524
+ if (this.options.virtualScroll === true) {
5525
+ bodyEl.innerHTML = this.buildBodyHtml(data, true)
5526
+ }
5527
+ else {
5528
+ bodyEl.innerHTML += this.buildBodyHtml(data, true)
5529
+ }
5530
+ }
5531
+ // this.data = this.data.concat(data)
5532
+ // this.rowCount = this.data.length
5533
+ }
5534
+ buildBodyHtml (data = [], useWidths = false) {
5535
+ if (data.length === 0) {
5536
+ return ''
5537
+ }
5538
+ let bodyHtml = ``
5539
+ let sizingColumns = this.options.columns[this.options.columns.length - 1]
5540
+ if (useWidths === true) {
5541
+ bodyHtml += '<colgroup>'
5542
+ bodyHtml += sizingColumns.map(c => `
5543
+ <col
5544
+ style='width: ${c.width || c.actualWidth}px!important'
5545
+ ></col>
5546
+ `).join('')
5547
+ bodyHtml += '</colgroup>'
5548
+ }
5549
+ data.forEach(row => {
5550
+ bodyHtml += `<tr class="websy-table-row">`
5551
+ row.forEach((cell, cellIndex) => {
5552
+ bodyHtml += `<td
5553
+ class='websy-table-cell'
5554
+ style='${cell.style}'
5555
+ data-info='${cell.value}'
5556
+ colspan='${cell.colspan || 1}'
5557
+ rowspan='${cell.rowspan || 1}'
5558
+ `
5559
+ // if (useWidths === true) {
5560
+ // bodyHtml += `
5561
+ // style='width: ${sizingColumns[cellIndex].width || sizingColumns[cellIndex].actualWidth}px!important'
5562
+ // width='${sizingColumns[cellIndex].width || sizingColumns[cellIndex].actualWidth}'
5563
+ // `
5564
+ // }
5565
+ bodyHtml += `
5566
+ >
5567
+ ${cell.value}
5568
+ </td>`
5569
+ })
5570
+ bodyHtml += `</tr>`
5571
+ })
5572
+ // bodyHtml += `</div>`
5573
+ return bodyHtml
5574
+ }
5575
+ buildHeaderHtml (useWidths = false) {
5576
+ let headerHtml = ''
5577
+ let sizingColumns = this.options.columns[this.options.columns.length - 1]
5578
+ if (useWidths === true) {
5579
+ headerHtml += '<colgroup>'
5580
+ headerHtml += sizingColumns.map(c => `
5581
+ <col
5582
+ style='width: ${c.width || c.actualWidth}px!important'
5583
+ ></col>
5584
+ `).join('')
5585
+ headerHtml += '</colgroup>'
5586
+ }
5587
+ this.options.columns.forEach((row, rowIndex) => {
5588
+ if (useWidths === false && rowIndex !== this.options.columns.length - 1) {
5589
+ // if we're calculating the size we only want to render the last row of column headers
5590
+ return
5591
+ }
5592
+ headerHtml += `<tr class="websy-table-row websy-table-header-row">`
5593
+ row.forEach(col => {
5594
+ headerHtml += `<td
5595
+ class='websy-table-cell'
5596
+ style='${col.style}'
5597
+ colspan='${col.colspan || 1}'
5598
+ rowspan='${col.rowspan || 1}'
5599
+ `
5600
+ // if (useWidths === true && rowIndex === this.options.columns.length - 1) {
5601
+ // headerHtml += `
5602
+ // style='width: ${col.width || col.actualWidth}px'
5603
+ // width='${col.width || col.actualWidth}'
5604
+ // `
5605
+ // }
5606
+ headerHtml += `
5607
+ >
5608
+ ${col.name}
5609
+ </td>`
5610
+ })
5611
+ headerHtml += `</tr>`
5612
+ })
5613
+ return headerHtml
5614
+ }
5615
+ buildTotalHtml (useWidths = false) {
5616
+ if (!this.options.totals) {
5617
+ return ''
5618
+ }
5619
+ let totalHtml = `<tr class="websy-table-row websy-table-total-row">`
5620
+ this.options.totals.forEach((col, colIndex) => {
5621
+ totalHtml += `<td
5622
+ class='websy-table-cell'
5623
+ colspan='${col.colspan || 1}'
5624
+ rowspan='${col.rowspan || 1}'
5625
+ `
5626
+ if (useWidths === true) {
5627
+ totalHtml += `
5628
+ style='width: ${this.options.columns[this.options.columns.length - 1][colIndex].width || this.options.columns[this.options.columns.length - 1][colIndex].actualWidth}px'
5629
+ width='${col.width || col.actualWidth}'
5630
+ `
5631
+ }
5632
+ totalHtml += `
5633
+ >
5634
+ ${col.value}
5635
+ </td>`
5636
+ })
5637
+ totalHtml += `</tr>`
5638
+ return totalHtml
5639
+ }
5640
+ calculateSizes (sample = [], totalRowCount, totalColumnCount, pinnedColumns) {
5641
+ this.totalRowCount = totalRowCount // probably need some error handling here if no value is passed in
5642
+ this.totalColumnCount = totalColumnCount // probably need some error handling here if no value is passed in
5643
+ this.pinnedColumns = pinnedColumns // probably need some error handling here if no value is passed in
5644
+ let outerEl = document.getElementById(this.elementId)
5645
+ let tableEl = document.getElementById(`${this.elementId}_tableContainer`)
5646
+ let headEl = document.getElementById(`${this.elementId}_tableHeader`)
5647
+ headEl.style.width = 'auto'
5648
+ headEl.innerHTML = this.buildHeaderHtml()
5649
+ this.sizes.outer = outerEl.getBoundingClientRect()
5650
+ this.sizes.table = tableEl.getBoundingClientRect()
5651
+ this.sizes.header = headEl.getBoundingClientRect()
5652
+ let maxWidth
5653
+ if (typeof this.options.maxColWidth === 'number') {
5654
+ maxWidth = this.options.maxColWidth
5655
+ }
5656
+ else if (this.options.maxColWidth.indexOf('%') !== -1) {
5657
+ maxWidth = this.sizes.outer.width * (+(this.options.maxColWidth.replace('%', '')) / 100)
5658
+ }
5659
+ else if (this.options.maxColWidth.indexOf('px') !== -1) {
5660
+ maxWidth = +this.options.maxColWidth.replace('px', '')
5661
+ }
5662
+ let bodyEl = document.getElementById(`${this.elementId}_tableBody`)
5663
+ bodyEl.style.width = 'auto'
5664
+ bodyEl.innerHTML = this.buildBodyHtml([sample])
5665
+ let footerEl = document.getElementById(`${this.elementId}_tableFooter`)
5666
+ footerEl.innerHTML = this.buildTotalHtml()
5667
+ this.sizes.total = footerEl.getBoundingClientRect()
5668
+ const rows = Array.from(tableEl.querySelectorAll('.websy-table-row'))
5669
+ let totalWidth = 0
5670
+ this.sizes.scrollableWidth = this.sizes.outer.width
5671
+ rows.forEach((row, rowIndex) => {
5672
+ Array.from(row.children).forEach((col, colIndex) => {
5673
+ let colSize = col.getBoundingClientRect()
5674
+ this.sizes.cellHeight = colSize.height
5675
+ if (this.options.columns[this.options.columns.length - 1][colIndex]) {
5676
+ if (!this.options.columns[this.options.columns.length - 1][colIndex].actualWidth) {
5677
+ this.options.columns[this.options.columns.length - 1][colIndex].actualWidth = 0
5678
+ }
5679
+ this.options.columns[this.options.columns.length - 1][colIndex].actualWidth = Math.min(Math.max(this.options.columns[this.options.columns.length - 1][colIndex].actualWidth, colSize.width), maxWidth)
5680
+ this.options.columns[this.options.columns.length - 1][colIndex].cellHeight = colSize.height
5681
+ }
5682
+ })
5683
+ })
5684
+ this.options.columns[this.options.columns.length - 1].forEach((col, colIndex) => {
5685
+ if (colIndex < this.pinnedColumns) {
5686
+ this.sizes.scrollableWidth -= col.actualWidth
5687
+ }
5688
+ })
5689
+ this.sizes.totalWidth = this.options.columns[this.options.columns.length - 1].reduce((a, b) => a + (b.width || b.actualWidth), 0)
5690
+ const outerSize = outerEl.getBoundingClientRect()
5691
+ if (this.sizes.totalWidth < outerSize.width) {
5692
+ this.sizes.totalWidth = 0
5693
+ let equalWidth = outerSize.width / this.options.columns[this.options.columns.length - 1].length
5694
+ this.options.columns[this.options.columns.length - 1].forEach((c, i) => {
5695
+ if (!c.width) {
5696
+ if (c.actualWidth < equalWidth) {
5697
+ // adjust the width
5698
+ c.actualWidth = equalWidth
5699
+ }
5700
+ }
5701
+ this.sizes.totalWidth += c.width || c.actualWidth
5702
+ equalWidth = (outerSize.width - this.sizes.totalWidth) / (this.options.columns[this.options.columns.length - 1].length - (i + 1))
5703
+ })
5704
+ }
5705
+ // take the height of the last cell as the official height for data cells
5706
+ // this.sizes.dataCellHeight = this.options.columns[this.options.columns.length - 1].cellHeight
5707
+ headEl.innerHTML = ''
5708
+ bodyEl.innerHTML = ''
5709
+ footerEl.innerHTML = ''
5710
+ headEl.style.width = 'initial'
5711
+ bodyEl.style.width = 'initial'
5712
+ this.sizes.bodyHeight = this.sizes.table.height - (this.sizes.header.height + this.sizes.total.height)
5713
+ this.sizes.rowsToRender = Math.ceil(this.sizes.bodyHeight / this.sizes.cellHeight)
5714
+ this.sizes.rowsToRenderPrecise = this.sizes.bodyHeight / this.sizes.cellHeight
5715
+ this.startRow = 0
5716
+ this.endRow = this.sizes.rowsToRender
5717
+ this.startCol = 0
5718
+ this.endCol = this.options.columns[this.options.columns.length - 1].length
5719
+ if (this.sizes.rowsToRender < this.totalRowCount) {
5720
+ this.vScrollRequired = true
5721
+ }
5722
+ if (this.sizes.totalWidth > this.sizes.outer.width) {
5723
+ this.hScrollRequired = true
5724
+ }
5725
+ this.options.allColumns = this.options.columns.map(c => c)
5726
+ console.log('sizes', this.sizes)
5727
+ return this.sizes
5728
+ }
5729
+ createSample (data) {
5730
+ let output = []
5731
+ this.options.columns[this.options.columns.length - 1].forEach((col, colIndex) => {
5732
+ if (col.maxLength) {
5733
+ output.push({value: new Array(col.maxLength).fill('W').join('')})
5734
+ }
5735
+ else if (data) {
5736
+ let longest = ''
5737
+ for (let i = 0; i < Math.min(data.length, 1000); i++) {
5738
+ if (longest.length < data[i][colIndex].value.length) {
5739
+ longest = data[i][colIndex].value
5740
+ }
5741
+ }
5742
+ output.push({value: longest})
5743
+ }
5744
+ else {
5745
+ output.push({value: ''})
5746
+ }
5747
+ })
5748
+ return output
5749
+ }
5750
+ handleClick (event) {
5751
+
5752
+ }
5753
+ handleMouseDown (event) {
5754
+ if (event.target.classList.contains('websy-scroll-handle-y')) {
5755
+ // set up the scroll start values
5756
+ this.scrollDragging = true
5757
+ this.scrollDirection = 'y'
5758
+ const scrollHandleEl = document.getElementById(`${this.elementId}_vScrollHandle`)
5759
+ this.handleYStart = scrollHandleEl.offsetTop
5760
+ this.mouseYStart = event.pageY
5761
+ console.log('mouse down', this.handleYStart, this.mouseYStart)
5762
+ console.log(scrollHandleEl.offsetTop)
5763
+ }
5764
+ else if (event.target.classList.contains('websy-scroll-handle-x')) {
5765
+ this.scrollDragging = true
5766
+ this.scrollDirection = 'x'
5767
+ const scrollHandleEl = document.getElementById(`${this.elementId}_hScrollHandle`)
5768
+ this.handleXStart = scrollHandleEl.offsetLeft
5769
+ this.mouseXStart = event.pageX
5770
+ }
5771
+ }
5772
+ handleMouseMove (event) {
5773
+ // event.preventDefault()
5774
+ if (this.scrollDragging === true) {
5775
+ if (this.scrollDirection === 'y') {
5776
+ const diff = event.pageY - this.mouseYStart
5777
+ this.scrollY(diff)
5778
+ }
5779
+ else if (this.scrollDirection === 'x') {
5780
+ const diff = event.pageX - this.mouseXStart
5781
+ this.scrollX(diff)
5782
+ }
5783
+ }
5784
+ }
5785
+ handleMouseUp (event) {
5786
+ this.scrollDragging = false
5787
+ this.cellDragging = false
5788
+ this.handleYStart = null
5789
+ this.mouseYStart = null
5790
+ this.handleXStart = null
5791
+ this.mouseXStart = null
5792
+ }
5793
+ handleScrollWheel (event) {
5794
+ event.preventDefault()
5795
+ console.log('scrollwheel', event)
5796
+ if (Math.abs(event.deltaX) > Math.abs(event.deltaY)) {
5797
+ this.scrollX(Math.max(-5, Math.min(5, event.deltaX)))
5798
+ }
5799
+ else {
5800
+ this.scrollY(Math.max(-5, Math.min(5, event.deltaY)))
5801
+ }
5802
+ }
5803
+ hideError () {
5804
+ const el = document.getElementById(`${this.elementId}_tableContainer`)
5805
+ if (el) {
5806
+ el.classList.remove('has-error')
5807
+ }
5808
+ const tableEl = document.getElementById(`${this.elementId}_tableInner`)
5809
+ tableEl.classList.remove('hidden')
5810
+ const containerEl = document.getElementById(`${this.elementId}_errorContainer`)
5811
+ if (containerEl) {
5812
+ containerEl.classList.remove('active')
5813
+ }
5814
+ }
5815
+ hideLoading () {
5816
+ this.loadingDialog.hide()
5817
+ }
5818
+ render (data, calcSizes = true) {
5819
+ if (!this.options.columns) {
5820
+ console.log(`No columns provided for table with ID ${this.elementId}`)
5821
+ return
5822
+ }
5823
+ if (this.options.columns.length === 0) {
5824
+ console.log(`No columns provided for table with ID ${this.elementId}`)
5825
+ return
5826
+ }
5827
+ // this.data = []
5828
+ // Adjust the sizing of the header/body/footer
5829
+ if (calcSizes === true) {
5830
+ const sample = this.createSample(data)
5831
+ this.calculateSizes(sample, data.length, (data[0] || []).length, 0)
5832
+ }
5833
+ console.log(this.options.columns)
5834
+ const tableInnerEl = document.getElementById(`${this.elementId}_tableInner`)
5835
+ if (tableInnerEl) {
5836
+ tableInnerEl.style.width = `${this.sizes.totalWidth}px`
5837
+ }
5838
+ this.renderColumnHeaders()
5839
+ this.renderTotals()
5840
+ if (data) {
5841
+ this.appendRows(data)
5842
+ }
5843
+ let bodyEl = document.getElementById(`${this.elementId}_tableBody`)
5844
+ // bodyEl.innerHTML = this.buildBodyHtml(data, true)
5845
+ bodyEl.style.height = `calc(100% - ${this.sizes.header.height}px - ${this.sizes.total.height}px)`
5846
+ if (this.options.virtualScroll === true) {
5847
+ // set the scroll element positions
5848
+ if (this.vScrollRequired === true) {
5849
+ let vScrollEl = document.getElementById(`${this.elementId}_vScrollContainer`)
5850
+ let vHandleEl = document.getElementById(`${this.elementId}_vScrollHandle`)
5851
+ vScrollEl.style.top = `${this.sizes.header.height + this.sizes.total.height}px`
5852
+ vScrollEl.style.height = `${this.sizes.bodyHeight}px`
5853
+ vHandleEl.style.height = Math.max(this.options.minHandleSize, this.sizes.bodyHeight * (this.sizes.rowsToRenderPrecise / this.totalRowCount)) + 'px'
5854
+ }
5855
+ if (this.hScrollRequired === true) {
5856
+ let hScrollEl = document.getElementById(`${this.elementId}_hScrollContainer`)
5857
+ let hHandleEl = document.getElementById(`${this.elementId}_hScrollHandle`)
5858
+ hScrollEl.style.left = `${this.sizes.table.width - this.sizes.scrollableWidth}px`
5859
+ hScrollEl.style.width = `${this.sizes.scrollableWidth - 20}px`
5860
+ hHandleEl.style.width = Math.max(this.options.minHandleSize, this.sizes.scrollableWidth * (this.sizes.scrollableWidth / this.sizes.totalWidth)) + 'px'
5861
+ }
5862
+ }
5863
+ }
5864
+ renderColumnHeaders () {
5865
+ let headEl = document.getElementById(`${this.elementId}_tableHeader`)
5866
+ if (headEl) {
5867
+ headEl.innerHTML = this.buildHeaderHtml(true)
5868
+ }
5869
+ }
5870
+ renderTotals () {
5871
+ let headEl = document.getElementById(`${this.elementId}_tableHeader`)
5872
+ let totalHtml = this.buildTotalHtml(true)
5873
+ if (this.options.showTotalsAbove === true) {
5874
+ headEl.innerHTML += totalHtml
5875
+ }
5876
+ else {
5877
+ const footerEl = document.getElementById(`${this.elementId}_tableFooter`)
5878
+ if (footerEl) {
5879
+ footerEl.innerHTML = totalHtml
5880
+ }
5881
+ }
5882
+ }
5883
+ resize () {
5884
+
5885
+ }
5886
+ showError (options) {
5887
+ const el = document.getElementById(`${this.elementId}_tableContainer`)
5888
+ if (el) {
5889
+ el.classList.add('has-error')
5890
+ }
5891
+ const tableEl = document.getElementById(`${this.elementId}_tableInner`)
5892
+ tableEl.classList.add('hidden')
5893
+ const containerEl = document.getElementById(`${this.elementId}_errorContainer`)
5894
+ if (containerEl) {
5895
+ containerEl.classList.add('active')
5896
+ }
5897
+ if (options.title) {
5898
+ const titleEl = document.getElementById(`${this.elementId}_errorTitle`)
5899
+ if (titleEl) {
5900
+ titleEl.innerHTML = options.title
5901
+ }
5902
+ }
5903
+ if (options.message) {
5904
+ const messageEl = document.getElementById(`${this.elementId}_errorMessage`)
5905
+ if (messageEl) {
5906
+ messageEl.innerHTML = options.message
5907
+ }
5908
+ }
5909
+ }
5910
+ scrollX (diff) {
5911
+ const scrollContainerEl = document.getElementById(`${this.elementId}_hScrollContainer`)
5912
+ const scrollHandleEl = document.getElementById(`${this.elementId}_hScrollHandle`)
5913
+ let handlePos
5914
+ if (typeof this.handleXStart !== 'undefined' && this.handleXStart !== null) {
5915
+ handlePos = this.handleXStart + diff
5916
+ }
5917
+ else {
5918
+ handlePos = scrollHandleEl.offsetLeft + diff
5919
+ }
5920
+ const scrollableSpace = scrollContainerEl.getBoundingClientRect().width - scrollHandleEl.getBoundingClientRect().width
5921
+ console.log('dragging x', diff, scrollContainerEl.getBoundingClientRect().width - scrollHandleEl.getBoundingClientRect().width)
5922
+ scrollHandleEl.style.left = Math.min(scrollableSpace, Math.max(0, handlePos)) + 'px'
5923
+ if (this.options.onScroll) {
5924
+ let actualLeft = (this.sizes.totalWidth - this.sizes.scrollableWidth) * (Math.min(scrollableSpace, Math.max(0, handlePos)) / scrollableSpace)
5925
+ let cumulativeWidth = 0
5926
+ this.startCol = 0
5927
+ this.endCol = 0
5928
+ for (let i = 0; i < this.options.allColumns[this.options.allColumns.length - 1].length; i++) {
5929
+ cumulativeWidth += this.options.allColumns[this.options.allColumns.length - 1][i].actualWidth
5930
+ console.log(actualLeft, this.sizes.totalWidth, cumulativeWidth, cumulativeWidth + this.options.allColumns[this.options.allColumns.length - 1][i].actualWidth)
5931
+ if (actualLeft < cumulativeWidth) {
5932
+ this.startCol = i
5933
+ break
5934
+ }
5935
+ }
5936
+ cumulativeWidth = 0
5937
+ for (let i = this.startCol; i < this.options.allColumns[this.options.allColumns.length - 1].length; i++) {
5938
+ cumulativeWidth += this.options.allColumns[this.options.allColumns.length - 1][i].actualWidth
5939
+ if (cumulativeWidth < this.sizes.scrollableWidth) {
5940
+ this.endCol = i
5941
+ }
5942
+ }
5943
+ if (this.endCol < this.options.allColumns[this.options.allColumns.length - 1].length - 1) {
5944
+ this.endCol += 1
5945
+ }
5946
+ if (this.endCol === this.options.allColumns[this.options.allColumns.length - 1].length - 1 && cumulativeWidth > this.sizes.totalWidth) {
5947
+ this.startCol += 1
5948
+ }
5949
+ this.endCol = Math.max(this.startCol, this.endCol)
5950
+ this.options.onScroll('y', this.startRow, this.endRow, this.startCol, this.endCol)
5951
+ }
5952
+ }
5953
+ scrollY (diff) {
5954
+ const scrollContainerEl = document.getElementById(`${this.elementId}_vScrollContainer`)
5955
+ const scrollHandleEl = document.getElementById(`${this.elementId}_vScrollHandle`)
5956
+ let handlePos
5957
+ if (typeof this.handleYStart !== 'undefined' && this.handleYStart !== null) {
5958
+ handlePos = this.handleYStart + diff
5959
+ }
5960
+ else {
5961
+ console.log('appending not resetting')
5962
+ handlePos = scrollHandleEl.offsetTop + diff
5963
+ }
5964
+ const scrollableSpace = scrollContainerEl.getBoundingClientRect().height - scrollHandleEl.getBoundingClientRect().height
5965
+ console.log('dragging y', (diff), scrollContainerEl.getBoundingClientRect().height - scrollHandleEl.getBoundingClientRect().height)
5966
+ scrollHandleEl.style.top = Math.min(scrollableSpace, Math.max(0, handlePos)) + 'px'
5967
+ if (this.options.onScroll) {
5968
+ this.startRow = Math.min(this.totalRowCount - this.sizes.rowsToRender, Math.max(0, Math.round((this.totalRowCount - this.sizes.rowsToRender) * (handlePos / scrollableSpace))))
5969
+ this.endRow = this.startRow + this.sizes.rowsToRender
5970
+ if (this.endRow === this.totalRowCount) {
5971
+ this.startRow += 1
5972
+ }
5973
+ this.options.onScroll('y', this.startRow, this.endRow, this.startCol, this.endCol)
5974
+ }
5975
+ }
5976
+ showLoading (options) {
5977
+ this.loadingDialog.show(options)
5978
+ }
5979
+ }
5980
+
5125
5981
  /* global d3 include WebsyDesigns */
5126
5982
  class WebsyChart {
5127
5983
  constructor (elementId, options) {
@@ -6046,7 +6902,7 @@ bars
6046
6902
  .attr('x', getBarX.bind(this))
6047
6903
  .attr('y', getBarY.bind(this))
6048
6904
  .transition(this.transition)
6049
- .attr('fill', series.color)
6905
+ .attr('fill', d => d.color || series.color)
6050
6906
 
6051
6907
  bars
6052
6908
  .enter()
@@ -6056,7 +6912,7 @@ bars
6056
6912
  .attr('x', getBarX.bind(this))
6057
6913
  .attr('y', getBarY.bind(this))
6058
6914
  // .transition(this.transition)
6059
- .attr('fill', series.color)
6915
+ .attr('fill', d => d.color || series.color)
6060
6916
  .attr('class', d => {
6061
6917
  return `bar bar_${series.key}`
6062
6918
  })
@@ -6086,7 +6942,7 @@ if (this.options.showLabels) {
6086
6942
  .attr('y', getLabelY.bind(this))
6087
6943
  .attr('class', `label_${series.key}`)
6088
6944
  .style('font-size', `${this.options.labelSize || this.options.fontSize}px`)
6089
- .style('fill', this.options.labelColor || WebsyDesigns.WebsyUtils.getLightDark(series.color))
6945
+ .style('fill', d => this.options.labelColor || WebsyDesigns.WebsyUtils.getLightDark(d.color || series.color))
6090
6946
  .transition(this.transition)
6091
6947
  .text(d => d.y.label || d.y.value)
6092
6948
 
@@ -6099,7 +6955,7 @@ if (this.options.showLabels) {
6099
6955
  .attr('alignment-baseline', 'central')
6100
6956
  .attr('text-anchor', this.options.orientation === 'horizontal' ? 'left' : 'middle')
6101
6957
  .style('font-size', `${this.options.labelSize || this.options.fontSize}px`)
6102
- .style('fill', this.options.labelColor || WebsyDesigns.WebsyUtils.getLightDark(series.color))
6958
+ .style('fill', d => this.options.labelColor || WebsyDesigns.WebsyUtils.getLightDark(d.color || series.color))
6103
6959
  .text(d => d.y.label || d.y.value)
6104
6960
  .each(function (d, i) {
6105
6961
  if (that.options.orientation === 'horizontal') {
@@ -6805,8 +7661,10 @@ const WebsyDesigns = {
6805
7661
  Router: WebsyRouter,
6806
7662
  WebsyTable,
6807
7663
  WebsyTable2,
7664
+ WebsyTable3,
6808
7665
  Table: WebsyTable,
6809
7666
  Table2: WebsyTable2,
7667
+ Table3: WebsyTable3,
6810
7668
  WebsyChart,
6811
7669
  Chart: WebsyChart,
6812
7670
  WebsyChartTooltip,
@@ -6833,7 +7691,9 @@ const WebsyDesigns = {
6833
7691
  WebsySignup,
6834
7692
  Signup: WebsySignup,
6835
7693
  ResponsiveText,
6836
- WebsyResponsiveText: ResponsiveText
7694
+ WebsyResponsiveText: ResponsiveText,
7695
+ WebsyDragDrop,
7696
+ DragDrop: WebsyDragDrop
6837
7697
  }
6838
7698
 
6839
7699
  WebsyDesigns.service = new WebsyDesigns.APIService('')