@websy/websy-designs 1.3.4 → 1.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1321,9 +1321,9 @@ class WebsyDropdown {
1321
1321
  showCompleteSelectedList: false,
1322
1322
  closeAfterSelection: true,
1323
1323
  customActions: [],
1324
- searchIcon: `<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>`,
1325
- clearIcon: `<svg class='clear' xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 512 512"><title>ionicons-v5-l</title><line x1="368" y1="368" x2="144" y2="144" style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/><line x1="368" y1="144" x2="144" y2="368" style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/></svg>`,
1326
- arrowIcon: `<svg class='arrow' xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M23.677 18.52c.914 1.523-.183 3.472-1.967 3.472h-19.414c-1.784 0-2.881-1.949-1.967-3.472l9.709-16.18c.891-1.483 3.041-1.48 3.93 0l9.709 16.18z"/></svg>`,
1324
+ searchIcon: `<svg 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>`,
1325
+ clearIcon: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 512 512"><title>ionicons-v5-l</title><line x1="368" y1="368" x2="144" y2="144" style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/><line x1="368" y1="144" x2="144" y2="368" style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/></svg>`,
1326
+ arrowIcon: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M23.677 18.52c.914 1.523-.183 3.472-1.967 3.472h-19.414c-1.784 0-2.881-1.949-1.967-3.472l9.709-16.18c.891-1.483 3.041-1.48 3.93 0l9.709 16.18z"/></svg>`,
1327
1327
  actionsIcon: `<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>`
1328
1328
  }
1329
1329
  this.options = Object.assign({}, DEFAULTS, options)
