Накалякал тут
функцию валидации для Erlyweb. Сначала описание работы, а потом, может быть, о самой функции :) Работает примерно так:
Создаем форму с четырьмя полями:
- login
- password
- pasword_repeat
- email
Стандартная форма регистрации то бишь. Естественно, нам нужно провести валидацию полей следующим образом:
- login должен быть 4-16 символов
- password должен быть 4-16 символов
- password должен быть равен password_repeat
- email должен быть правильным адресом
Стандартные функции валидации для этого не подходят. Но подойдет моя :)
Предположим, у нас есть функция
process_signup, которая принимает на вход стандартную структуру
yaws_arg. Тогда валидация будет выглядеть следующим образом:
process_signup(A) ->
F = fun(A, Field) ->
{ok, Val} = yaws_api:postvar(A, Field),
L = string:len(Val),
if
L < 4 orelse L > 16 ->
{Field, length};
true ->
{}
end
end,
EmailCheck = fun(Args, Field2) ->
{ok, Email} = yaws_api:postvar(Args, Field2),
Match = regexp:match(Email, "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+"),
Match /= nomatch
end,
%% магия тут:
buktu_form:validate(A, [
{login, F},
{email, EmailCheck},
{password, [{'=', password_repeat}, F]}
]).
Таким образом, если вообще ни одно поле введено не будет, то мы получим:
[{login,invalid_field},
{email,invalid_field},
{password,[{invalid_fields,[password,password_repeat]},
invalid_field]}]
Если введем поля, не соответствующие критериям, то:
[{login,length},
{email,invalid_value},
{password,[{not_equal,password_repeat},
length]}]
- Callback-функция, которую можно передавать для валидации, может возвращать:
- кортеж типа
{FieldName, Error}
true, если поле прошло валидацию или false в противном случае (тогда функция валидации вернет кортеж {FieldName, invalid_value})
- любое значение
Value, которое будет трансформировано в {FieldName, Value}
- если любое из полей в правиле не существует или не содержит значение, то для каждого такого правила функция валидации вернет:
invalid_field если поле сравнивается со значением
{invalid_fields, [field1, field2]} если поле сравнивается с другим полем
- Если необходимо передать несколько правил, достаточно передать их в списке. Если достаточно проверить наличие поля, можно передать кортеж, содержащий только название поля:
- Проверить, существует ли такое поле
{field_name}
- Сравнить поле
field_name с полем field2_name (также можно использовать '=', '/=', '<', '=<', '>', '>=' )
{field_name, {'=', field2_name}}
- Сравнить значение поля с любым другим значением:
{field_name, {'=', Value}}
- Использовать callback-функцию (function/2, первый параметр - yaws_arg, второй - название поля). Функция может быть лямбдой или любой функцией из любого модуля в виде
module:function/2 или {module, function}
{field_name, F}
- Использовать callback-функцию с дополнительным значением (function/3, первый параметр - yaws_arg, второй - название поля, третий - значение). Функция может быть лямбдой или любой функцией из любого модуля в виде
module:function/3 или {module, function}
{field_name, {F, Value}}
- Функция валидации возвращает
proplist в виде:
[{FieldName(), Errors()}]
где
FieldName() = atom()
Errors() = Error() | [Error()]
Error() = любое_пользовательское_значение | absent | invalid_value |
invalid_field | {invalid_fields, [FieldName(), FieldName()]} |
ComparisonError()
ComparisonError() = {not_equal, value_or_field} | {equal, value_or_field} |
{not_greater, value_or_field} | {not_less, value_or_field} |
{not_greater_or_equal, value_or_field} | {not_less_or_equal, value_or_field} |