input-validator.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import { isBootstrap5 } from '@/features/utils/bootstrap-5'
  2. import createIcon from '@/features/form-helpers/create-icon'
  3. export default function inputValidator(inputEl) {
  4. const messageEl = document.createElement('div')
  5. messageEl.className =
  6. inputEl.getAttribute('data-ol-validation-message-classes') ||
  7. 'small text-danger mt-2 form-text'
  8. messageEl.hidden = true
  9. const messageInnerEl = messageEl.appendChild(document.createElement('span'))
  10. messageInnerEl.className = 'form-text-inner'
  11. const messageTextNode = document.createTextNode('')
  12. // In Bootstrap 5, add an icon
  13. if (isBootstrap5()) {
  14. const iconEl = createIcon('error')
  15. messageInnerEl.append(iconEl)
  16. }
  17. messageInnerEl.append(messageTextNode)
  18. inputEl.insertAdjacentElement('afterend', messageEl)
  19. // Hide messages until the user leaves the input field or submits the form.
  20. let canDisplayErrorMessages = false
  21. // Handle all kinds of inputs.
  22. inputEl.addEventListener('input', handleUpdate)
  23. inputEl.addEventListener('change', handleUpdate)
  24. // The user has left the input field.
  25. inputEl.addEventListener('blur', displayValidationMessages)
  26. // The user has submitted the form and the current field has errors.
  27. inputEl.addEventListener('invalid', e => {
  28. // Block the display of browser error messages.
  29. e.preventDefault()
  30. // Force the display of messages.
  31. inputEl.setAttribute('data-ol-dirty', '')
  32. displayValidationMessages()
  33. })
  34. function handleUpdate() {
  35. // Mark an input as "dirty": the user has typed something in at some point
  36. inputEl.setAttribute('data-ol-dirty', '')
  37. // Provide live updates to content sensitive error message like this:
  38. // Please include an '@' in the email address. 'foo' is missing an '@'.
  39. // We should not leave a stale message as the user types.
  40. updateValidationMessageContent()
  41. }
  42. function displayValidationMessages() {
  43. // Display all the error messages and highlight fields with red border.
  44. canDisplayErrorMessages = true
  45. updateValidationMessageContent()
  46. }
  47. function updateValidationMessageContent() {
  48. if (!canDisplayErrorMessages) return
  49. if (!inputEl.hasAttribute('data-ol-dirty')) return
  50. if (inputEl.validity.valid) {
  51. messageEl.hidden = true
  52. // Require another blur before displaying errors again.
  53. canDisplayErrorMessages = false
  54. } else {
  55. messageTextNode.data = inputEl.validationMessage
  56. messageEl.hidden = false
  57. }
  58. }
  59. }