@@ -1352,16 +1352,20 @@ class WebsyDropdown {
1352
1352
  let html = `
1353
1353
  <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' : ''}'>
1354
1354
  <div id='${this.elementId}_header' class='websy-dropdown-header ${this.selectedItems.length === 1 ? 'one-selected' : ''} ${this.options.allowClear === true ? 'allow-clear' : ''}'>
1355
- ${this.options.searchIcon}
1356
- <span>
1355
+ `
1356
+ if (this.options.disableSearch !== true) {
1357
+ html += `<div class='search'>${this.options.searchIcon}</div>`
1358
+ }
1359
+ html += `
1360
+ <div class='header-label'>
1357
1361
  <span class='websy-dropdown-header-value' data-info='${headerLabel}' id='${this.elementId}_selectedItems'>${headerLabel}</span>
1358
1362
  <span class='websy-dropdown-header-label' id='${this.elementId}_headerLabel'>${this.options.label}</span>
1359
- </span>
1363
+ </div>
1360
1364
  <input class='dropdown-input' id='${this.elementId}_input' name='${this.options.field || this.options.label}' value='${headerValue}'>
1361
- ${this.options.arrowIcon}
1365
+ <div class='arrow'>${this.options.arrowIcon}</div>
1362
1366
  `
1363
1367
  if (this.options.allowClear === true) {
1364
- html += this.options.clearIcon
1368
+ html += `<div class='clear'>${this.options.clearIcon}</div>`
1365
1369
  }
1366
1370
  html += `
1367
1371
  </div>
@@ -2326,7 +2330,7 @@ const WebsyIcons = {
2326
2330
  `,
2327
2331
  'bag-icon': `
2328
2332
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
2329
- viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
2333
+ viewBox="0 0 500 500">
2330
2334
  <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
2331
2335
  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
2332
2336
  H82.8L46.5,451.2z"/>
@@ -2349,6 +2353,104 @@ const WebsyIcons = {
2349
2353
  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"/>
2350
2354
  </svg>
2351
2355
 
2356
+ `,
2357
+ 'Search': `
2358
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
2359
+ viewBox="0 0 500 500" xml:space="preserve">
2360
+ <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
2361
+ 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
2362
+ 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
2363
+ 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"/>
2364
+ </svg>
2365
+
2366
+ `,
2367
+ 'Bag': `
2368
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
2369
+ viewBox="0 0 500 500">
2370
+ <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
2371
+ 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
2372
+ H82.8L46.5,451.2z"/>
2373
+ <g>
2374
+ <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
2375
+ 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
2376
+ "/>
2377
+ </g>
2378
+ </svg>
2379
+
2380
+ `,
2381
+ 'User': `
2382
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
2383
+ viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
2384
+ <g>
2385
+ <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
2386
+ 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"/>
2387
+ </g>
2388
+ <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
2389
+ 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"/>
2390
+ </svg>
2391
+
2392
+ `,
2393
+ 'DockLeft': `
2394
+ <svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
2395
+ viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
2396
+ <g>
2397
+ <path d="M419.7,425H80.3C49.8,425,25,400.2,25,369.7V130.3C25,99.8,49.8,75,80.3,75h339.4c30.5,0,55.3,24.8,55.3,55.3v239.4
2398
+ C475,400.2,450.2,425,419.7,425z M80.3,95C60.8,95,45,110.8,45,130.3v239.4c0,19.5,15.8,35.3,35.3,35.3h339.4
2399
+ c19.5,0,35.3-15.8,35.3-35.3V130.3c0-19.5-15.8-35.3-35.3-35.3H80.3z"/>
2400
+ </g>
2401
+ <path d="M92.8,90.1H92h-4.2c-24.8,0-45,20.2-45,45v229.8c0,24.8,20.2,45,45,45H92h0.8h105.4V90.1H92.8z"/>
2402
+ </svg>
2403
+
2404
+ `,
2405
+ 'DockRight': `
2406
+ <svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
2407
+ viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
2408
+ <g>
2409
+ <path d="M25,369.7V130.3C25,99.8,49.8,75,80.3,75h339.4c30.5,0,55.3,24.8,55.3,55.3v239.4c0,30.5-24.8,55.3-55.3,55.3H80.3
2410
+ C49.8,425,25,400.2,25,369.7z M80.3,95C60.8,95,45,110.8,45,130.3v239.4c0,19.5,15.8,35.3,35.3,35.3h339.4
2411
+ c19.5,0,35.3-15.8,35.3-35.3V130.3c0-19.5-15.8-35.3-35.3-35.3H80.3z"/>
2412
+ </g>
2413
+ <path d="M407.2,90.1h0.8h4.2c24.8,0,45,20.2,45,45v229.8c0,24.8-20.2,45-45,45H408h-0.8H301.8V90.1H407.2z"/>
2414
+ </svg>
2415
+
2416
+ `,
2417
+ 'Pin': `
2418
+ <svg xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
2419
+ viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
2420
+ <g>
2421
+ <path d="M368,312.1H132l-0.6-9.4c-0.1-2.4-0.2-4.8-0.2-7.1c0-40.3,20.7-78.1,54.4-99.9V73.2h-9c-13,0-23.6-10.6-23.6-23.6
2422
+ S163.5,26,176.6,26h146.9c13,0,23.6,10.6,23.6,23.6s-10.6,23.6-23.6,23.6h-9v122.5c33.7,21.8,54.4,59.5,54.4,99.9
2423
+ c0,2.3-0.1,4.7-0.2,7.1L368,312.1z M151.2,292.1h197.5c-1.2-33.8-19.9-65.1-49.4-82.1l-5-2.9V53.2h29c2,0,3.6-1.6,3.6-3.6
2424
+ c0-2-1.6-3.6-3.6-3.6H176.6c-2,0-3.6,1.6-3.6,3.6c0,2,1.6,3.6,3.6,3.6h29v153.9l-5,2.9C171.1,227,152.4,258.3,151.2,292.1z"/>
2425
+ </g>
2426
+ <path d="M260.9,403.8V299.9h-21.8v108.8h0c0.1,36.1,4.9,65.3,10.9,65.3c6,0,10.9-29.7,10.9-66.4
2427
+ C260.9,406.4,260.9,405.1,260.9,403.8z"/>
2428
+ </svg>
2429
+
2430
+ `,
2431
+ 'WindowPopout': `
2432
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
2433
+ viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
2434
+ <style type="text/css">
2435
+ .st0{fill:none;stroke:#000000;stroke-width:20;stroke-miterlimit:10;}
2436
+ </style>
2437
+ <path class="st0" d="M420.1,359.6h-285c-24.7,0-45-20.2-45-45V124.9c0-24.7,20.2-45,45-45h285c24.7,0,45,20.2,45,45v189.7
2438
+ C465.1,339.3,444.9,359.6,420.1,359.6z"/>
2439
+ <path class="st0" d="M407.3,389.8c-6.3,17.3-22.9,29.7-42.3,29.7H80c-24.7,0-45-20.2-45-45V184.9c0-18.2,10.9-33.9,26.5-41"/>
2440
+ </svg>
2441
+
2442
+ `,
2443
+ 'Plus': `
2444
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500">
2445
+ <path d="M254.7,486h-10.3c-5.5,0-10-4.5-10-10V26c0-5.5,4.5-10,10-10h10.3c5.5,0,10,4.5,10,10v450C264.6,481.5,260.2,486,254.7,486z"/>
2446
+ <path d="M15,255.1v-10.3c0-5.5,4.5-10,10-10h450c5.5,0,10,4.5,10,10v10.3c0,5.5-4.5,10-10,10H25C19.5,265.1,15,260.7,15,255.1z"/>
2447
+ </svg>
2448
+
2449
+ `,
2450
+ 'Minus': `
2451
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500">
2452
+ <path d="M15,255.1v-10.3c0-5.5,4.5-10,10-10h450c5.5,0,10,4.5,10,10v10.3c0,5.5-4.5,10-10,10H25C19.5,265.1,15,260.7,15,255.1z"/>
2453
+ </svg>
2352
2454
  `
2353
2455
  }
