Form Validation е процесът на проверка на коректността на всички полета на формуляра преди изпращане на данни към сървъра. За разлика от валидацията на отделно поле, Form Validation взема предвид взаимните връзки между полетата: потвърждение на парола, зависимост на едно поле от друго, условна задължителност. Според данни на Google Developers, 2026, Form Validation трябва да проверява целия формуляр при изпращане и да предоставя на потребителя обобщение на всички грешки. Коректната валидация на формуляр увеличава конверсията на регистрация с 25-35% и намалява броя на грешките при въвеждане.
Основни точки
Form Validation е процес, който гарантира, че всички данни, въведени от потребителя във формуляра, отговарят на бизнес изискванията преди изпращане към сървъра. Валидацията на формуляр включва проверка на всяко поле поотделно, както и кръстосани проверки: съвпада ли паролата с потвърждението, избрано ли е поне едно квадратче за отметка, попълнени ли са всички задължителни полета, коректна ли е датата (например датата на раждане не е в бъдещето).
Разликата от простата валидация на поле е, че Form Validation оперира с формуляра като единно цяло. Може да блокира изпращането, ако условно поле не е попълнено, или да покаже обобщение на грешките в диалогов прозорец. В сложни формуляри (регистрация, поръчка, анкета) валидацията на формуляр е отделен слой логика, който се тества независимо от UI.
Според UX изследвания на NN Group, потребителите завършват попълването на формуляр 3 пъти по-често, ако видят грешките веднага след изпращане, а не след всяко поле поотделно. Най-добър резултат обаче дава комбинацията: незабавна валидация на прости полета (дължина, формат) + пълна проверка при изпращане за кръстосани полета и бизнес логика.
Валидация на поле отговаря на въпроса: коректно ли е въвеждането в това конкретно поле? Имейлът има формат user@domain.com, телефонът се състои от цифри, паролата е по-дълга от 6 знака. Валидацията на поле е изолирана — не зависи от други полета и може да се изпълнява в реално време. Резултат: грешка за конкретно поле или липса на такава.
Валидация на формуляр отговаря на въпроса: може ли формулярът да бъде изпратен като цяло? Тя взема предвид не само всяко поле, но и техните комбинации: паролата и потвърждението трябва да съвпадат, началната дата не може да бъде по-късна от крайната дата, сумата на полетата трябва да бъде 100%. Валидацията на формуляр се изпълнява при изпращане и връща общ резултат: формулярът е валиден или не.
Архитектурно, валидацията на поле се поставя в UI слоя (фрагмент, ViewModel), а валидацията на формуляр — в домейн слоя (use case, interactor). Това позволява повторно използване на валидацията на формуляр в различни UI компоненти и тестването ѝ без емулатор. В Clean Architecture валидацията на формуляр е бизнес правило, а не UI логика.
| Критерий | Валидация на поле | Валидация на формуляр |
|---|---|---|
| Обект на проверка | Едно поле | Всички полета + техните взаимни връзки |
| Момент на изпълнение | В реално време / при загуба на фокус | При изпращане на формуляр |
| Резултат | Грешка на конкретно поле | Общ статус на формуляра + списък с грешки |
| Архитектурен слой | UI слой | Домейн слой |
Съществуват два основни подхода за Form Validation. Първият — императивен: разработчикът пише функция, която последователно проверява всяко поле и събира списък с грешки. Този подход е лесен за разбиране, но кодът нараства с всяко ново поле. За формуляр с 5 полета императивният подход е все още удобен, за 15 полета — вече проблематичен.
Вторият подход — декларативен: правилата за валидация се описват с анотации или конфигурация. Библиотеката сама обхожда всички полета, прилага правилата и връща резултата. Пример: анотация @Email над полето emailData, @ConfirmPassword над полето за потвърждение. Декларативният подход съкращава кода за валидация 3-5 пъти и го прави четим.
Третият подход — реактивен с използване на RxJava или Kotlin Flow. Всяко поле е представено като Observable или StateFlow. Валидацията на формуляр се абонира за промените на всички полета и преизчислява общото състояние при всяка промяна. Бутонът за изпращане автоматично става активен, когато всички полета са валидни. Този подход изисква разбиране на реактивното програмиране, но предоставя най-плавното UX.
Нека разгледаме регистрационен формуляр с три полета: имейл, парола и потвърждение на парола. Валидацията на формуляр включва: проверка на имейл чрез Patterns.EMAIL_ADDRESS, проверка на парола за минимална дължина от 8 знака и наличие на цифра, проверка на съвпадение на парола и потвърждение. Едва когато и трите проверки преминат, формулярът може да бъде изпратен.
data class RegistrationForm(
val email: String,
val password: String,
val confirmPassword: String
)
fun validateRegistration(form: RegistrationForm): ValidationResult {
if (!Patterns.EMAIL_ADDRESS.matcher(form.email).matches())
return ValidationResult(false, "Invalid email address")
if (form.password.length < 8)
return ValidationResult(false, "Password too short")
if (form.password != form.confirmPassword)
return ValidationResult(false, "Passwords do not match")
return ValidationResult(true)
}
В примера validateRegistration приема data class на формуляра и връща ValidationResult. Ако поне една проверка не премине, се връща false със съответно съобщение. Управлението на бутона за изпращане се основава на Result: ако isValid = true, бутонът е активен. За актуализация на състоянието в реално време може да се използва LiveData<ValidationResult> и да се актуализира бутонът при всяка промяна на което и да е поле.
Реактивният подход с Kotlin Flow позволява автоматично преизчисляване на състоянието на формуляра. Всяко поле е представено като MutableStateFlow<String>, а combine ги обединява в един Flow<ValidationResult>. Абонаментът в UI актуализира бутона за изпращане без ръчно извикване на валидация. Този модел се препоръчва от Google за Jetpack Compose и MVVM архитектура.
Android Saripaar — най-популярната библиотека за валидация за Android. Позволява директно анотиране на полета и View: @Email, @NotEmpty, @Password(min = 8, scheme = Password.Scheme.ALPHA_NUMERIC). Валидацията се извиква с един ред validator.validate() с callback. Saripaar автоматично задава грешката чрез setError на EditText. Библиотеката също поддържа персонализирани анотации за специфични бизнес правила.
RxBinding + RxJava — реактивен подход без отделна библиотека за валидация. Всяко поле публикува промени чрез RxTextView.textChanges(). Операторът combineLatest обединява всички полета и изчислява общия статус. Предимство: пълен контрол над pipeline за валидация, възможност за добавяне на debounce, throttle, filter. Недостатък: изисква познания по RxJava.
Material Design Components — вградена поддръжка за TextInputLayout и TextInputEditText. Библиотеката не предоставя валидация като такава, но дава UI за показване на грешки: setError(), setHelperText(), setCounterEnabled(). За самата валидация все още е необходима ръчна логика или Saripaar. Material Components отговарят за показването, а не за проверката.
Първата грешка — валидация само от страна на клиента. Form Validation от страна на клиента е предназначена за UX, а не за сигурност. Нападател може да изпрати заявка директно към API, заобикаляйки валидацията. Сървърът трябва да провери всички полета отново. Клиентската валидация не трябва да бъде единствената защита — това е допълнителен слой за удобство на потребителя, а не за сигурност на данните.
Втората грешка — блокиране на бутона за изпращане без съобщения. Ако бутонът е неактивен, потребителят трябва да вижда кои полета трябва да коригира. Сив бутон без обяснение — една от най-честите причини за ниска конверсия на формуляри. Винаги показвайте грешките на полетата до тях, дори ако бутонът е блокиран. Потребителят трябва да разбира какво точно пречи на изпращането.
Третата грешка — игнориране на кръстосани полета. Валидацията на всяко поле поотделно не е достатъчна. Полетата могат да зависят едно от друго: парола и потвърждение, начална дата и крайна дата, държава и град. Form Validation трябва да проверява тези взаимни връзки. Проверката само на отделни полета създава фалшиво чувство за сигурност — формулярът може да бъде изпратен с несъгласувани данни.
| Грешка | Последица | Решение |
|---|---|---|
| Само клиентска валидация | Уязвимост на сигурността | Задължителна сървърна проверка |
| Бутон без съобщения | Ниска конверсия на формуляр | Показване на грешките на полетата |
| Без кръстосани проверки | Несъгласувани данни | Валидация на взаимните връзки на полетата |
| Твърде чести проверки | Раздразнение на потребителя | Debounce и проверка при загуба на фокус |
Често задавани въпроси
Валидация на поле проверява една стойност спрямо формат или дължина. Form Validation проверява всички полета заедно, включително кръстосани проверки: съвпадение на пароли, зависимост на полетата едно от друго. Валидацията на поле се изпълнява в UI слоя, Form Validation — в домейн слоя като бизнес правило.
Използвайте реактивен подход: обединете всички полета в един Flow или Observable и се абонирайте за промените. При всяка промяна на което и да е поле, преизчислете общия статус на формуляра. Ако статусът е валиден — бутонът е активен. Използвайте Kotlin Flow с combine или RxJava с combineLatest за автоматично актуализиране.
Android Saripaar — най-добрият избор за декларативна валидация с анотации. Ако проектът използва RxJava — RxBinding осигурява реактивен подход без отделна библиотека. За прости формуляри е достатъчна ръчна валидация с Patterns и TextUtils без външни зависимости.
Задължително. Клиентската валидация подобрява UX, но не осигурява сигурност. Сървърът трябва да провери всички данни отново, тъй като API е директно достъпен. Никога не разчитайте само на клиентска валидация за защита от неправилни или злонамерени данни.
В Jetpack Compose използвайте Kotlin Flow или StateFlow за съхранение на състоянието на всяко поле. Функцията за валидация приема състоянието на формуляра и връща ValidationResult. Бутонът за изпращане се абонира за общия статус. За показване на грешки използвайте isError в OutlinedTextField или TextField Compose.
Резюме
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също