| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- document.head.insertAdjacentHTML('beforeend','<style type="text/tailwindcss" component="FormValidator">'+stylFns['app/shared/FormValidator/index.styl']+'</style>')
- module.exports =
- name: 'FormValidator'
- render: (new Function '_ctx', '_cache', renderFns['app/shared/FormValidator/index.pug'])()
- props:
- fields:
- type: Object
- default: ->
- email: true
- phone: true
- message: true
- file: false
- validationRules:
- type: Object
- default: -> {}
- data: ->
- formData:
- email: ''
- phone: ''
- message: ''
- file: null
- errors: {}
- isSubmitting: false
- isSubmitted: false
- fileInfo: ''
- debounceTimers: {}
- computed:
- isFormValid: ->
- Object.keys(@errors).length == 0 &&
- Object.keys(@formData).some((key) => @formData[key] && @formData[key].toString().trim() != '')
- mounted: ->
- @initializeValidation()
- methods:
- initializeValidation: ->
- # Установка правил валидации по умолчанию
- @defaultRules =
- email:
- required: true
- pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
- message: 'Введите корректный email адрес'
- phone:
- required: true
- pattern: /^\+?[0-9\s\-\(\)]{10,}$/
- message: 'Введите корректный номер телефона'
- message:
- required: true
- minLength: 10
- message: 'Сообщение должно содержать минимум 10 символов'
- file:
- maxSize: 5 * 1024 * 1024 # 5MB
- allowedTypes: ['image/jpeg', 'image/png', 'application/pdf']
- message: 'Файл должен быть JPEG, PNG или PDF, не более 5MB'
- validateField: (fieldName) ->
- rules = @validationRules[fieldName] || @defaultRules[fieldName]
- value = @formData[fieldName]
-
- @errors[fieldName] = ''
-
- if rules.required && (!value || value.toString().trim() == '')
- @errors[fieldName] = 'Это поле обязательно для заполнения'
- return false
-
- if rules.pattern && value && !rules.pattern.test(value)
- @errors[fieldName] = rules.message
- return false
-
- if rules.minLength && value && value.length < rules.minLength
- @errors[fieldName] = rules.message
- return false
-
- true
- debouncedValidate: (fieldName) ->
- clearTimeout @debounceTimers[fieldName] if @debounceTimers[fieldName]
- @debounceTimers[fieldName] = setTimeout =>
- @validateField fieldName
- , 500
- handleFileUpload: (event) ->
- file = event.target.files[0]
- return unless file
-
- rules = @defaultRules.file
- @errors.file = ''
-
- # Проверка типа файла :cite[2]:cite[7]
- if !rules.allowedTypes.includes(file.type)
- @errors.file = 'Разрешены только JPEG, PNG и PDF файлы'
- return
-
- if file.size > rules.maxSize
- @errors.file = 'Файл слишком большой. Максимальный размер: 5MB'
- return
-
- @formData.file = file
- @fileInfo = "#{file.name} (#{(file.size / 1024 / 1024).toFixed(2)} MB)"
- handleSubmit: (event) ->
- event.preventDefault()
-
- # Валидация всех полей
- isValid = true
- for fieldName of @fields
- if @fields[fieldName] && !@validateField(fieldName)
- isValid = false
-
- return unless isValid
-
- @isSubmitting = true
-
- # Имитация отправки
- setTimeout =>
- @isSubmitting = false
- @isSubmitted = true
- @$emit 'form-submitted', @formData
- , 2000
- getFieldClasses: (fieldName) ->
- baseClasses = 'border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 text-gray-900 dark:text-white'
- errorClasses = 'border-red-500 dark:border-red-400 ring-1 ring-red-500 dark:ring-red-400'
- validClasses = 'border-green-500 dark:border-green-400'
-
- if @errors[fieldName]
- return "#{baseClasses} #{errorClasses}"
- else if @formData[fieldName] && @formData[fieldName].toString().trim() != ''
- return "#{baseClasses} #{validClasses}"
- else
- return baseClasses
- emits: ['form-submitted', 'validation-changed']
|