2354
2456
 
@@ -2465,7 +2567,7 @@ class WebsyLogin {
2465
2567
  }
2466
2568
  }
2467
2569
 
2468
- /* global */
2570
+ /* global WebsyDesigns */
2469
2571
  class WebsyNavigationMenu {
2470
2572
  constructor (elementId, options) {
2471
2573
  this.options = Object.assign({}, {
@@ -2473,20 +2575,28 @@ class WebsyNavigationMenu {
2473
2575
  orientation: 'horizontal',
2474
2576
  parentMap: {},
2475
2577
  childIndentation: 10,
2476
- activeSymbol: 'none'
2578
+ activeSymbol: 'none',
2579
+ enableSearch: false,
2580
+ searchProp: 'text',
2581
+ menuIcon: `<svg viewbox="0 0 40 40" width="30" height="40">
2582
+ <rect x="0" y="0" width="30" height="4" rx="2"></rect>
2583
+ <rect x="0" y="12" width="30" height="4" rx="2"></rect>
2584
+ <rect x="0" y="24" width="30" height="4" rx="2"></rect>
2585
+ </svg>`,
2586
+ searchOptions: {}
2477
2587
  }, options)
2478
2588
  if (!elementId) {
2479
2589
  console.log('No element Id provided for Websy Menu')
2480
2590
  return
2481
2591
  }
2592
+ this.maxLevel = 0
2482
2593
  const el = document.getElementById(elementId)
2483
2594
  if (el) {
2484
2595
  this.elementId = elementId
2485
2596
  this.lowestLevel = 0
2486
2597
  this.flatItems = []
2487
2598
  this.itemMap = {}
2488
- this.flattenItems(0, this.options.items)
2489
- console.log(this.flatItems)
2599
+ this.flattenItems(0, this.options.items)
2490
2600
  el.classList.add(`websy-${this.options.orientation}-list-container`)
2491
2601
  el.classList.add('websy-menu')
2492
2602
  if (this.options.align) {
@@ -2498,27 +2608,27 @@ class WebsyNavigationMenu {
2498
2608
  if (this.options.classes) {
2499
2609
  this.options.classes.split(' ').forEach(c => el.classList.add(c))
2500
2610
  }
2501
- el.addEventListener('click', this.handleClick.bind(this))
2611
+ el.addEventListener('click', this.handleClick.bind(this))
2502
2612
  this.render()
2503
2613
  }
2504
2614
  }
2505
- flattenItems (index, items, level = 0) {
2615
+ flattenItems (index, items, level = 0, path = '') {
2506
2616
  if (items[index]) {
2507
2617
  this.lowestLevel = Math.max(level, this.lowestLevel)
2508
2618
  items[index].id = items[index].id || `${this.elementId}_${this.normaliseString(items[index].text)}`
2509
- this.itemMap[items[index].id] = items[index]
2510
2619
  items[index].level = level
2620
+ items[index].hasChildren = items[index].items && items[index].items.length > 0
2621
+ items[index].path = path !== '' ? `${path}::${items[index].id}` : items[index].id
2622
+ this.itemMap[items[index].id] = Object.assign({}, items[index])
2511
2623
  this.flatItems.push(items[index])
2512
2624
  if (items[index].items) {
2513
- this.flattenItems(0, items[index].items, level + 1)
2625
+ this.flattenItems(0, items[index].items, level + 1, items[index].path)
2514
2626
  }
2515
- this.flattenItems(++index, items, level)
2627
+ this.flattenItems(++index, items, level, path)
2516
2628
  }
2517
2629
  }
2518
2630
  handleClick (event) {
2519
- if (event.target.classList.contains('websy-menu-icon') ||
2520
- event.target.nodeName === 'svg' ||
2521
- event.target.nodeName === 'rect') {
2631
+ if (event.target.classList.contains('websy-menu-icon')) {
2522
2632
  this.toggleMobileMenu()
2523
2633
  }
2524
2634
  if (event.target.classList.contains('websy-menu-header')) {
@@ -2526,7 +2636,7 @@ class WebsyNavigationMenu {
2526
2636
  if (event.target.classList.contains('trigger-item') && item.level === this.lowestLevel) {
2527
2637
  this.toggleMobileMenu('remove')
2528
2638
  }
2529
- if (item.items) {
2639
+ if (item.hasChildren === true) {
2530
2640
  event.target.classList.toggle('menu-open')
2531
2641
  this.toggleMenu(item.id)
2532
2642
  }
@@ -2535,6 +2645,42 @@ class WebsyNavigationMenu {
2535
2645
  this.toggleMobileMenu()
2536
2646
  }
2537
2647
  }
2648
+ handleSearch (searchText) {
2649
+ const el = document.getElementById(this.elementId)
2650
+ let lowestItems = this.flatItems.filter(d => d.level === this.maxLevel)
2651
+ let visibleItems = lowestItems
2652
+ let defaultMethod = 'remove'
2653
+ if (searchText.length > 1) {
2654
+ defaultMethod = 'add'
2655
+ visibleItems = lowestItems.filter(d => d[this.options.searchProp].toLowerCase().indexOf(searchText.toLowerCase()) !== -1)
2656
+ }
2657
+ // hide everything
2658
+ const textEls = el.querySelectorAll(`div.websy-menu-header`)
2659
+ for (let t = 0; t < textEls.length; t++) {
2660
+ textEls[t].classList[defaultMethod]('websy-hidden')
2661
+ }
2662
+ const listEls = el.querySelectorAll(`ul.websy-child-list`)
2663
+ for (let l = 0; l < listEls.length; l++) {
2664
+ listEls[l].classList.add('websy-menu-collapsed')
2665
+ }
2666
+ if (searchText.length > 1) {
2667
+ visibleItems.forEach(d => {
2668
+ // show the item and open the list
2669
+ let pathParts = d.path.split('::')
2670
+ pathParts.forEach(p => {
2671
+ const textEl = document.getElementById(p)
2672
+ if (textEl) {
2673
+ textEl.classList.remove('websy-hidden')
2674
+ }
2675
+ const listEl = document.getElementById(`${p}_list`)
2676
+ if (listEl) {
2677
+ listEl.classList.remove('websy-menu-collapsed')
2678
+ }
2679
+ })
2680
+ })
2681
+ }
2682
+ console.log('visibleItems', visibleItems)
2683
+ }
2538
2684
  normaliseString (text) {
2539
2685
  return text.replace(/-/g, '').replace(/\s/g, '_')
2540
2686
  }
@@ -2545,14 +2691,10 @@ class WebsyNavigationMenu {
2545
2691
  if (this.options.collapsible === true) {
2546
2692
  html += `
2547
2693
  <div id='${this.elementId}_menuIcon' class='websy-menu-icon'>
2548
- <svg viewbox="0 0 40 40" width="30" height="40">
2549
- <rect x="0" y="0" width="30" height="4" rx="2"></rect>
2550
- <rect x="0" y="12" width="30" height="4" rx="2"></rect>
2551
- <rect x="0" y="24" width="30" height="4" rx="2"></rect>
2552
- </svg>
2694
+ ${this.options.menuIcon}
2553
2695
  </div>
2554
2696
  `
2555
- }
2697
+ }
2556
2698
  if (this.options.logo) {
2557
2699
  if (Array.isArray(this.options.logo.classes)) {
2558
2700
  this.options.logo.classes = this.options.logo.classes.join(' ')
@@ -2568,14 +2710,25 @@ class WebsyNavigationMenu {
2568
2710
  <div id="${this.elementId}_menuContainer" class="websy-menu-block-container">
2569
2711
  `
2570
2712
  }
2571
- html += this.renderBlock(this.options.items, 'main', 0)
2713
+ if (this.options.enableSearch === true) {
2714
+ html += `
2715
+ <div id='${this.elementId}_search' class='websy-menu-search'></div>
2716
+ `
2717
+ }
2718
+ html += this.renderBlock(this.elementId, this.elementId, this.options.items, 'main', 0)
2572
2719
  html += `</div>`
2573
2720
  el.innerHTML = html
2721
+ if (this.options.enableSearch === true) {
2722
+ this.search = new WebsyDesigns.Search(`${this.elementId}_search`, Object.assign({}, {
2723
+ onSearch: this.handleSearch.bind(this)
2724
+ }, this.options.searchOptions))
2725
+ }
2574
2726
  }
2575
2727
  }
2576
- renderBlock (items, block, level = 0) {
2728
+ renderBlock (id, path, items, block, level = 0) {
2729
+ this.maxLevel = Math.max(this.maxLevel, level)
2577
2730
  let html = `
2578
- <ul class='websy-${this.options.orientation}-list ${level > 0 ? 'websy-child-list' : ''} ${(block !== 'main' ? 'websy-menu-collapsed' : '')}' id='${this.elementId}_${block}_list'
2731
+ <ul class='websy-${this.options.orientation}-list ${level > 0 ? 'websy-child-list' : ''} ${(block !== 'main' ? 'websy-menu-collapsed' : '')}' id='${id}_list' data-path='${path}'
2579
2732
  `
2580
2733
  if (block !== 'main') {
2581
2734
  html += ` data-collapsed='${(block !== 'main' ? 'true' : 'false')}'`
@@ -2593,13 +2746,14 @@ class WebsyNavigationMenu {
2593
2746
  html += `
2594
2747
  <li class='websy-${this.options.orientation}-list-item ${items[i].alwaysOpen === true ? 'always-open' : ''}'>
2595
2748
  <div class='websy-menu-header ${items[i].classes || ''} ${selected} ${active}'
2596
- id='${blockId}'
2597
- data-id='${currentBlock}'
2598
- data-menu-id='${this.elementId}_${currentBlock}_list'
2599
- data-popout-id='${level > 1 ? block : currentBlock}'
2600
- data-text='${items[i].isLink !== true ? items[i].text : ''}'
2601
- style='padding-left: ${level * this.options.childIndentation}px'
2602
- ${(items[i].attributes && items[i].attributes.join(' ')) || ''}
2749
+ id='${blockId}'
2750
+ data-id='${currentBlock}'
2751
+ data-path='${items[i].path}'
2752
+ data-menu-id='${this.elementId}_${currentBlock}_list'
2753
+ data-popout-id='${level > 1 ? block : currentBlock}'
2754
+ data-text='${items[i].isLink !== true ? items[i].text : ''}'
2755
+ style='padding-left: ${level * this.options.childIndentation}px'
2756
+ ${(items[i].attributes && items[i].attributes.join(' ')) || ''}
2603
2757
  >
2604
2758
  `
2605
2759
  if (this.options.orientation === 'horizontal') {
@@ -2619,9 +2773,9 @@ class WebsyNavigationMenu {
2619
2773
  <span class='${items[i].items && items[i].items.length > 0 ? 'menu-carat' : ''}'></span>
2620
2774
  `
2621
2775
  if (this.options.orientation === 'vertical') {
2622
- html += `
2623
- &nbsp;
2624
- `
2776
+ // html += `
2777
+ // &nbsp;
2778
+ // `
2625
2779
  }
2626
2780
  if (items[i].isLink === true && items[i].href) {
2627
2781
  html += `<a href='${items[i].href}'>${items[i].text}</a>`
@@ -2630,7 +2784,7 @@ class WebsyNavigationMenu {
2630
2784
  </div>
2631
2785
  `
2632
2786
  if (items[i].items) {
2633
- html += this.renderBlock(items[i].items, currentBlock, items[i].level + 1)
2787
+ html += this.renderBlock(blockId, items[i].path, items[i].items, currentBlock, items[i].level + 1)
2634
2788
  }
2635
2789
  // map the item to it's parent
2636
2790
  if (block && block !== 'main') {
@@ -2647,6 +2801,8 @@ class WebsyNavigationMenu {
2647
2801
  }
2648
2802
  toggleMenu (id) {
2649
2803
  const el = document.getElementById(`${id}_list`)
2804
+ // const menuId = el.getAttribute('data-menu-id')
2805
+ // const menuEl = document.getElementById(menuId)
2650
2806
  if (el) {
2651
2807
  el.classList.toggle('websy-menu-collapsed')
2652
2808
  }
@@ -3584,7 +3740,14 @@ class WebsyRouter {
3584
3740
  this.previousView = ''
3585
3741
  this.currentView = ''
3586
3742
  this.currentViewMain = ''
3587
- this.currentParams = {}
3743
+ this.currentParams = {
3744
+ path: '',
3745
+ items: {}
3746
+ }
3747
+ this.previousParams = {
3748
+ path: '',
3749
+ items: {}
3750
+ }
3588
3751
  this.controlPressed = false
3589
3752
  this.usesHTMLSuffix = window.location.pathname.indexOf('.htm') !== -1
3590
3753
  window.addEventListener('popstate', this.onPopState.bind(this))
@@ -3625,10 +3788,11 @@ class WebsyRouter {
3625
3788
  }
3626
3789
  }
3627
3790
  }
3628
- addUrlParams (params) {
3791
+ addUrlParams (params, reloadView = false) {
3629
3792
  if (typeof params === 'undefined') {
3630
3793
  return
3631
3794
  }
3795
+ this.previousParams = Object.assign({}, this.currentParams)
3632
3796
  const output = {
3633
3797
  path: '',
3634
3798
  items: {}
@@ -3650,6 +3814,9 @@ class WebsyRouter {
3650
3814
  history.pushState({
3651
3815
  inputPath
3652
3816
  }, inputPath, `${inputPath}?${path}`)
3817
+ if (reloadView === true) {
3818
+ this.showView(this.currentView, this.currentParams, 'main')
3819
+ }
3653
3820
  }
3654
3821
  buildUrlPath (params) {
3655
3822
  let path = []
@@ -3678,6 +3845,7 @@ class WebsyRouter {
3678
3845
  }
3679
3846
  }
3680
3847
  formatParams (params) {
3848
+ this.previousParams = Object.assign({}, this.currentParams)
3681
3849
  const output = {
3682
3850
  path: params,
3683
3851
  items: {}
@@ -3897,6 +4065,10 @@ class WebsyRouter {
3897
4065
  if (this.previousView !== this.currentView || group !== 'main') {
3898
4066
  this.showComponents(view)
3899
4067
  this.publish('show', [view, params, group])
4068
+ }
4069
+ else if (this.previousView === this.currentView && this.previousParams.path !== this.currentParams.path) {
4070
+ this.showComponents(view)
4071
+ this.publish('show', [view, params, group])
3900
4072
  }
3901
4073
  }
3902
4074
  reloadCurrentView () {
@@ -3912,17 +4084,14 @@ class WebsyRouter {
3912
4084
  let groupActiveView
3913
4085
  let params = {}
3914
4086
  let newPath = inputPath
3915
- if (inputPath === this.options.defaultView && this.usesHTMLSuffix === false) {
4087
+ if (inputPath.split('?')[0] === this.options.defaultView && this.usesHTMLSuffix === false) {
3916
4088
  inputPath = inputPath.replace(this.options.defaultView, '/')
3917
4089
  }
3918
4090
  if (this.options.persistentParameters === true) {
3919
4091
  if (inputPath.indexOf('?') === -1 && this.queryParams) {
3920
4092
  inputPath += `?${this.queryParams}`
3921
4093
  }
3922
- }
3923
- else {
3924
- this.currentParams = {}
3925
- }
4094
+ }
3926
4095
  if (this.usesHTMLSuffix === true) {
3927
4096
  if (inputPath.indexOf('?') === -1) {
3928
4097
  inputPath = `?view=${inputPath}`
@@ -3943,7 +4112,11 @@ class WebsyRouter {
3943
4112
  inputPath = parts[0]
3944
4113
  }
3945
4114
  else if (group === this.options.defaultGroup) {
3946
- this.currentParams = {}
4115
+ this.previousParams = Object.assign({}, this.currentParams)
4116
+ this.currentParams = {
4117
+ path: '',
4118
+ items: {}
4119
+ }
3947
4120
  }
3948
4121
  if (event) {
3949
4122
  if (event.target && event.target.classList.contains(this.options.triggerToggleClass)) {
@@ -3995,13 +4168,7 @@ class WebsyRouter {
3995
4168
  }
3996
4169
  if (toggle === true && newPath === groupActiveView) {
3997
4170
  return
3998
- }
3999
- if (toggle === false) {
4000
- this.showView(this.currentView, this.currentParams, group)
4001
- }
4002
- else if (newPath && newPath !== '') {
4003
- this.showView(newPath, null, group)
4004
- }
4171
+ }
4005
4172
  if (this.usesHTMLSuffix === true) {
4006
4173
  inputPath = window.location.pathname.split('/').pop() + inputPath
4007
4174
  }
@@ -4028,6 +4195,12 @@ class WebsyRouter {
4028
4195
  //
4029
4196
  }
4030
4197
  }
4198
+ if (toggle === false) {
4199
+ this.showView(this.currentView, this.currentParams, group)
4200
+ }
4201
+ else if (newPath && newPath !== '') {
4202
+ this.showView(newPath, null, group)
4203
+ }
4031
4204
  }
4032
4205
  on (event, fn) {
4033
4206
  this.options.subscribers[event].push(fn)
@@ -4112,7 +4285,7 @@ class WebsySearch {
4112
4285
  this.elementId = elementId
4113
4286
  const DEFAULTS = {
4114
4287
  searchIcon: `<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>`,
4115
- clearIcon: `<svg class='clear' xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 512 512"><title>ionicons-v5-l</title><line x1="368" y1="368" x2="144" y2="144" style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/><line x1="368" y1="144" x2="144" y2="368" style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/></svg>`,
4288
+ clearIcon: `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 512 512"><title>ionicons-v5-l</title><line x1="368" y1="368" x2="144" y2="144" style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/><line x1="368" y1="144" x2="144" y2="368" style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/></svg>`,
4116
4289
  placeholder: 'Search',
4117
4290
  searchTimeout: 500,
4118
4291
  minLength: 2
@@ -4122,12 +4295,15 @@ class WebsySearch {
4122
4295
  const el = document.getElementById(elementId)
4123
4296
  if (el) {
4124
4297
  // el.addEventListener('click', this.handleClick.bind(this))
4298
+ el.addEventListener('click', this.handleClick.bind(this))
4125
4299
  el.addEventListener('keyup', this.handleKeyUp.bind(this))
4126
4300
  el.innerHTML = `
4127
4301
  <div class='websy-search-input-container'>
4128
4302
  ${this.options.searchIcon}
4129
4303
  <input id='${this.elementId}_search' class='websy-search-input' placeholder='${this.options.placeholder || 'Search'}'>
4130
- ${this.options.clearIcon}
4304
+ <div class='clear websy-hidden' id='${this.elementId}_clear'>
4305
+ ${this.options.clearIcon}
4306
+ </div>
4131
4307
  </div>
4132
4308
  `
4133
4309
  }
@@ -4135,11 +4311,25 @@ class WebsySearch {
4135
4311
  console.log('No element found with Id', elementId)
4136
4312
  }
4137
4313
  }
4314
+ handleClick (event) {
4315
+ if (event.target.classList.contains('clear')) {
4316
+ const inputEl = document.getElementById(`${this.elementId}_search`)
4317
+ inputEl.value = ''
4318
+ this.options.onSearch('')
4319
+ }
4320
+ }
4138
4321
  handleKeyUp (event) {
4139
4322
  if (event.target.classList.contains('websy-search-input')) {
4140
4323
  if (this.searchTimeoutFn) {
4141
4324
  clearTimeout(this.searchTimeoutFn)
4142
4325
  }
4326
+ const clearEl = document.getElementById(`${this.elementId}_clear`)
4327
+ if (event.target.value.length > 0) {
4328
+ clearEl.classList.remove('websy-hidden')
4329
+ }
4330
+ else {
4331
+ clearEl.classList.add('websy-hidden')
4332
+ }
4143
4333
  if (event.target.value.length >= this.options.minLength) {
4144
4334
  this.searchTimeoutFn = setTimeout(() => {
4145
4335
  if (this.options.onSearch) {
@@ -5693,7 +5883,7 @@ class WebsyTable3 {
5693
5883
  `).join('')
5694
5884
  bodyHtml += '</colgroup>'
5695
5885
  }
5696
- data.forEach(row => {
5886
+ data.forEach((row, rowIndex) => {
5697
5887
  bodyHtml += `<tr class="websy-table-row">`
5698
5888
  row.forEach((cell, cellIndex) => {
5699
5889
  if (typeof sizingColumns[cellIndex] === 'undefined') {
@@ -5722,6 +5912,8 @@ class WebsyTable3 {
5722
5912
  data-info='${cell.value}'
5723
5913
  colspan='${cell.colspan || 1}'
5724
5914
  rowspan='${cell.rowspan || 1}'
5915
+ data-row-index='${rowIndex}'
5916
+ data-col-index='${cellIndex}'
5725
5917
  `
5726
5918
  // if (useWidths === true) {
5727
5919
  // bodyHtml += `
@@ -5730,7 +5922,22 @@ class WebsyTable3 {
5730
5922
  // `
5731
5923
  // }
5732
5924
  bodyHtml += `
5733
- >
5925
+ >`
5926
+ if (cell.expandable === true) {
5927
+ bodyHtml += `<i
5928
+ data-row-index='${rowIndex}'
5929
+ data-col-index='${cellIndex}'
5930
+ class='websy-table-cell-expand'
5931
+ >${WebsyDesigns.Icons.Plus}</i>`
5932
+ }
5933
+ if (cell.collapsable === true) {
5934
+ bodyHtml += `<i
5935
+ data-row-index='${rowIndex}'
5936
+ data-col-index='${cellIndex}'
5937
+ class='websy-table-cell-collapse'
5938
+ >${WebsyDesigns.Icons.Minus}</i>`
5939
+ }
5940
+ bodyHtml += `
5734
5941
  ${cell.value}
5735
5942
  </td>`
5736
5943
  })
@@ -5948,13 +6155,30 @@ class WebsyTable3 {
5948
6155
  return output
5949
6156
  }
5950
6157
  handleClick (event) {
6158
+ const colIndex = +event.target.getAttribute('data-col-index')
6159
+ const rowIndex = +event.target.getAttribute('data-row-index')
5951
6160
  if (event.target.classList.contains('websy-table-search-icon')) {
5952
- console.log('clicked on search icon')
5953
- const colIndex = +event.target.getAttribute('data-col-index')
6161
+ console.log('clicked on search icon')
5954
6162
  if (this.options.columns[this.options.columns.length - 1][colIndex].onSearch) {
5955
6163
  this.options.columns[this.options.columns.length - 1][colIndex].onSearch(event, this.options.columns[this.options.columns.length - 1][colIndex])
5956
6164
  }
5957
6165
  }
6166
+ if (event.target.classList.contains('websy-table-cell-collapse')) {
6167
+ if (this.options.onCollapseCell) {
6168
+ this.options.onCollapseCell(event, +rowIndex, +colIndex)
6169
+ }
6170
+ else {
6171
+ // out of box function
6172
+ }
6173
+ }
6174
+ if (event.target.classList.contains('websy-table-cell-expand')) {
6175
+ if (this.options.onExpandCell) {
6176
+ this.options.onExpandCell(event, +rowIndex, +colIndex)
6177
+ }
6178
+ else {
6179
+ // out of box function
6180
+ }
6181
+ }
5958
6182
  }
5959
6183
  handleMouseDown (event) {
5960
6184
  if (event.target.classList.contains('websy-scroll-handle-y')) {
@@ -6659,6 +6883,9 @@ else {
6659
6883
  this.longestBottom = this.options.data.bottom.max.toString()
6660
6884
  if (this.options.data.bottom.formatter) {
6661
6885
  this.longestBottom = this.options.data.bottom.formatter(this.options.data.bottom.max).toString()
6886
+ }
6887
+ else {
6888
+ this.longestBottom = '01/01/2000'
6662
6889
  }
6663
6890
  }
6664
6891
  if (this.options.data.left && this.options.data.left.data && this.options.data.left.max === 'undefined') {
@@ -7174,8 +7401,8 @@ if (this.options.showLabels === true || series.showLabels === true) {
7174
7401
  .style('stroke-opacity', 1e-6)
7175
7402
  .remove()
7176
7403
  labels
7177
- .attr('x', getLabelX.bind(this))
7178
- .attr('y', getLabelY.bind(this))
7404
+ .attr('x', d => getLabelX.call(this, d, series.labelPosition))
7405
+ .attr('y', d => getLabelY.call(this, d, series.labelPosition))
7179
7406
  .attr('class', `label_${series.key}`)
7180
7407
  .attr('fill', d => this.options.labelColor || WebsyDesigns.WebsyUtils.getLightDark(d.y.color || d.color || series.color))
7181
7408
  .style('font-size', `${this.options.labelSize || this.options.fontSize}px`)
@@ -7211,8 +7438,8 @@ if (this.options.showLabels === true || series.showLabels === true) {
7211
7438
  .enter()
7212
7439
  .append('text')
7213
7440
  .attr('class', `label_${series.key}`)
7214
- .attr('x', getLabelX.bind(this))
7215
- .attr('y', getLabelY.bind(this))
7441
+ .attr('x', d => getLabelX.call(this, d, series.labelPosition))
7442
+ .attr('y', d => getLabelY.call(this, d, series.labelPosition))
7216
7443
  .attr('alignment-baseline', 'central')
7217
7444
  .attr('text-anchor', this.options.orientation === 'horizontal' ? 'left' : 'middle')
7218
7445
  .attr('fill', d => this.options.labelColor || WebsyDesigns.WebsyUtils.getLightDark(d.y.color || d.color || series.color))