Быстрая валидация позволяет декларативно описать в разметке, без применения скриптов, ограничения пользовательского ввода.

Компоненты EditText и MemoEdit обладают атрибутами постусловий валидации::

  • Required - логический, необходимость наличия текста в поле при валидации
  • Length - целое число, максимальная длина текста в поле при валидации
  • Mask - регулярное выражение, применяемое при валидации

Компоненты Button(ver. 2.7)HorizontalLayout(ver. 2.7)VerticalLayout(ver. 2.7)DockLayout(ver. 2.7) обладают атрибутом области валидации: SubmitScope. Перед выполнением события OnClick и OnClickAction производится проверка постусловий тех компонентов, которые перечислены в области валидации. Если хотя бы одно из них не выполняется, событие не вызывается, а соответствующие поля отмечаются сообщением об ошибке.

Пример

Рассмотрим в экран данных контакта (в комментариях к экрану указаны основные требования в вводимым данным): 

<c:Screen xmlns:c="BitMobile.Controls" xmlns:s="BitMobile.ValueStack">
	<c:DockLayout>
		<!-- Каждое поле не должно превышать размер поля в БД-->
		<c:EditText Id="edtName" Placeholder="#name#" /><!-- Имя контакта: обязательно, должно содержать только буквы-->
		<c:VerticalLayout Id="contacts">
			<c:EditText Id="edtEmail" Placeholder="#email#" /> <!-- Почта: обязательно, должна быть валидна -->
			<c:EditText Id="edtPhone" Placeholder="#phone#" /> <!-- Телефон: должен быть валиден -->
			<c:MemoEdit Id="memAddress" Placeholder="#address#" /><!-- Адрес: должен содержать индекс -->
		</c:VerticalLayout>
		<c:MemoEdit Id="memEmployees" Placeholder="#employees#" /><!-- Список персонала через пробел/перенос -->
		<c:HorizontalLayout>
			<c:Button Text="#back#" OnClick="$DoRollback()" OnEvent="Back" />
			<c:Button Text="#save_contact#" OnClick="$SaveContact()" /><!-- Записываем все, кроме memEmployees -->
			<c:Button Text="#save_all#" OnClick="$SaveAll()" /><!-- Записываем все -->
		</c:HorizontalLayout>
	</c:DockLayout>
</c:Screen>

В данном экране пользователь вводит/редактирует информацию о клиенте. Имеется возможность записать данные, исключая информацию по персоналу (функции SaveContact() и SaveAll()). Необходимо исключить ошибки во введенных данных. При выполнении требований комментарии будут удаляться.

Для начала установим область валидации для кнопок. Для выполнения SaveAll() нам необходимо проверить все данные клиента, поэтому мы устанавливаем значение "all":

<c:Button Text="#save_all#" OnClick="$SaveAll()" SubmitScope="all"/>

SaveContact() не записывает данные о персонале, так что в области валидации необходимо указать только необходимые поля:

<c:Button Text="#save_contact#" OnClick="$SaveContact()" SubmitScope="edtName;contacts"/>

Обратите внимание, мы не перечисляли edtEmail, edtPhone, memAddress, а всего лишь указали идентификатор родительского контейнера. В случае, если в области валидации указан контейнер, в нее добавляются все вложенные компоненты (рекурсивно).

Помимо области валидации нам необходимо указать постусловия. Для всех полей существует одно общее ограничение - максимальная длина строки, поэтому установим для всех полей соответствующие значения атрибута Length:

<c:Screen xmlns:c="BitMobile.Controls" xmlns:s="BitMobile.ValueStack">
	<c:DockLayout>
		<c:EditText Id="edtName" Placeholder="#name#" Length="64" /><!-- Имя контакта: обязательно, должно содержать только буквы-->
		<c:VerticalLayout Id="contacts">
			<c:EditText Id="edtEmail" Placeholder="#email#" Length="64" /> <!-- Почта: обязательно, должна быть валидна -->
			<c:EditText Id="edtPhone" Placeholder="#phone#" Length="16" /> <!-- Телефон: должен быть валиден -->
			<c:MemoEdit Id="memAddress" Placeholder="#address#" Length="128" /><!-- Адрес -->
		</c:VerticalLayout>
		<c:MemoEdit Id="memEmployees" Placeholder="#employees#" Length="256" /><!-- Список персонала через пробел/перенос -->
		<c:HorizontalLayout>
			<c:Button Text="#back#" OnClick="$DoRollback()" OnEvent="Back" />
			<c:Button Text="#save_contact#" OnClick="$SaveContact()" SubmitScope="edtName;contacts"/>
			<c:Button Text="#save_all#" OnClick="$SaveAll()" SubmitScope="all"/>
		</c:HorizontalLayout>
	</c:DockLayout>
</c:Screen>

