@websy/websy-designs 1.10.7 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ const bCrypt = require('bcrypt-nodejs')
2
+ const md5 = require('md5')
3
+
4
+ class AuthHelper {
5
+ constructor (dbHelper, options) {
6
+ this.dbHelper = dbHelper
7
+ const DEFAULTS = {
8
+ loginType: 'email'
9
+ }
10
+ this.options = Object.assign({}, DEFAULTS, options)
11
+ // console.log(this.options)
12
+ }
13
+ isLoggedIn (req, res, next) {
14
+ next()
15
+ }
16
+ checkPermissions (req, res, next) {
17
+ next()
18
+ }
19
+ }
20
+
21
+ module.exports = AuthHelper
@@ -221,6 +221,9 @@ class PGHelper {
221
221
  let updates = []
222
222
  for (let key in data) {
223
223
  if (this.updateIgnores.indexOf(key) === -1) {
224
+ if (typeof data[key] === 'string') {
225
+ data[key] = data[key].replace(/''/gm, `'`).replace(/'/gm, `''`).replace(/\\\\/gm, '\\')
226
+ }
224
227
  updates.push(`${key} = ${(data[key] === null ? data[key] : `'${data[key]}'`)}`)
225
228
  }
226
229
  }
@@ -269,9 +272,21 @@ class PGHelper {
269
272
  }
270
273
  else {
271
274
  delete row[(this.options.entityConfig[entity] && this.options.entityConfig[entity].idColumn) || 'id']
275
+ let sqlValues = Object.values(row).map(d => {
276
+ if (d === null) {
277
+ return d
278
+ }
279
+ else {
280
+ if (typeof d === 'string') {
281
+ d = d.replace(/'/g, `''`)
282
+ }
283
+ return `'${d}'`
284
+ // (d === null ? `${d}` : `'${d.replace(/'/)}'`)
285
+ }
286
+ }).join(',')
272
287
  sql += `
273
288
  INSERT INTO ${entity} (${Object.keys(row).join(',')})
274
- VALUES (${Object.values(row).map(d => (d === null ? `${d}` : `'${d}'`)).join(',')})
289
+ VALUES (${sqlValues})
275
290
  RETURNING ${(this.options.entityConfig[entity] && this.options.entityConfig[entity].idColumn) || 'id'};
276
291
  `
277
292
  }
@@ -24,10 +24,12 @@ module.exports = function (options) {
24
24
  process.env.wdRoot = __dirname
25
25
  let version = options.version || 'v1'
26
26
  process.env.WD_VERSION = version
27
- app.use(bodyParser.json({limit: '5mb'}))
28
- app.use(bodyParser.urlencoded({limit: '5mb', extended: true}))
29
- app.use(bodyParser.raw({limit: '5mb'}))
27
+ console.log('max body size is', options.maxBodySize)
28
+ app.use(bodyParser.json({limit: options.maxBodySize || '5mb'}))
29
+ app.use(bodyParser.urlencoded({limit: options.maxBodySize || '5mb', extended: true}))
30
+ app.use(bodyParser.raw({limit: options.maxBodySize || '5mb'}))
30
31
  const AuthHelper = require(`./helpers/${version}/authHelper`)
32
+ const NoAuthHelper = require(`./helpers/${version}/noAuthHelper`)
31
33
  const allowCrossDomain = (req, res, next) => {
32
34
  // console.log(req.url);
33
35
  // const allowedOrigins = ['https://www.google.com', 'http://localhost:4000', 'https://localhost:4000', 'http://ec2-3-92-185-52.compute-1.amazonaws.com', 'https://ec2-3-92-185-52.compute-1.amazonaws.com']
@@ -128,6 +130,9 @@ module.exports = function (options) {
128
130
  }
129
131
  app.use('/auth', require(`./routes/${version}/auth`)(dbHelper, options.dbEngine, app, options.strategy))
130
132
  }
133
+ else {
134
+ app.authHelper = new NoAuthHelper()
135
+ }
131
136
  const protectedRoutes = function (req, res, next) {
132
137
  let secureRoutes = true
133
138
  if (process.env.SECURE_ROUTES) {
@@ -1909,6 +1909,7 @@ class WebsyDropdown {
1909
1909
  const headerPos = WebsyUtils.getElementPos(headerEl)
1910
1910
  const contentPos = WebsyUtils.getElementPos(contentEl)
1911
1911
  if (this.options.style === 'plain' && headerPos.width > 0 && headerPos.height > 0) {
1912
+ contentEl.style.left = 'unset'
1912
1913
  contentEl.style.right = `calc(100vw - ${headerPos.right}px)`
1913
1914
  contentEl.style.width = `${Math.max(this.options.minWidth, headerEl.clientWidth)}px`
1914
1915
  if (headerPos.bottom + contentPos.height > window.innerHeight) {
@@ -1921,6 +1922,7 @@ class WebsyDropdown {
1921
1922
  }
1922
1923
  else if (this.options.style === 'plain' && headerPos.width === 0 && headerPos.height === 0) {
1923
1924
  const targetPos = WebsyUtils.getElementPos(event.target)
1925
+ contentEl.style.left = 'unset'
1924
1926
  contentEl.style.right = `calc(100vw - ${targetPos.right}px)`
1925
1927
  contentEl.style.width = `${Math.max(this.options.minWidth, targetPos.width)}px`
1926
1928
  }
@@ -2486,7 +2488,7 @@ class WebsyForm {
2486
2488
  if (f.component) {
2487
2489
  componentsToProcess.push(f)
2488
2490
  html += `
2489
- ${i > 0 ? '-->' : ''}<div id='${this.elementId}_${f.field}_inputContainer' style='${f.style || ''}' class='websy-input-container ${f.classes ? f.classes.join(' ') : ''}'>
2491
+ ${i > 0 ? '-->' : ''}<div id='${this.elementId}_${f.field}_inputContainer' style='${f.style || ''}' class='websy-input-container ${f.classes ? f.classes.join(' ') : ''} ${f.component === 'MediaUpload' ? 'media-upload' : ''}'>
2490
2492
  ${f.label ? `<label for="${f.field}">${f.label}</label>` : ''}${f.required === true ? '<span class="websy-form-required-value">*</span>' : ''}
2491
2493
  <div id='${this.elementId}_input_${f.field}_component' class='form-component'></div>
2492
2494
  <span id='${this.elementId}_${f.field}_error' class='websy-form-validation-error'></span>
@@ -2506,7 +2508,7 @@ class WebsyForm {
2506
2508
  name="${f.field}"
2507
2509
  ${(f.attributes || []).join(' ')}
2508
2510
  class="websy-input websy-textarea"
2509
- ></textarea>
2511
+ >${f.value || ''}</textarea>
2510
2512
  <span id='${this.elementId}_${f.field}_error' class='websy-form-validation-error'></span>
2511
2513
  </div><!--
2512
2514
  `
@@ -2525,7 +2527,7 @@ class WebsyForm {
2525
2527
  ${(f.attributes || []).join(' ')}
2526
2528
  name="${f.field}"
2527
2529
  placeholder="${f.placeholder || ''}"
2528
- value="${f.value || ''}"
2530
+ value="${f.type === 'date' ? '' : f.value || ''}"
2529
2531
  valueAsDate="${f.type === 'date' ? f.value : ''}"
2530
2532
  oninvalidx="this.setCustomValidity('${f.invalidMessage || 'Please fill in this field.'}')"
2531
2533
  />
@@ -2573,6 +2575,9 @@ class WebsyForm {
2573
2575
  if (this.fieldMap[field].type === 'checkbox') {
2574
2576
  el.checked = value
2575
2577
  }
2578
+ if (this.fieldMap[field].type === 'date') {
2579
+ el.valueAsDate = value
2580
+ }
2576
2581
  }
2577
2582
  else {
2578
2583
  console.error(`Input for ${field} does not exist in form.`)
@@ -2717,10 +2722,12 @@ class MultiForm {
2717
2722
  constructor (elementId, options) {
2718
2723
  this.elementId = elementId
2719
2724
  const DEFAULTS = {
2720
- addButton: `<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 512 512"><line x1="256" y1="112" x2="256" y2="400" style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/><line x1="400" y1="256" x2="112" y2="256" style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/></svg>`,
2721
- deleteButton: `<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 512 512"><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>`,
2725
+ addIcon: `<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 512 512"><line x1="256" y1="112" x2="256" y2="400" style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/><line x1="400" y1="256" x2="112" y2="256" style="fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px"/></svg>`,
2726
+ deleteIcon: `<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="0 0 512 512"><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>`,
2722
2727
  allowAdd: true,
2723
- allowDelete: true
2728
+ allowDelete: true,
2729
+ addLabel: '',
2730
+ deleteLabel: ''
2724
2731
  }
2725
2732
  this.options = Object.assign({}, DEFAULTS, options)
2726
2733
  this.formData = []
@@ -2729,7 +2736,12 @@ class MultiForm {
2729
2736
  const el = document.getElementById(elementId)
2730
2737
  if (el) {
2731
2738
  el.addEventListener('click', this.handleClick.bind(this))
2732
- el.innerHTML = `<div id='${elementId}_container' class='websy-multi-form-container'></div>`
2739
+ el.innerHTML = `
2740
+ <div id='${elementId}_container' class='websy-multi-form-container'></div>
2741
+ <button id='${this.elementId}_addButton' class='websy-multi-form-add'>
2742
+ ${this.options.addIcon}${this.options.addLabel}
2743
+ </button>
2744
+ `
2733
2745
  }
2734
2746
  this.render()
2735
2747
  }
@@ -2738,24 +2750,28 @@ class MultiForm {
2738
2750
  this.render()
2739
2751
  }
2740
2752
  addEntry () {
2741
- const el = document.getElementById(`${this.elementId}_container`)
2742
- let newId = WebsyDesigns.Utils.createIdentity()
2743
- const newFormEl = document.createElement('div')
2744
- newFormEl.id = `${this.elementId}_${newId}_formContainer`
2745
- newFormEl.classList.add('websy-multi-form-form-container')
2746
- newFormEl.innerHTML = `
2747
- <div id='${this.elementId}_${newId}_form' class='websy-multi-form-form'>
2748
- </div>
2749
- <button id='${this.elementId}_${newId}_deleteButton' data-formid='${newId}' class='hidden websy-multi-form-delete'>
2750
- ${this.options.deleteButton}
2751
- </button>
2752
- <button id='${this.elementId}_${newId}_addButton' data-formid='${newId}' class='websy-multi-form-add'>
2753
- ${this.options.addButton}
2754
- </button>
2755
- `
2756
- el.appendChild(newFormEl)
2757
- let formOptions = Object.assign({}, this.options, { fields: [...this.options.fields.map(f => Object.assign({}, f))] })
2758
- this.forms.push(new WebsyDesigns.Form(`${this.elementId}_${newId}_form`, formOptions))
2753
+ const addEl = document.getElementById(`${this.elementId}_addButton`)
2754
+ if (typeof this.options.maxRows === 'undefined' || this.forms.length < this.options.maxRows) {
2755
+ const el = document.getElementById(`${this.elementId}_container`)
2756
+ let newId = WebsyDesigns.Utils.createIdentity()
2757
+ const newFormEl = document.createElement('div')
2758
+ newFormEl.id = `${this.elementId}_${newId}_formContainer`
2759
+ newFormEl.classList.add('websy-multi-form-form-container')
2760
+ let html = `
2761
+ <div id='${this.elementId}_${newId}_form' class='websy-multi-form-form'>
2762
+ </div>
2763
+ <button id='${this.elementId}_${newId}_deleteButton' data-formid='${newId}' class='websy-multi-form-delete'>
2764
+ ${this.options.deleteIcon}${this.options.deleteLabel}
2765
+ </button>
2766
+ `
2767
+ newFormEl.innerHTML = html
2768
+ el.appendChild(newFormEl)
2769
+ let formOptions = Object.assign({}, this.options, { fields: [...this.options.fields.map(f => Object.assign({}, f))] })
2770
+ this.forms.push(new WebsyDesigns.Form(`${this.elementId}_${newId}_form`, formOptions))
2771
+ if (addEl) {
2772
+ addEl.style.display = this.forms.length < this.options.maxRows ? 'flex' : 'none'
2773
+ }
2774
+ }
2759
2775
  }
2760
2776
  clear () {
2761
2777
  this.formData = []
@@ -2767,12 +2783,7 @@ class MultiForm {
2767
2783
  }
2768
2784
  }
2769
2785
  get data () {
2770
- const d = this.forms.map(f => (f.data))
2771
- console.log('forms data', d)
2772
- if (this.options.allowAdd !== false) {
2773
- // we don't return the last form
2774
- d.pop()
2775
- }
2786
+ const d = this.forms.map(f => (f.data))
2776
2787
  return d
2777
2788
  }
2778
2789
  set data (d) {
@@ -2784,16 +2795,6 @@ class MultiForm {
2784
2795
  }
2785
2796
  handleClick (event) {
2786
2797
  if (event.target.classList.contains('websy-multi-form-add')) {
2787
- let id = event.target.getAttribute('data-formid')
2788
- // hide add button and show delete button
2789
- const addButtonEl = document.getElementById(`${this.elementId}_${id}_addButton`)
2790
- if (addButtonEl) {
2791
- addButtonEl.classList.add('hidden')
2792
- }
2793
- const deleteButtonEl = document.getElementById(`${this.elementId}_${id}_deleteButton`)
2794
- if (deleteButtonEl) {
2795
- deleteButtonEl.classList.remove('hidden')
2796
- }
2797
2798
  // add new form
2798
2799
  if (this.options.allowAdd === true) {
2799
2800
  this.addEntry()
@@ -2818,6 +2819,10 @@ class MultiForm {
2818
2819
  if (el) {
2819
2820
  el.remove()
2820
2821
  }
2822
+ const addEl = document.getElementById(`${this.elementId}_addButton`)
2823
+ if (addEl) {
2824
+ addEl.style.display = (typeof this.options.maxRows === 'undefined' || this.forms.length < this.options.maxRows) ? 'flex' : 'none'
2825
+ }
2821
2826
  // delete form element based on id
2822
2827
  }
2823
2828
  }
@@ -2837,7 +2842,7 @@ class MultiForm {
2837
2842
  if (this.options.allowDelete === true) {
2838
2843
  html += `
2839
2844
  <button id='${this.elementId}_${d.formId}_deleteButton' data-formid='${d.formId}' data-rowid='${d.id}' class='websy-multi-form-delete'>
2840
- ${this.options.deleteButton}
2845
+ ${this.options.deleteIcon}${this.options.deleteLabel}
2841
2846
  </button>
2842
2847
  `
2843
2848
  }
@@ -2846,20 +2851,6 @@ class MultiForm {
2846
2851
  `
2847
2852
  })
2848
2853
  let id = WebsyDesigns.Utils.createIdentity()
2849
- if (this.options.allowAdd === true) {
2850
- html += `
2851
- <div id='${this.elementId}_${id}_formContainer' class='websy-multi-form-form-container'>
2852
- <div id='${this.elementId}_${id}_form' class='websy-multi-form-form'>
2853
- </div>
2854
- <button id='${this.elementId}_${id}_deleteButton' data-formid='${id}' class='hidden websy-multi-form-delete'>
2855
- ${this.options.deleteButton}
2856
- </button>
2857
- <button id='${this.elementId}_${id}_addButton' data-formid='${id}' class='websy-multi-form-add'>
2858
- ${this.options.addButton}
2859
- </button>
2860
- </div>
2861
- `
2862
- }
2863
2854
  el.innerHTML = html
2864
2855
  this.forms = new Array(this.formData.length)
2865
2856
  this.formData.forEach((d, i) => {
@@ -2868,11 +2859,15 @@ class MultiForm {
2868
2859
  formObject.data = d
2869
2860
  this.forms[i] = formObject
2870
2861
  })
2871
- if (this.options.allowAdd === true) {
2872
- let formOptions = Object.assign({}, this.options, { fields: [...this.options.fields.map(f => Object.assign({}, f))] })
2873
- let formObject = new WebsyDesigns.Form(`${this.elementId}_${id}_form`, formOptions)
2874
- this.forms.push(formObject)
2875
- }
2862
+ const addEl = document.getElementById(`${this.elementId}_addButton`)
2863
+ if (addEl) {
2864
+ if (this.options.allowAdd === true) {
2865
+ addEl.style.display = (typeof this.options.maxRows === 'undefined' || this.forms.length < this.options.maxRows) ? 'flex' : 'none'
2866
+ }
2867
+ else {
2868
+ addEl.style.display = 'none'
2869
+ }
2870
+ }
2876
2871
  }
2877
2872
  }
2878
2873
  validateForm () {
@@ -1882,6 +1882,7 @@ var WebsyDropdown = /*#__PURE__*/function () {
1882
1882
  var headerPos = WebsyUtils.getElementPos(headerEl);
1883
1883
  var contentPos = WebsyUtils.getElementPos(contentEl);
1884
1884
  if (this.options.style === 'plain' && headerPos.width > 0 && headerPos.height > 0) {
1885
+ contentEl.style.left = 'unset';
1885
1886
  contentEl.style.right = "calc(100vw - ".concat(headerPos.right, "px)");
1886
1887
  contentEl.style.width = "".concat(Math.max(this.options.minWidth, headerEl.clientWidth), "px");
1887
1888
  if (headerPos.bottom + contentPos.height > window.innerHeight) {
@@ -1892,6 +1893,7 @@ var WebsyDropdown = /*#__PURE__*/function () {
1892
1893
  }
1893
1894
  } else if (this.options.style === 'plain' && headerPos.width === 0 && headerPos.height === 0) {
1894
1895
  var targetPos = WebsyUtils.getElementPos(event.target);
1896
+ contentEl.style.left = 'unset';
1895
1897
  contentEl.style.right = "calc(100vw - ".concat(targetPos.right, "px)");
1896
1898
  contentEl.style.width = "".concat(Math.max(this.options.minWidth, targetPos.width), "px");
1897
1899
  }
@@ -2516,11 +2518,11 @@ var WebsyForm = /*#__PURE__*/function () {
2516
2518
  f.owningElement = _this18.elementId;
2517
2519
  if (f.component) {
2518
2520
  componentsToProcess.push(f);
2519
- html += "\n ".concat(i > 0 ? '-->' : '', "<div id='").concat(_this18.elementId, "_").concat(f.field, "_inputContainer' style='").concat(f.style || '', "' class='websy-input-container ").concat(f.classes ? f.classes.join(' ') : '', "'>\n ").concat(f.label ? "<label for=\"".concat(f.field, "\">").concat(f.label, "</label>") : '').concat(f.required === true ? '<span class="websy-form-required-value">*</span>' : '', "\n <div id='").concat(_this18.elementId, "_input_").concat(f.field, "_component' class='form-component'></div>\n <span id='").concat(_this18.elementId, "_").concat(f.field, "_error' class='websy-form-validation-error'></span>\n </div><!--\n ");
2521
+ html += "\n ".concat(i > 0 ? '-->' : '', "<div id='").concat(_this18.elementId, "_").concat(f.field, "_inputContainer' style='").concat(f.style || '', "' class='websy-input-container ").concat(f.classes ? f.classes.join(' ') : '', " ").concat(f.component === 'MediaUpload' ? 'media-upload' : '', "'>\n ").concat(f.label ? "<label for=\"".concat(f.field, "\">").concat(f.label, "</label>") : '').concat(f.required === true ? '<span class="websy-form-required-value">*</span>' : '', "\n <div id='").concat(_this18.elementId, "_input_").concat(f.field, "_component' class='form-component'></div>\n <span id='").concat(_this18.elementId, "_").concat(f.field, "_error' class='websy-form-validation-error'></span>\n </div><!--\n ");
2520
2522
  } else if (f.type === 'longtext') {
2521
- html += "\n ".concat(i > 0 ? '-->' : '', "<div id='").concat(_this18.elementId, "_").concat(f.field, "_inputContainer' style='").concat(f.style || '', "' class='websy-input-container ").concat(f.classes ? f.classes.join(' ') : '', "'>\n ").concat(f.label ? "<label for=\"".concat(f.field, "\">").concat(f.label, "</label>") : '').concat(f.required === true ? '<span class="websy-form-required-value">*</span>' : '', "\n <textarea\n id=\"").concat(_this18.elementId, "_input_").concat(f.field, "\"\n ").concat(f.required === true ? 'required' : '', " \n placeholder=\"").concat(f.placeholder || '', "\"\n data-user-type=\"").concat(f.type, "\"\n data-index=\"").concat(i, "\"\n name=\"").concat(f.field, "\" \n ").concat((f.attributes || []).join(' '), "\n class=\"websy-input websy-textarea\"\n ></textarea>\n <span id='").concat(_this18.elementId, "_").concat(f.field, "_error' class='websy-form-validation-error'></span>\n </div><!--\n ");
2523
+ html += "\n ".concat(i > 0 ? '-->' : '', "<div id='").concat(_this18.elementId, "_").concat(f.field, "_inputContainer' style='").concat(f.style || '', "' class='websy-input-container ").concat(f.classes ? f.classes.join(' ') : '', "'>\n ").concat(f.label ? "<label for=\"".concat(f.field, "\">").concat(f.label, "</label>") : '').concat(f.required === true ? '<span class="websy-form-required-value">*</span>' : '', "\n <textarea\n id=\"").concat(_this18.elementId, "_input_").concat(f.field, "\"\n ").concat(f.required === true ? 'required' : '', " \n placeholder=\"").concat(f.placeholder || '', "\"\n data-user-type=\"").concat(f.type, "\"\n data-index=\"").concat(i, "\"\n name=\"").concat(f.field, "\" \n ").concat((f.attributes || []).join(' '), "\n class=\"websy-input websy-textarea\"\n >").concat(f.value || '', "</textarea>\n <span id='").concat(_this18.elementId, "_").concat(f.field, "_error' class='websy-form-validation-error'></span>\n </div><!--\n ");
2522
2524
  } else {
2523
- html += "\n ".concat(i > 0 ? '-->' : '', "<div id='").concat(_this18.elementId, "_").concat(f.field, "_inputContainer' style='").concat(f.style || '', "' class='websy-input-container ").concat(f.classes ? f.classes.join(' ') : '', "'>\n ").concat(f.label ? "<label for=\"".concat(f.field, "\">").concat(f.label, "</label>") : '').concat(f.required === true ? '<span class="websy-form-required-value">*</span>' : '', "\n <input \n id=\"").concat(_this18.elementId, "_input_").concat(f.field, "\"\n ").concat(f.required === true ? 'required' : '', " \n type=\"").concat((f.type === 'expiry' ? 'text' : f.type === 'cvv' ? 'number' : f.type) || 'text', "\" \n data-user-type=\"").concat(f.type, "\"\n data-index=\"").concat(i, "\"\n class=\"websy-input\" \n ").concat((f.attributes || []).join(' '), "\n name=\"").concat(f.field, "\" \n placeholder=\"").concat(f.placeholder || '', "\"\n value=\"").concat(f.value || '', "\"\n valueAsDate=\"").concat(f.type === 'date' ? f.value : '', "\"\n oninvalidx=\"this.setCustomValidity('").concat(f.invalidMessage || 'Please fill in this field.', "')\"\n />\n <span id='").concat(_this18.elementId, "_").concat(f.field, "_error' class='websy-form-validation-error'></span>\n </div><!--\n ");
2525
+ html += "\n ".concat(i > 0 ? '-->' : '', "<div id='").concat(_this18.elementId, "_").concat(f.field, "_inputContainer' style='").concat(f.style || '', "' class='websy-input-container ").concat(f.classes ? f.classes.join(' ') : '', "'>\n ").concat(f.label ? "<label for=\"".concat(f.field, "\">").concat(f.label, "</label>") : '').concat(f.required === true ? '<span class="websy-form-required-value">*</span>' : '', "\n <input \n id=\"").concat(_this18.elementId, "_input_").concat(f.field, "\"\n ").concat(f.required === true ? 'required' : '', " \n type=\"").concat((f.type === 'expiry' ? 'text' : f.type === 'cvv' ? 'number' : f.type) || 'text', "\" \n data-user-type=\"").concat(f.type, "\"\n data-index=\"").concat(i, "\"\n class=\"websy-input\" \n ").concat((f.attributes || []).join(' '), "\n name=\"").concat(f.field, "\" \n placeholder=\"").concat(f.placeholder || '', "\"\n value=\"").concat(f.type === 'date' ? '' : f.value || '', "\"\n valueAsDate=\"").concat(f.type === 'date' ? f.value : '', "\"\n oninvalidx=\"this.setCustomValidity('").concat(f.invalidMessage || 'Please fill in this field.', "')\"\n />\n <span id='").concat(_this18.elementId, "_").concat(f.field, "_error' class='websy-form-validation-error'></span>\n </div><!--\n ");
2524
2526
  }
2525
2527
  });
2526
2528
  if (this.options.useRecaptcha === true) {
@@ -2553,6 +2555,9 @@ var WebsyForm = /*#__PURE__*/function () {
2553
2555
  if (this.fieldMap[field].type === 'checkbox') {
2554
2556
  el.checked = value;
2555
2557
  }
2558
+ if (this.fieldMap[field].type === 'date') {
2559
+ el.valueAsDate = value;
2560
+ }
2556
2561
  } else {
2557
2562
  console.error("Input for ".concat(field, " does not exist in form."));
2558
2563
  }
@@ -2702,10 +2707,12 @@ var MultiForm = /*#__PURE__*/function () {
2702
2707
  _classCallCheck(this, MultiForm);
2703
2708
  this.elementId = elementId;
2704
2709
  var DEFAULTS = {
2705
- addButton: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 512 512\"><line x1=\"256\" y1=\"112\" x2=\"256\" y2=\"400\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px\"/><line x1=\"400\" y1=\"256\" x2=\"112\" y2=\"256\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px\"/></svg>",
2706
- deleteButton: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 512 512\"><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>",
2710
+ addIcon: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 512 512\"><line x1=\"256\" y1=\"112\" x2=\"256\" y2=\"400\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px\"/><line x1=\"400\" y1=\"256\" x2=\"112\" y2=\"256\" style=\"fill:none;stroke-linecap:round;stroke-linejoin:round;stroke-width:32px\"/></svg>",
2711
+ deleteIcon: "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"40\" height=\"40\" viewBox=\"0 0 512 512\"><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>",
2707
2712
  allowAdd: true,
2708
- allowDelete: true
2713
+ allowDelete: true,
2714
+ addLabel: '',
2715
+ deleteLabel: ''
2709
2716
  };
2710
2717
  this.options = _extends({}, DEFAULTS, options);
2711
2718
  this.formData = [];
@@ -2714,7 +2721,7 @@ var MultiForm = /*#__PURE__*/function () {
2714
2721
  var el = document.getElementById(elementId);
2715
2722
  if (el) {
2716
2723
  el.addEventListener('click', this.handleClick.bind(this));
2717
- el.innerHTML = "<div id='".concat(elementId, "_container' class='websy-multi-form-container'></div>");
2724
+ el.innerHTML = "\n <div id='".concat(elementId, "_container' class='websy-multi-form-container'></div>\n <button id='").concat(this.elementId, "_addButton' class='websy-multi-form-add'>\n ").concat(this.options.addIcon).concat(this.options.addLabel, "\n </button> \n ");
2718
2725
  }
2719
2726
  this.render();
2720
2727
  }
@@ -2727,19 +2734,26 @@ var MultiForm = /*#__PURE__*/function () {
2727
2734
  }, {
2728
2735
  key: "addEntry",
2729
2736
  value: function addEntry() {
2730
- var el = document.getElementById("".concat(this.elementId, "_container"));
2731
- var newId = WebsyDesigns.Utils.createIdentity();
2732
- var newFormEl = document.createElement('div');
2733
- newFormEl.id = "".concat(this.elementId, "_").concat(newId, "_formContainer");
2734
- newFormEl.classList.add('websy-multi-form-form-container');
2735
- newFormEl.innerHTML = "\n <div id='".concat(this.elementId, "_").concat(newId, "_form' class='websy-multi-form-form'>\n </div>\n <button id='").concat(this.elementId, "_").concat(newId, "_deleteButton' data-formid='").concat(newId, "' class='hidden websy-multi-form-delete'>\n ").concat(this.options.deleteButton, "\n </button> \n <button id='").concat(this.elementId, "_").concat(newId, "_addButton' data-formid='").concat(newId, "' class='websy-multi-form-add'>\n ").concat(this.options.addButton, "\n </button> \n ");
2736
- el.appendChild(newFormEl);
2737
- var formOptions = _extends({}, this.options, {
2738
- fields: _toConsumableArray(this.options.fields.map(function (f) {
2739
- return _extends({}, f);
2740
- }))
2741
- });
2742
- this.forms.push(new WebsyDesigns.Form("".concat(this.elementId, "_").concat(newId, "_form"), formOptions));
2737
+ var addEl = document.getElementById("".concat(this.elementId, "_addButton"));
2738
+ if (typeof this.options.maxRows === 'undefined' || this.forms.length < this.options.maxRows) {
2739
+ var el = document.getElementById("".concat(this.elementId, "_container"));
2740
+ var newId = WebsyDesigns.Utils.createIdentity();
2741
+ var newFormEl = document.createElement('div');
2742
+ newFormEl.id = "".concat(this.elementId, "_").concat(newId, "_formContainer");
2743
+ newFormEl.classList.add('websy-multi-form-form-container');
2744
+ var html = "\n <div id='".concat(this.elementId, "_").concat(newId, "_form' class='websy-multi-form-form'>\n </div>\n <button id='").concat(this.elementId, "_").concat(newId, "_deleteButton' data-formid='").concat(newId, "' class='websy-multi-form-delete'>\n ").concat(this.options.deleteIcon).concat(this.options.deleteLabel, "\n </button>\n ");
2745
+ newFormEl.innerHTML = html;
2746
+ el.appendChild(newFormEl);
2747
+ var formOptions = _extends({}, this.options, {
2748
+ fields: _toConsumableArray(this.options.fields.map(function (f) {
2749
+ return _extends({}, f);
2750
+ }))
2751
+ });
2752
+ this.forms.push(new WebsyDesigns.Form("".concat(this.elementId, "_").concat(newId, "_form"), formOptions));
2753
+ if (addEl) {
2754
+ addEl.style.display = this.forms.length < this.options.maxRows ? 'flex' : 'none';
2755
+ }
2756
+ }
2743
2757
  }
2744
2758
  }, {
2745
2759
  key: "clear",
@@ -2758,11 +2772,6 @@ var MultiForm = /*#__PURE__*/function () {
2758
2772
  var d = this.forms.map(function (f) {
2759
2773
  return f.data;
2760
2774
  });
2761
- console.log('forms data', d);
2762
- if (this.options.allowAdd !== false) {
2763
- // we don't return the last form
2764
- d.pop();
2765
- }
2766
2775
  return d;
2767
2776
  },
2768
2777
  set: function set(d) {
@@ -2781,16 +2790,6 @@ var MultiForm = /*#__PURE__*/function () {
2781
2790
  key: "handleClick",
2782
2791
  value: function handleClick(event) {
2783
2792
  if (event.target.classList.contains('websy-multi-form-add')) {
2784
- var id = event.target.getAttribute('data-formid');
2785
- // hide add button and show delete button
2786
- var addButtonEl = document.getElementById("".concat(this.elementId, "_").concat(id, "_addButton"));
2787
- if (addButtonEl) {
2788
- addButtonEl.classList.add('hidden');
2789
- }
2790
- var deleteButtonEl = document.getElementById("".concat(this.elementId, "_").concat(id, "_deleteButton"));
2791
- if (deleteButtonEl) {
2792
- deleteButtonEl.classList.remove('hidden');
2793
- }
2794
2793
  // add new form
2795
2794
  if (this.options.allowAdd === true) {
2796
2795
  this.addEntry();
@@ -2798,12 +2797,12 @@ var MultiForm = /*#__PURE__*/function () {
2798
2797
  }
2799
2798
  if (event.target.classList.contains('websy-multi-form-delete')) {
2800
2799
  // delete form based on index
2801
- var _id = event.target.getAttribute('data-formid');
2800
+ var id = event.target.getAttribute('data-formid');
2802
2801
  var rowId = event.target.getAttribute('data-rowid');
2803
2802
  this.recordsToDelete.push(rowId);
2804
2803
  var indexToDelete = -1;
2805
2804
  for (var i = 0; i < this.forms.length; i++) {
2806
- if (this.forms[i].elementId === "".concat(this.elementId, "_").concat(_id, "_form")) {
2805
+ if (this.forms[i].elementId === "".concat(this.elementId, "_").concat(id, "_form")) {
2807
2806
  indexToDelete = i;
2808
2807
  break;
2809
2808
  }
@@ -2811,10 +2810,14 @@ var MultiForm = /*#__PURE__*/function () {
2811
2810
  if (indexToDelete !== -1) {
2812
2811
  this.forms.splice(indexToDelete, 1);
2813
2812
  }
2814
- var el = document.getElementById("".concat(this.elementId, "_").concat(_id, "_formContainer"));
2813
+ var el = document.getElementById("".concat(this.elementId, "_").concat(id, "_formContainer"));
2815
2814
  if (el) {
2816
2815
  el.remove();
2817
2816
  }
2817
+ var addEl = document.getElementById("".concat(this.elementId, "_addButton"));
2818
+ if (addEl) {
2819
+ addEl.style.display = typeof this.options.maxRows === 'undefined' || this.forms.length < this.options.maxRows ? 'flex' : 'none';
2820
+ }
2818
2821
  // delete form element based on id
2819
2822
  }
2820
2823
  }
@@ -2831,14 +2834,11 @@ var MultiForm = /*#__PURE__*/function () {
2831
2834
  d.formId = WebsyDesigns.Utils.createIdentity();
2832
2835
  html += "\n <div id='".concat(_this21.elementId, "_").concat(d.formId, "_formContainer' class='websy-multi-form-form-container'>\n <div id='").concat(_this21.elementId, "_").concat(d.formId, "_form' class='websy-multi-form-form'>\n </div>\n ");
2833
2836
  if (_this21.options.allowDelete === true) {
2834
- html += "\n <button id='".concat(_this21.elementId, "_").concat(d.formId, "_deleteButton' data-formid='").concat(d.formId, "' data-rowid='").concat(d.id, "' class='websy-multi-form-delete'>\n ").concat(_this21.options.deleteButton, "\n </button>\n ");
2837
+ html += "\n <button id='".concat(_this21.elementId, "_").concat(d.formId, "_deleteButton' data-formid='").concat(d.formId, "' data-rowid='").concat(d.id, "' class='websy-multi-form-delete'>\n ").concat(_this21.options.deleteIcon).concat(_this21.options.deleteLabel, "\n </button>\n ");
2835
2838
  }
2836
2839
  html += "\n </div>\n ";
2837
2840
  });
2838
2841
  var id = WebsyDesigns.Utils.createIdentity();
2839
- if (this.options.allowAdd === true) {
2840
- html += "\n <div id='".concat(this.elementId, "_").concat(id, "_formContainer' class='websy-multi-form-form-container'>\n <div id='").concat(this.elementId, "_").concat(id, "_form' class='websy-multi-form-form'>\n </div>\n <button id='").concat(this.elementId, "_").concat(id, "_deleteButton' data-formid='").concat(id, "' class='hidden websy-multi-form-delete'>\n ").concat(this.options.deleteButton, "\n </button> \n <button id='").concat(this.elementId, "_").concat(id, "_addButton' data-formid='").concat(id, "' class='websy-multi-form-add'>\n ").concat(this.options.addButton, "\n </button> \n </div>\n ");
2841
- }
2842
2842
  el.innerHTML = html;
2843
2843
  this.forms = new Array(this.formData.length);
2844
2844
  this.formData.forEach(function (d, i) {
@@ -2851,14 +2851,13 @@ var MultiForm = /*#__PURE__*/function () {
2851
2851
  formObject.data = d;
2852
2852
  _this21.forms[i] = formObject;
2853
2853
  });
2854
- if (this.options.allowAdd === true) {
2855
- var formOptions = _extends({}, this.options, {
2856
- fields: _toConsumableArray(this.options.fields.map(function (f) {
2857
- return _extends({}, f);
2858
- }))
2859
- });
2860
- var formObject = new WebsyDesigns.Form("".concat(this.elementId, "_").concat(id, "_form"), formOptions);
2861
- this.forms.push(formObject);
2854
+ var addEl = document.getElementById("".concat(this.elementId, "_addButton"));
2855
+ if (addEl) {
2856
+ if (this.options.allowAdd === true) {
2857
+ addEl.style.display = typeof this.options.maxRows === 'undefined' || this.forms.length < this.options.maxRows ? 'flex' : 'none';
2858
+ } else {
2859
+ addEl.style.display = 'none';
2860
+ }
2862
2861
  }
2863
2862
  }
2864
2863
  }