input-validator.js 2.3 KB

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