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.

149 lines
3.4 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
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. *
  42. */
  43. setConstraits(constraits)
  44. {
  45. this.constraits = constraits
  46. }
  47. /**
  48. *
  49. *
  50. */
  51. getConstraits(constraits)
  52. {
  53. return this.constraits
  54. }
  55. /**
  56. *
  57. * @param {[type]} event [description]
  58. * @return {[type]} [description]
  59. */
  60. onSubmit(event)
  61. {
  62. event.preventDefault()
  63. let errors = validate.async(serialize(event.target, {
  64. hash: true
  65. }), this.constraits, {
  66. fullMessages: false
  67. }).then(
  68. () => {
  69. this.onSuccess(event, serialize(event.target, {
  70. hash: true
  71. }))
  72. },
  73. (errors) => {
  74. // send each element a event
  75. this.elements.forEach((element) => {
  76. let elementErrors = false
  77. // check for errors by name
  78. if (errors[element.attributes.name.nodeValue]) {
  79. elementErrors = errors[element.attributes.name.nodeValue]
  80. }
  81. this.dispatchCustomEvent(elementErrors, element)
  82. })
  83. }
  84. )
  85. }
  86. /**
  87. *
  88. *
  89. * @param {Event} event
  90. *
  91. */
  92. onFieldUpdate(event)
  93. {
  94. // workaround, make sure that value for single is undefined if it is empty
  95. if (event.detail.value == '') {
  96. event.detail.value = undefined
  97. }
  98. let errors = validate.single(event.detail.value, this.constraits[event.detail.name])
  99. // search for element by name and dispatch event
  100. this.elements.forEach((element) => {
  101. if (element.attributes.name.nodeValue == event.detail.name) {
  102. this.dispatchCustomEvent(errors, element)
  103. }
  104. })
  105. }
  106. /**
  107. * dispatch event to single element
  108. *
  109. * @param {Array} errors
  110. * @param {Element} element
  111. *
  112. */
  113. dispatchCustomEvent(errors, element)
  114. {
  115. let detail = false
  116. if (errors) {
  117. detail = errors
  118. }
  119. const formValidationEvent = new CustomEvent('form-validation', {
  120. 'detail': detail
  121. })
  122. element.dispatchEvent(formValidationEvent)
  123. }
  124. }
  125. export default FormValidator