В случае, если требования данного постусловия будут нарушены, пользователь увидит сообщение "Недопустимая длина текста"/"Text too long".

Поля ввода имени и почты обязательны для заполнения - используем атрибут Required:

<c:EditText Id="edtName" Placeholder="#name#" Length="64" Required="true" /><!-- Имя контакта: должно содержать только буквы или цифры-->
<c:EditText Id="edtEmail" Placeholder="#email#" Length="64" Required="true" /> <!-- Почта: должна быть валидна -->

В случае, если требования данного постусловия будут нарушены, пользователь увидит сообщение "Поле не может быть пустым"/"Field shouldn't be empty".

Более сложные постусловия можно реализовать с использованием атрибута Mask. Разработчик задает в качестве значения атрибута регулярное выражение, на основе которого производится поиск в поле. Если найдено хотя бы одно соответствие, условие подтверждается. В случае, если требования данного постусловия будут нарушены, пользователь увидит сообщение "Недопустимые значения"/"Invalid values".

Для edtName существует требование содержать только буквы или цифры. Для этого применяем регулярное выражение "^\w*$":

<c:EditText Id="edtName" Placeholder="#name#" Length="64" Required="true" Mask="^\w*$" />

Обратите внимание, мы используем знаки начала (^) и конца ($) строки для того, что бы выражение \w* проверялось для всего введенного значения.

Регулярное выражение, применимое для валидации поля ввода электронной почты гораздо сложнее: "^([a-z0-9_-]+\.)*[a-z0-9_-]+@[a-z0-9_-]+(\.[a-z0-9_-]+)*\.[a-z]{2,6}$". Более того, использование фигурных  скобок конфликтует механикой форматирования строк. Для решения данной проблемы используем файлы локализации en.txt и ru.txt (текст аналогичный):

email_regexp	^([a-z0-9_-]+\.)*[a-z0-9_-]+@[a-z0-9_-]+(\.[a-z0-9_-]+)*\.[a-z]{2,6}$
<c:EditText Id="edtEmail" Placeholder="#email#" Length="64" Required="true" Mask="#email_regexp#" />

Аналогично запишем логику валидации для поля ввода телефона:

phone_regexp	^((8|\+7)[\- ]?)?(\(?\d{3}\)?[\- ]?)?[\d\- ]{7,10}$
<c:EditText Id="edtPhone" Placeholder="#phone#" Length="16" Mask="#phone_regexp#" />

Для поля ввода адреса требуется проверить наличие почтового индекса. Никаких других ограничений, кроме длины, нет, так что можно просто искать 6 цифр, идущих подряд "\d\d\d\d\d\d":

<c:MemoEdit Id="memAddress" Placeholder="#address#" Length="128" Mask="\d\d\d\d\d\d" />

Конечно, мы можем использовать регулярное выражение вида "\d{6}", но в таком случае нам бы пришлось использовать константы локализации.

Поле ввода информации о персонале должно содержать только буквы и пробелы, но применение регулярного выражения вида "^[а-яА-ЯёЁa-zA-Z\s]*$" не применимо, так как поле memEmployees многострочное. В данном случае необходимо использовать знаки начала (\A) и конца (\Z) текста "\A^[а-яА-ЯёЁa-zA-Z\s]*\Z":

<c:MemoEdit Id="memEmployees" Placeholder="#employees#" Length="256" Mask="\A^[а-яА-ЯёЁa-zA-Z\s]*\Z" />

Таким образом мы, без применения скриптов, получили экран с необходимыми ограничениями ввода:

<c:Screen xmlns:c="BitMobile.Controls" xmlns:s="BitMobile.ValueStack">
	<c:DockLayout>
		<c:EditText Id="edtName" Placeholder="#name#" Length="64" Required="true" Mask="^\w*$" />
		<c:VerticalLayout Id="contacts">
			<c:EditText Id="edtEmail" Placeholder="#email#" Length="64" Required="true" Mask="#email_regexp#" />
			<c:EditText Id="edtPhone" Placeholder="#phone#" Length="16" Mask="#phone_regexp#" />
			<c:MemoEdit Id="memAddress" Placeholder="#address#" Length="128" Mask="\d\d\d\d\d\d" />
		</c:VerticalLayout>
		<c:MemoEdit Id="memEmployees" Placeholder="#employees#" Length="256" Mask="\A^[а-яА-ЯёЁa-zA-Z\s]*\Z" />
		<c:HorizontalLayout>
			<c:Button Text="#back#" OnClick="$DoRollback()" OnEvent="Back" />
			<c:Button Text="#save_contact#" OnClick="$SaveContact()" SubmitScope="edtName;contacts"/>
			<c:Button Text="#save_all#" OnClick="$SaveAll()" SubmitScope="all"/>
		</c:HorizontalLayout>
	</c:DockLayout>
</c:Screen>
  • Нет меток
Написать комментарий...