@websy/websy-designs 1.3.3 → 1.3.5

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.
@@ -216,7 +216,13 @@ class PGHelper {
216
216
  let partValues = parts[1]
217
217
  partValues = partValues.split('|')
218
218
  if (partValues.length === 1) {
219
- if (parts[1].indexOf('%') !== -1) {
219
+ if (parts[1].indexOf('>') !== -1) {
220
+ return `${entity ? entity + '.' : ''}${parts[0]} > '${parts[1].replace('>', '')}'`
221
+ }
222
+ else if (parts[1].indexOf('<') !== -1) {
223
+ return `${entity ? entity + '.' : ''}${parts[0]} < '${parts[1].replace('<', '')}'`
224
+ }
225
+ else if (parts[1].indexOf('%') !== -1) {
220
226
  return `${entity ? entity + '.' : ''}${parts[0]} LIKE '${parts[1]}'`
221
227
  }
222
228
  else {
@@ -2217,7 +2217,7 @@ class WebsyLoadingDialog {
2217
2217
  }
2218
2218
  }
2219
2219
 
2220
- /* global */
2220
+ /* global WebsyDesigns */
2221
2221
  class WebsyNavigationMenu {
2222
2222
  constructor (elementId, options) {
2223
2223
  this.options = Object.assign({}, {
@@ -2225,20 +2225,28 @@ class WebsyNavigationMenu {
2225
2225
  orientation: 'horizontal',
2226
2226
  parentMap: {},
2227
2227
  childIndentation: 10,
2228
- activeSymbol: 'none'
2228
+ activeSymbol: 'none',
2229
+ enableSearch: false,
2230
+ searchProp: 'text',
2231
+ menuIcon: `<svg viewbox="0 0 40 40" width="30" height="40">
2232
+ <rect x="0" y="0" width="30" height="4" rx="2"></rect>
2233
+ <rect x="0" y="12" width="30" height="4" rx="2"></rect>
2234
+ <rect x="0" y="24" width="30" height="4" rx="2"></rect>
2235
+ </svg>`,
2236
+ searchOptions: {}
2229
2237
  }, options)
2230
2238
  if (!elementId) {
2231
2239
  console.log('No element Id provided for Websy Menu')
2232
2240
  return
2233
2241
  }
2242
+ this.maxLevel = 0
2234
2243
  const el = document.getElementById(elementId)
2235
2244
  if (el) {
2236
2245
  this.elementId = elementId
2237
2246
  this.lowestLevel = 0
2238
2247
  this.flatItems = []
2239
2248
  this.itemMap = {}
2240
- this.flattenItems(0, this.options.items)
2241
- console.log(this.flatItems)
2249
+ this.flattenItems(0, this.options.items)
2242
2250
  el.classList.add(`websy-${this.options.orientation}-list-container`)
2243
2251
  el.classList.add('websy-menu')
2244
2252
  if (this.options.align) {
@@ -2250,27 +2258,27 @@ class WebsyNavigationMenu {
2250
2258
  if (this.options.classes) {
2251
2259
  this.options.classes.split(' ').forEach(c => el.classList.add(c))
2252
2260
  }
2253
- el.addEventListener('click', this.handleClick.bind(this))
2261
+ el.addEventListener('click', this.handleClick.bind(this))
2254
2262
  this.render()
2255
2263
  }
2256
2264
  }
2257
- flattenItems (index, items, level = 0) {
2265
+ flattenItems (index, items, level = 0, path = '') {
2258
2266
  if (items[index]) {
2259
2267
  this.lowestLevel = Math.max(level, this.lowestLevel)
2260
2268
  items[index].id = items[index].id || `${this.elementId}_${this.normaliseString(items[index].text)}`
2261
- this.itemMap[items[index].id] = items[index]
2262
2269
  items[index].level = level
2270
+ items[index].hasChildren = items[index].items && items[index].items.length > 0
2271
+ items[index].path = path !== '' ? `${path}::${items[index].id}` : items[index].id
2272
+ this.itemMap[items[index].id] = Object.assign({}, items[index])
2263
2273
  this.flatItems.push(items[index])
2264
2274
  if (items[index].items) {
2265
- this.flattenItems(0, items[index].items, level + 1)
2275
+ this.flattenItems(0, items[index].items, level + 1, items[index].path)
2266
2276
  }
2267
- this.flattenItems(++index, items, level)
2277
+ this.flattenItems(++index, items, level, path)
2268
2278
  }
2269
2279
  }
2270
2280
  handleClick (event) {
2271
- if (event.target.classList.contains('websy-menu-icon') ||
2272
- event.target.nodeName === 'svg' ||
2273
- event.target.nodeName === 'rect') {
2281
+ if (event.target.classList.contains('websy-menu-icon')) {
2274
2282
  this.toggleMobileMenu()
2275
2283
  }
2276
2284
  if (event.target.classList.contains('websy-menu-header')) {
@@ -2278,7 +2286,7 @@ class WebsyNavigationMenu {
2278
2286
  if (event.target.classList.contains('trigger-item') && item.level === this.lowestLevel) {
2279
2287
  this.toggleMobileMenu('remove')
2280
2288
  }
2281
- if (item.items) {
2289
+ if (item.hasChildren === true) {
2282
2290
  event.target.classList.toggle('menu-open')
2283
2291
  this.toggleMenu(item.id)
2284
2292
  }
@@ -2287,6 +2295,42 @@ class WebsyNavigationMenu {
2287
2295
  this.toggleMobileMenu()
2288
2296
  }
2289
2297
  }
2298
+ handleSearch (searchText) {
2299
+ const el = document.getElementById(this.elementId)
2300
+ let lowestItems = this.flatItems.filter(d => d.level === this.maxLevel)
2301
+ let visibleItems = lowestItems
2302
+ let defaultMethod = 'remove'
2303
+ if (searchText.length > 1) {
2304
+ defaultMethod = 'add'
2305
+ visibleItems = lowestItems.filter(d => d[this.options.searchProp].toLowerCase().indexOf(searchText.toLowerCase()) !== -1)
2306
+ }
2307
+ // hide everything
2308
+ const textEls = el.querySelectorAll(`div.websy-menu-header`)
2309
+ for (let t = 0; t < textEls.length; t++) {
2310
+ textEls[t].classList[defaultMethod]('websy-hidden')
2311
+ }
2312
+ const listEls = el.querySelectorAll(`ul.websy-child-list`)
2313
+ for (let l = 0; l < listEls.length; l++) {
2314
+ listEls[l].classList.add('websy-menu-collapsed')
2315
+ }
2316
+ if (searchText.length > 1) {
2317
+ visibleItems.forEach(d => {
2318
+ // show the item and open the list
2319
+ let pathParts = d.path.split('::')
2320
+ pathParts.forEach(p => {
2321
+ const textEl = document.getElementById(p)
2322
+ if (textEl) {
2323
+ textEl.classList.remove('websy-hidden')
2324
+ }
2325
+ const listEl = document.getElementById(`${p}_list`)
2326
+ if (listEl) {
2327
+ listEl.classList.remove('websy-menu-collapsed')
2328
+ }
2329
+ })
2330
+ })
2331
+ }
2332
+ console.log('visibleItems', visibleItems)
2333
+ }
2290
2334
  normaliseString (text) {
2291
2335
  return text.replace(/-/g, '').replace(/\s/g, '_')
2292
2336
  }
@@ -2297,14 +2341,10 @@ class WebsyNavigationMenu {
2297
2341
  if (this.options.collapsible === true) {
2298
2342
  html += `
2299
2343
  <div id='${this.elementId}_menuIcon' class='websy-menu-icon'>
2300
- <svg viewbox="0 0 40 40" width="30" height="40">
2301
- <rect x="0" y="0" width="30" height="4" rx="2"></rect>
2302
- <rect x="0" y="12" width="30" height="4" rx="2"></rect>
2303
- <rect x="0" y="24" width="30" height="4" rx="2"></rect>
2304
- </svg>
2344
+ ${this.options.menuIcon}
2305
2345
  </div>
2306
2346
  `
2307
- }
2347
+ }
2308
2348
  if (this.options.logo) {
2309
2349
  if (Array.isArray(this.options.logo.classes)) {
2310
2350
  this.options.logo.classes = this.options.logo.classes.join(' ')
@@ -2320,14 +2360,25 @@ class WebsyNavigationMenu {
2320
2360
  <div id="${this.elementId}_menuContainer" class="websy-menu-block-container">
2321
2361
  `
2322
2362
  }
2323
- html += this.renderBlock(this.options.items, 'main', 0)
2363
+ if (this.options.enableSearch === true) {
2364
+ html += `
2365
+ <div id='${this.elementId}_search' class='websy-menu-search'></div>
2366
+ `
2367
+ }
2368
+ html += this.renderBlock(this.elementId, this.elementId, this.options.items, 'main', 0)
2324
2369
  html += `</div>`
2325
2370
  el.innerHTML = html
2371
+ if (this.options.enableSearch === true) {
2372
+ this.search = new WebsyDesigns.Search(`${this.elementId}_search`, Object.assign({}, {
2373
+ onSearch: this.handleSearch.bind(this)
2374
+ }, this.options.searchOptions))
2375
+ }
2326
2376
  }
2327
2377
  }
2328
- renderBlock (items, block, level = 0) {
2378
+ renderBlock (id, path, items, block, level = 0) {
2379
+ this.maxLevel = Math.max(this.maxLevel, level)
2329
2380
  let html = `
2330
- <ul class='websy-${this.options.orientation}-list ${level > 0 ? 'websy-child-list' : ''} ${(block !== 'main' ? 'websy-menu-collapsed' : '')}' id='${this.elementId}_${block}_list'
2381
+ <ul class='websy-${this.options.orientation}-list ${level > 0 ? 'websy-child-list' : ''} ${(block !== 'main' ? 'websy-menu-collapsed' : '')}' id='${id}_list' data-path='${path}'
2331
2382
  `
2332
2383
  if (block !== 'main') {
2333
2384
  html += ` data-collapsed='${(block !== 'main' ? 'true' : 'false')}'`
@@ -2345,13 +2396,14 @@ class WebsyNavigationMenu {
2345
2396
  html += `
2346
2397
  <li class='websy-${this.options.orientation}-list-item ${items[i].alwaysOpen === true ? 'always-open' : ''}'>
2347
2398
  <div class='websy-menu-header ${items[i].classes || ''} ${selected} ${active}'
2348
- id='${blockId}'
2349
- data-id='${currentBlock}'
2350
- data-menu-id='${this.elementId}_${currentBlock}_list'
2351
- data-popout-id='${level > 1 ? block : currentBlock}'
2352
- data-text='${items[i].isLink !== true ? items[i].text : ''}'
2353
- style='padding-left: ${level * this.options.childIndentation}px'
2354
- ${(items[i].attributes && items[i].attributes.join(' ')) || ''}
2399
+ id='${blockId}'
2400
+ data-id='${currentBlock}'
2401
+ data-path='${items[i].path}'
2402
+ data-menu-id='${this.elementId}_${currentBlock}_list'
2403
+ data-popout-id='${level > 1 ? block : currentBlock}'
2404
+ data-text='${items[i].isLink !== true ? items[i].text : ''}'
2405
+ style='padding-left: ${level * this.options.childIndentation}px'
2406
+ ${(items[i].attributes && items[i].attributes.join(' ')) || ''}
2355
2407
  >
2356
2408
  `
2357
2409
  if (this.options.orientation === 'horizontal') {
@@ -2371,9 +2423,9 @@ class WebsyNavigationMenu {
2371
2423
  <span class='${items[i].items && items[i].items.length > 0 ? 'menu-carat' : ''}'></span>
2372
2424
  `
2373
2425
  if (this.options.orientation === 'vertical') {
2374
- html += `
2375
- &nbsp;
2376
- `
2426
+ // html += `
2427
+ // &nbsp;
2428
+ // `
2377
2429
  }
2378
2430
  if (items[i].isLink === true && items[i].href) {
2379
2431
  html += `<a href='${items[i].href}'>${items[i].text}</a>`
@@ -2382,7 +2434,7 @@ class WebsyNavigationMenu {
2382
2434
  </div>
2383
2435
  `
2384
2436
  if (items[i].items) {
2385
- html += this.renderBlock(items[i].items, currentBlock, items[i].level + 1)
2437
+ html += this.renderBlock(blockId, items[i].path, items[i].items, currentBlock, items[i].level + 1)
2386
2438
  }
2387
2439
  // map the item to it's parent
2388
2440
  if (block && block !== 'main') {
@@ -2399,6 +2451,8 @@ class WebsyNavigationMenu {
2399
2451
  }
2400
2452
  toggleMenu (id) {
2401
2453
  const el = document.getElementById(`${id}_list`)
2454
+ // const menuId = el.getAttribute('data-menu-id')
2455
+ // const menuEl = document.getElementById(menuId)
2402
2456
  if (el) {
2403
2457
  el.classList.toggle('websy-menu-collapsed')
2404
2458
  }
@@ -3089,7 +3143,7 @@ class WebsyResultList {
3089
3143
  const el = document.getElementById(this.elementId)
3090
3144
  el.innerHTML += html.replace(/\n/g, '')
3091
3145
  }
3092
- buildHTML (d, startIndex = 0, inputTemplate) {
3146
+ buildHTML (d, startIndex = 0, inputTemplate, locator = []) {
3093
3147
  let html = ``
3094
3148
  if (this.options.template) {
3095
3149
  if (d.length > 0) {
@@ -3191,13 +3245,13 @@ class WebsyResultList {
3191
3245
  parts.forEach(p => {
3192
3246
  items = items[p]
3193
3247
  })
3194
- template = template.replace(m[0], this.buildHTML(items, 0, withoutFor))
3248
+ template = template.replace(m[0], this.buildHTML(items, 0, withoutFor, [...locator, `${startIndex + ix}:${c}`]))
3195
3249
  }
3196
3250
  })
3197
3251
  let tagMatches = [...template.matchAll(/(\sdata-event=["|']\w.+)["|']/g)]
3198
3252
  tagMatches.forEach(m => {
3199
3253
  if (m[0] && m.index > -1) {
3200
- template = template.replace(m[0], `${m[0]} data-id=${startIndex + ix}`)
3254
+ template = template.replace(m[0], `${m[0]} data-id=${startIndex + ix} data-locator='${locator.join(';')}'`)
3201
3255
  }
3202
3256
  })
3203
3257
  let flatRow = this.flattenObject(row)
@@ -3258,15 +3312,30 @@ class WebsyResultList {
3258
3312
  l = l.split('(')
3259
3313
  let params = []
3260
3314
  const id = event.target.getAttribute('data-id')
3315
+ const locator = event.target.getAttribute('data-locator')
3261
3316
  if (l[1]) {
3262
3317
  l[1] = l[1].replace(')', '')
3263
3318
  params = l[1].split(',')
3264
3319
  }
3265
3320
  l = l[0]
3321
+ let data = this.rows
3322
+ if (locator !== '') {
3323
+ let locatorItems = locator.split(';')
3324
+ locatorItems.forEach(loc => {
3325
+ let locatorParts = loc.split(':')
3326
+ if (data[locatorParts[0]]) {
3327
+ data = data[locatorParts[0]]
3328
+ let parts = locatorParts[1].split('.')
3329
+ parts.forEach(p => {
3330
+ data = data[p]
3331
+ })
3332
+ }
3333
+ })
3334
+ }
3266
3335
  params = params.map(p => {
3267
3336
  if (typeof p !== 'string' && typeof p !== 'number') {
3268
- if (this.rows[+id]) {
3269
- p = this.rows[+id][p]
3337
+ if (data[+id]) {
3338
+ p = data[+id][p]
3270
3339
  }
3271
3340
  }
3272
3341
  else if (typeof p === 'string') {
@@ -3276,7 +3345,7 @@ class WebsyResultList {
3276
3345
  })
3277
3346
  if (event.target.classList.contains('clickable') && this.options.listeners.click[l]) {
3278
3347
  event.stopPropagation()
3279
- this.options.listeners.click[l].call(this, event, this.rows[+id], ...params)
3348
+ this.options.listeners.click[l].call(this, event, data[+id], ...params)
3280
3349
  }
3281
3350
  }
3282
3351
  }
@@ -3321,7 +3390,14 @@ class WebsyRouter {
3321
3390
  this.previousView = ''
3322
3391
  this.currentView = ''
3323
3392
  this.currentViewMain = ''
3324
- this.currentParams = {}
3393
+ this.currentParams = {
3394
+ path: '',
3395
+ items: {}
3396
+ }
3397
+ this.previousParams = {
3398
+ path: '',
3399
+ items: {}
3400
+ }
3325
3401
  this.controlPressed = false
3326
3402
  this.usesHTMLSuffix = window.location.pathname.indexOf('.htm') !== -1
3327
3403
  window.addEventListener('popstate', this.onPopState.bind(this))
@@ -3362,10 +3438,11 @@ class WebsyRouter {
3362
3438
  }
3363
3439
  }
3364
3440
  }
3365
- addUrlParams (params) {
3441
+ addUrlParams (params, reloadView = false) {
3366
3442
  if (typeof params === 'undefined') {
3367
3443
  return
3368
3444
  }
3445
+ this.previousParams = Object.assign({}, this.currentParams)
3369
3446
  const output = {
3370
3447
  path: '',
3371
3448
  items: {}
@@ -3387,6 +3464,9 @@ class WebsyRouter {
3387
3464
  history.pushState({
3388
3465
  inputPath
3389
3466
  }, inputPath, `${inputPath}?${path}`)
3467
+ if (reloadView === true) {
3468
+ this.showView(this.currentView, this.currentParams, 'main')
3469
+ }
3390
3470
  }
3391
3471
  buildUrlPath (params) {
3392
3472
  let path = []
@@ -3415,6 +3495,7 @@ class WebsyRouter {
3415
3495
  }
3416
3496
  }
3417
3497
  formatParams (params) {
3498
+ this.previousParams = Object.assign({}, this.currentParams)
3418
3499
  const output = {
3419
3500
  path: params,
3420
3501
  items: {}
@@ -3634,6 +3715,10 @@ class WebsyRouter {
3634
3715
  if (this.previousView !== this.currentView || group !== 'main') {
3635
3716
  this.showComponents(view)
3636
3717
  this.publish('show', [view, params, group])
3718
+ }
3719
+ if (this.previousView === this.currentView && this.previousParams.path !== this.currentParams.path) {
3720
+ this.showComponents(view)
3721
+ this.publish('show', [view, params, group])
3637
3722
  }
3638
3723
  }
3639
3724
  reloadCurrentView () {
@@ -3649,17 +3734,14 @@ class WebsyRouter {
3649
3734
  let groupActiveView
3650
3735
  let params = {}
3651
3736
  let newPath = inputPath
3652
- if (inputPath === this.options.defaultView && this.usesHTMLSuffix === false) {
3737
+ if (inputPath.split('?')[0] === this.options.defaultView && this.usesHTMLSuffix === false) {
3653
3738
  inputPath = inputPath.replace(this.options.defaultView, '/')
3654
3739
  }
3655
3740
  if (this.options.persistentParameters === true) {
3656
3741
  if (inputPath.indexOf('?') === -1 && this.queryParams) {
3657
3742
  inputPath += `?${this.queryParams}`
3658
3743
  }
3659
- }
3660
- else {
3661
- this.currentParams = {}
3662
- }
3744
+ }
3663
3745
  if (this.usesHTMLSuffix === true) {
3664
3746
  if (inputPath.indexOf('?') === -1) {
3665
3747
  inputPath = `?view=${inputPath}`
@@ -3680,7 +3762,11 @@ class WebsyRouter {
3680
3762
  inputPath = parts[0]
3681
3763
  }
3682
3764
  else if (group === this.options.defaultGroup) {
3683
- this.currentParams = {}
3765
+ this.previousParams = Object.assign({}, this.currentParams)
3766
+ this.currentParams = {
3767
+ path: '',
3768
+ items: {}
3769
+ }
3684
3770
  }
3685
3771
  if (event) {
3686
3772
  if (event.target && event.target.classList.contains(this.options.triggerToggleClass)) {