index.coffee 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. document.head.insertAdjacentHTML('beforeend','<style type="text/tailwindcss" component="FormValidator">'+stylFns['app/shared/FormValidator/index.styl']+'</style>')
  2. module.exports =
  3. name: 'FormValidator'
  4. render: (new Function '_ctx', '_cache', renderFns['app/shared/FormValidator/index.pug'])()
  5. props:
  6. fields:
  7. type: Object
  8. default: ->
  9. email: true
  10. phone: true
  11. message: true
  12. file: false
  13. validationRules:
  14. type: Object
  15. default: -> {}
  16. data: ->
  17. formData:
  18. email: ''
  19. phone: ''
  20. message: ''
  21. file: null
  22. errors: {}
  23. isSubmitting: false
  24. isSubmitted: false
  25. fileInfo: ''
  26. debounceTimers: {}
  27. computed:
  28. isFormValid: ->
  29. Object.keys(@errors).length == 0 &&
  30. Object.keys(@formData).some((key) => @formData[key] && @formData[key].toString().trim() != '')
  31. mounted: ->
  32. @initializeValidation()
  33. methods:
  34. initializeValidation: ->
  35. # Установка правил валидации по умолчанию
  36. @defaultRules =
  37. email:
  38. required: true
  39. pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  40. message: 'Введите корректный email адрес'
  41. phone:
  42. required: true
  43. pattern: /^\+?[0-9\s\-\(\)]{10,}$/
  44. message: 'Введите корректный номер телефона'
  45. message:
  46. required: true
  47. minLength: 10
  48. message: 'Сообщение должно содержать минимум 10 символов'
  49. file:
  50. maxSize: 5 * 1024 * 1024 # 5MB
  51. allowedTypes: ['image/jpeg', 'image/png', 'application/pdf']
  52. message: 'Файл должен быть JPEG, PNG или PDF, не более 5MB'
  53. validateField: (fieldName) ->
  54. rules = @validationRules[fieldName] || @defaultRules[fieldName]
  55. value = @formData[fieldName]
  56. @errors[fieldName] = ''
  57. if rules.required && (!value || value.toString().trim() == '')
  58. @errors[fieldName] = 'Это поле обязательно для заполнения'
  59. return false
  60. if rules.pattern && value && !rules.pattern.test(value)
  61. @errors[fieldName] = rules.message
  62. return false
  63. if rules.minLength && value && value.length < rules.minLength
  64. @errors[fieldName] = rules.message
  65. return false
  66. true
  67. debouncedValidate: (fieldName) ->
  68. clearTimeout @debounceTimers[fieldName] if @debounceTimers[fieldName]
  69. @debounceTimers[fieldName] = setTimeout =>
  70. @validateField fieldName
  71. , 500
  72. handleFileUpload: (event) ->
  73. file = event.target.files[0]
  74. return unless file
  75. rules = @defaultRules.file
  76. @errors.file = ''
  77. # Проверка типа файла :cite[2]:cite[7]
  78. if !rules.allowedTypes.includes(file.type)
  79. @errors.file = 'Разрешены только JPEG, PNG и PDF файлы'
  80. return
  81. if file.size > rules.maxSize
  82. @errors.file = 'Файл слишком большой. Максимальный размер: 5MB'
  83. return
  84. @formData.file = file
  85. @fileInfo = "#{file.name} (#{(file.size / 1024 / 1024).toFixed(2)} MB)"
  86. handleSubmit: (event) ->
  87. event.preventDefault()
  88. # Валидация всех полей
  89. isValid = true
  90. for fieldName of @fields
  91. if @fields[fieldName] && !@validateField(fieldName)
  92. isValid = false
  93. return unless isValid
  94. @isSubmitting = true
  95. # Имитация отправки
  96. setTimeout =>
  97. @isSubmitting = false
  98. @isSubmitted = true
  99. @$emit 'form-submitted', @formData
  100. , 2000
  101. getFieldClasses: (fieldName) ->
  102. baseClasses = 'border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white'
  103. errorClasses = 'border-red-500 dark:border-red-400 ring-1 ring-red-500 dark:ring-red-400'
  104. validClasses = 'border-green-500 dark:border-green-400'
  105. if @errors[fieldName]
  106. return "#{baseClasses} #{errorClasses}"
  107. else if @formData[fieldName] && @formData[fieldName].toString().trim() != ''
  108. return "#{baseClasses} #{validClasses}"
  109. else
  110. return baseClasses
  111. emits: ['form-submitted', 'validation-changed']