You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.1 KiB

3 years ago
3 years ago
  1. import validate from 'validate.js'
  2. import serialize from 'form-serialize'
  3. /**
  4. * Form Validator with RiotJS Components
  5. *
  6. *
  7. *
  8. *
  9. */
  10. class FormValidator
  11. {
  12. /**
  13. *
  14. * @param {[type]} formSelector [description]
  15. * @param {[type]} constraits [description]
  16. */
  17. constructor(formSelector, constraits, onSuccess)
  18. {
  19. // getting selector to find form-element
  20. this.formSelector = formSelector
  21. // constraits for validate.js
  22. this.constraits = constraits
  23. // get form and elements
  24. this.form = document.querySelector(this.formSelector)
  25. if (!this.form) {
  26. console.error('FormValidator: form not found, querySelector not found "' + this.formSelector + '"')
  27. }
  28. this.elements = this.form.querySelectorAll('field-error')
  29. // adding submit event
  30. this.form.addEventListener('submit', (event) => {
  31. this.onSubmit(event)
  32. })
  33. // adding event if a element is updated
  34. this.form.addEventListener('field-update', (event) => {
  35. this.onFieldUpdate(event)
  36. })
  37. this.onSuccess = onSuccess
  38. }
  39. /**
  40. *
  41. * @param {[type]} event [description]
  42. * @return {[type]} [description]
  43. */
  44. onSubmit(event)
  45. {
  46. event.preventDefault()
  47. let errors = validate(serialize(event.target, {
  48. hash: true
  49. }), this.constraits, {
  50. fullMessages: false
  51. })
  52. if (errors) {
  53. // send each element a event
  54. this.elements.forEach((element) => {
  55. let elementErrors = false
  56. // check for errors by name
  57. if (errors[element.attributes.name.nodeValue]) {
  58. elementErrors = errors[element.attributes.name.nodeValue]
  59. }
  60. this.dispatchCustomEvent(elementErrors, element)
  61. })
  62. } else {
  63. this.onSuccess(event, serialize(event.target, {
  64. hash: true
  65. }))
  66. }
  67. }
  68. /**
  69. *
  70. *
  71. * @param {Event} event
  72. *
  73. */
  74. onFieldUpdate(event)
  75. {
  76. // workaround, make sure that value for single is undefined if it is empty
  77. if (event.detail.value == '') {
  78. event.detail.value = undefined
  79. }
  80. let errors = validate.single(event.detail.value, this.constraits[event.detail.name])
  81. // search for element by name and dispatch event
  82. this.elements.forEach((element) => {
  83. if (element.attributes.name.nodeValue == event.detail.name) {
  84. this.dispatchCustomEvent(errors, element)
  85. }
  86. })
  87. }
  88. /**
  89. * dispatch event to single element
  90. *
  91. * @param {Array} errors
  92. * @param {Element} element
  93. *
  94. */
  95. dispatchCustomEvent(errors, element)
  96. {
  97. let detail = false
  98. if (errors) {
  99. detail = errors
  100. }
  101. const formValidationEvent = new CustomEvent('form-validation', {
  102. 'detail': detail
  103. })
  104. element.dispatchEvent(formValidationEvent)
  105. }
  106. }
  107. export default FormValidator