Комментарии 34
Такой подход имеет смысл, если вы строите форму по каким-то данным. Тогда в эти данные можно положить еще сведения о требуемой валидации.
А если идти от разметки, то проще каждому инпуту добавить класс, который будет указывать на нужный тип валидации, типа
А если идти от разметки, то проще каждому инпуту добавить класс, который будет указывать на нужный тип валидации, типа
<input type="text" name="email" class="js-validate js-validate-email"/>
+2
Да, действительно можно раздать полям формы классы, а не id. Но в погоне за «системностью» подхода я на это пойтить не могу.
-1
лучше не классами, а data- атрибутами тогда уж, что-то типа этого:
<input type="text" name="email" data-js-validators='email required'>
0
Тоже вариант, да.
Я пока не стремлюсь использовать data-атрибуты, потому что уж очень мало где поддерживаются нативно.
Я пока не стремлюсь использовать data-атрибуты, потому что уж очень мало где поддерживаются нативно.
0
data-атрибуты поддерживаются абсолютно везде.
0
Нативно?
0
Ну да, а в чём проблема? Чем отличается поддержка data-атрибутов в четвёртом фоксе и ie6?
0
Ну и что? getAttribute сильно причина не использовать data-атрибуты? className ведь тоже нужно парсить.
0
Давайте разделим два пункта.
Первое: нативная поддержка все-таки не везде.
Второе: да, для меня это повод пока что не использовать. По ряду причин. Расписывать?
Первое: нативная поддержка все-таки не везде.
Второе: да, для меня это повод пока что не использовать. По ряду причин. Расписывать?
0
1. Ну, я так понял, что под ненативной поддержкой вы подразумевали всякие хаки, поехавшую вёрстку и т.п. в ie. Как нерабочий css для html5 без shiv-патча. На счёт dataset — согласен, есть не везде
2. Да, если не сложно.
2. Да, если не сложно.
0
1. Не думаю, что верстка поедет из-за дата-атрибутов даже в ie6… Хотя кто его знает:)
2.
Одна из причин — суеверная. Я не готов поручиться, что это будет работать as expected. Надо провести тесты, etc — мне лень.
Вторая — консервативная. Существует как минимум два метода, которые будут работать примерно так же по скорости и служат верой и правдой уже давно. Соответственно, не вижу острых причин что-либо менять.
Третья — семантичность это здорово, но жизнь заставляет не ставить ее во главу угла.
2.
Одна из причин — суеверная. Я не готов поручиться, что это будет работать as expected. Надо провести тесты, etc — мне лень.
Вторая — консервативная. Существует как минимум два метода, которые будут работать примерно так же по скорости и служат верой и правдой уже давно. Соответственно, не вижу острых причин что-либо менять.
Третья — семантичность это здорово, но жизнь заставляет не ставить ее во главу угла.
0
Много мелких замечаний к коду.
==========
Не очень понравился кусок. Не очевидно. Понял со второго раза. Почему нельзя было сделать так?
==========
Это можно было записать изящнее:
==========
Не совсем понятна логика кое-каких названий. Например,
Или функция, которая создаёт класс. Следовательно, должен быть один из вариантов:
Потому что
==========
У меня возникло впечатление, что вы не знаете про хеш
почему
если в данном случае Array не совсем подходит и правильнее будет с хешем. Тем более, можно красиво записать:
Хотя название
==========
Singleton аналогично непонятно. Во-первых, вы отошли от собственного стиля кодирования и именования переменных в стиле camelCase (regForm, createField) и назвали свойство в стиле underscore (nullify_values)
Во-вторых, даже если вы объявляете объект, который является Синглтоном, называть его "
В третьих — неправильно делать такие вещи синглтоном. А если у меня несколько независимых форм на странице — всё, облом?
==========
submit — очень тяжёлый. неплохо бы отрефакторить, тем более там есть куда.
==========
function createField() {
var members = new Array('required', 'regexp');
for(var i = 0; i < arguments.length; i++) {
this[members[i]] = arguments[i];
}
}
Не очень понравился кусок. Не очевидно. Понял со второго раза. Почему нельзя было сделать так?
function createField (required, regexp) {
if (required != null) this.required = required;
if (regexp != null) this.regexp = regexp;
}
==========
Это можно было записать изящнее:
createField.prototype.regexp = /^[A-z0-9-_+. ,@]{1,}$/ig;
createField.prototype.valid = false;
createField.prototype.required = true;
createField.prototype.nullify = function() {
this.valid = false;
};
// =>
createField.prototype = {
regexp : /^[A-z0-9-_+. ,@]{1,}$/ig,
valid : false,
required : true,
nullify : function() {
this.valid = false;
}
};
==========
Не совсем понятна логика кое-каких названий. Например,
createField
— это ведь класс, который создаётся с помощью оператора new
.Или функция, которая создаёт класс. Следовательно, должен быть один из вариантов:
var field = createField();
var field = new Field();
Потому что
new createField
— это тавтология==========
У меня возникло впечатление, что вы не знаете про хеш
{}
почему
var single = new Array();
single['name'] = ...
если в данном случае Array не совсем подходит и правильнее будет с хешем. Тем более, можно красиво записать:
var single = {
name : new Field(),
email : new Field(true, /^[A-z0-9._-]+@[A-z0-9.-]+\.[A-z]{2,4}$/),
sex : new Field(true, /male$/ig)
};
Хотя название
single
мне тоже непонятно. Тут, кажется, больше подошло бы userRegistrationForm
==========
Singleton аналогично непонятно. Во-первых, вы отошли от собственного стиля кодирования и именования переменных в стиле camelCase (regForm, createField) и назвали свойство в стиле underscore (nullify_values)
Во-вторых, даже если вы объявляете объект, который является Синглтоном, называть его "
Singleton
" — моветон. Вот вы назвали так форму свою. А потом в другом месте у вас ещё один синглтон рулит запросами. Он тоже назовётся Singleton
? А ещё один — рулит вводом с клавиатуры — тоже Singleton
? Три Singleton делают совершенно разные вещиВ третьих — неправильно делать такие вещи синглтоном. А если у меня несколько независимых форм на странице — всё, облом?
==========
submit — очень тяжёлый. неплохо бы отрефакторить, тем более там есть куда.
+4
Все прям перетер ;)
The best ever инлайн форм валидатор — Mootools Form.Validator.Inline Live пример использования jsfiddle.net/timwienk/LgJsN/ Со всеми зависимостями он пожатый весит 32Кб это много, если поточить напильником и убрать локаль, не нужные валидолы, то до 10, думаю, можно сократить.
Сейчас все проекты используют какой-либо фрэймворк, чаще jQuery, так что лучше, если пишете свой валидатор, писать под фрэймворк.
А если вы желаете изучить принципы работы валидаторов, то лучше изучить исходник того же Form.Validator.Inline кроме изучения принципа работы найдете много интересного, плюс научитесь хорошо структурировать код.
aiwan9 и ещё прогоните, пожалуйста, свой код через JSLint (перед запуском ткните кнопку The Good Parts) и сделайте так, чтобы он вообще не ругался, на некоторые части вашего JavaScript кода больно смотреть.
The best ever инлайн форм валидатор — Mootools Form.Validator.Inline Live пример использования jsfiddle.net/timwienk/LgJsN/ Со всеми зависимостями он пожатый весит 32Кб это много, если поточить напильником и убрать локаль, не нужные валидолы, то до 10, думаю, можно сократить.
Сейчас все проекты используют какой-либо фрэймворк, чаще jQuery, так что лучше, если пишете свой валидатор, писать под фрэймворк.
А если вы желаете изучить принципы работы валидаторов, то лучше изучить исходник того же Form.Validator.Inline кроме изучения принципа работы найдете много интересного, плюс научитесь хорошо структурировать код.
aiwan9 и ещё прогоните, пожалуйста, свой код через JSLint (перед запуском ткните кнопку The Good Parts) и сделайте так, чтобы он вообще не ругался, на некоторые части вашего JavaScript кода больно смотреть.
+1
Ну вы ведь со мной согласны? ;)
Конечно, сейчас не имеет смысла в продакшне писать код с нуля, но всё-же, неплохо знать, как это сделать.
Но вообще согласен с azproduction
Конечно, сейчас не имеет смысла в продакшне писать код с нуля, но всё-же, неплохо знать, как это сделать.
Но вообще согласен с azproduction
0
Да. Кроме всего прочего есть момент:
Свойства объекта в прототипе хранить не безопасно в плане ошибок из-за делегирующего прототипного наследования в JavaScript лучше их сразу вынести в OwnProperty в конструкторе.
aiwan9 и заодно, не используйте
Комильфо:
createField.prototype.valid = false;
createField.prototype.required = true;
Свойства объекта в прототипе хранить не безопасно в плане ошибок из-за делегирующего прототипного наследования в JavaScript лучше их сразу вынести в OwnProperty в конструкторе.
aiwan9 и заодно, не используйте
new Array
и делайте явное объявление входных переменных в функцию :)Комильфо:
var Field = function (required, regexp) {
this.required = (typeof required === 'undefined') ? true : !!required;
this.regexp = regexp || /^[A-z0-9-_+. ,@]{1,}$/ig;
this.valid = false;
};
Field.prototype.reset = function () {
this.valid = false;
return this;
};
0
между прочим,
(typeof required === 'undefined')
отлично заменяется на required == null
. По логике вполне подходит, т.к. если передали null, то хотели сделать значение по-умолчанию. Очень удобно.0
Стараюсь сравнивать по ссылке, поэтому мне
required == null
не подходит, если бы undefined было бы объявлено в глобальном замыкании как это сделано в jQuery, тогда я бы сделал вот так required === undefined
. Другое дело если мы пропускаем переменную required и у меня будет false, хотя ожидаем true, но для стиля JavaScript это не подходит — лучше переделать конструктор и отправить хэш {regexp: /.*/gi}
в качестве единственного параметра.0
а чем не подходит null, я таки не понял =)
ведь required == null будет трушным только при undefined и null =) null != false.
да, хеш — это правильно =)
ведь required == null будет трушным только при undefined и null =) null != false.
да, хеш — это правильно =)
0
Бейте меня ногами, но я полагаю, что валидация должна быть только одна — на стороне сервера. Причины простые: на стороне сервера она должна быть обязательно (понятно почему), а значит придётся повторять тот же код. Причём, наверняка, на другом языке.
Я сейчас практически всегда использую AJAX-формы. Проверка на сервере, ответ на клиенте. Массу клиент-кода экономит.
Я сейчас практически всегда использую AJAX-формы. Проверка на сервере, ответ на клиенте. Массу клиент-кода экономит.
0
Согласен. На стороне клиента можно оставить разве что небольшие правила для экономии времени и нервов, например допустимые символы в поле (и то не сложные, например только числа) или проверку занятости логина (сразу ajax отправлять)
0
Используйте нормальные генераторы форм и не надо будет ничего повторять. Подобные генераторы пишутся с нуля за пару часов максимум.
0
То есть, вы предлагаете написать ещё дополнительный код, который будет связывать воедино логику сервера и клиента, вместо того, чтобы оставить только код на сервере?
Кроме того, генераторы форм практически всегда оборачиваются головняком для верстальщика. Особенно, если внешний вид формы нужно кастомизировать. А ещё можно вспомнить ситуации, когда форма динамически генерируется на клиенте. Предлагаете в этом случае обращаться к серверу, чтобы он сгенерировал нам форму?
Я просто не вижу смысла оставлять клиент-валидацию. Зачем она? Ну ладно, проверка занятости логина, как выше писали. Но зачем делать дважды одну и ту же проверку обычных полей ума не приложу.
Кроме того, генераторы форм практически всегда оборачиваются головняком для верстальщика. Особенно, если внешний вид формы нужно кастомизировать. А ещё можно вспомнить ситуации, когда форма динамически генерируется на клиенте. Предлагаете в этом случае обращаться к серверу, чтобы он сгенерировал нам форму?
Я просто не вижу смысла оставлять клиент-валидацию. Зачем она? Ну ладно, проверка занятости логина, как выше писали. Но зачем делать дважды одну и ту же проверку обычных полей ума не приложу.
+1
Смысл валидации на клиенте в том, что она работает быстрее. Это экономит время пользователям и снижает нагрузку с сервера. Так что ее наличие — это плюс примерно того же порядка, что сжатие js- и css- файлов в один или использование спрайтов.
0
Я понимаю в чём смысл валидации на клиенте, честно. И отказался от неё совершенно осознано. В наше время быстрых каналов экономия времени получается на спичках, а деньги сэкономленные от работы над скриптом валидации проще вложить в апгрейд сервера, это будет лучше чем избегать нагрузки подобным способом.
Кроме того, проведённая вами параллель не совсем удачна: сжатие JS/CSS это простая технология. А логика валидации это, как ни крути, код со всеми из него вытекающими: поддержка, апдэйт либ в случае использования сторонних решений, рефакторинг.
Я понимаю, допустим, использование рэгэксп-маски на поле, там скрипт простой и универсальный, пару строчек кода в логике. Написание же полноценной валидации это всегда разработка нового мета-языка обозначений: not_empty, is_email, is_url, is_phone и т. п. И везде оно разное, хотя и стандарты тоже есть. Дублировать довольно таки сложную и трудоёмкую логику я не вижу смысла.
Кроме того, проведённая вами параллель не совсем удачна: сжатие JS/CSS это простая технология. А логика валидации это, как ни крути, код со всеми из него вытекающими: поддержка, апдэйт либ в случае использования сторонних решений, рефакторинг.
Я понимаю, допустим, использование рэгэксп-маски на поле, там скрипт простой и универсальный, пару строчек кода в логике. Написание же полноценной валидации это всегда разработка нового мета-языка обозначений: not_empty, is_email, is_url, is_phone и т. п. И везде оно разное, хотя и стандарты тоже есть. Дублировать довольно таки сложную и трудоёмкую логику я не вижу смысла.
0
Вы просто не умеете их готовить :)
Валидаторы в верстку должны добавляться при помощи соответствующих атрибутов и только! Дальше по все странице проходится скрипт и смотрит эти атрибуты.
Ни верстке, ни динамической генерации формы это не помешает никак. А вот юзеру удобнее.
Валидаторы в верстку должны добавляться при помощи соответствующих атрибутов и только! Дальше по все странице проходится скрипт и смотрит эти атрибуты.
Ни верстке, ни динамической генерации формы это не помешает никак. А вот юзеру удобнее.
0
Я всегда их так и делал ) Я практически весь JS-код подключаю исключительно через спецаттрибуты.
И как это решает вопрос динамической генерации форм, скажите? По вашей логике генератор форм на сервере лежит, по любому нужно будет к нему обратиться, чтобы форма вышла согласно заданным в одном месте параметрам. Или я неправильно вас понял?
И как это решает вопрос динамической генерации форм, скажите? По вашей логике генератор форм на сервере лежит, по любому нужно будет к нему обратиться, чтобы форма вышла согласно заданным в одном месте параметрам. Или я неправильно вас понял?
0
Ajax-валидация — по мне так хорошее решение.
А еще есть решение — сайт на nodeJS. Пишем 1 класс для валидации данных и используем его и на клиенте и на сервере.
А еще есть решение — сайт на nodeJS. Пишем 1 класс для валидации данных и используем его и на клиенте и на сервере.
0
Ага, знаю ) Я как большой поклонник JS давно хочу попробовать Node. Но возможности пока не предоставляется.
AJAX-валидация стала для меня выходом, к которому я пришёл после долгой работы с формами: наиболее удачное и автоматизируемое решение. Минимум разработки и максимум эффекта.
ЗЫ: Никаких классов в моём уютненьком прототипном JS!
AJAX-валидация стала для меня выходом, к которому я пришёл после долгой работы с формами: наиболее удачное и автоматизируемое решение. Минимум разработки и максимум эффекта.
ЗЫ: Никаких классов в моём уютненьком прототипном JS!
+1
А почему бы не сделать валидацию но основе описанной в спецификации, зачем придумывать свою нотацию?
www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#common-input-element-attributes
см атрибуты required, pattern
www.whatwg.org/specs/web-apps/current-work/multipage/common-input-element-attributes.html#common-input-element-attributes
см атрибуты required, pattern
0
Опытным путем я заметил, что когда применяется функция RegExp.test(), то сначала она возвращает результат ожидаемый, а потом прямо противоположный.
Никакой магии в этом нет, результат вполне задокументированный. Вы сталкиваетесь с lastIndex
Суть очень проста. Когда в тексте находится совпадение с регулярным выражением, то
lastIndex
устанавливается в его позицию и в следующий раз ищется начиная с этой позиции. Если не находится — lastIndex
устанавливается в нуль. Самый простой способ бороться с этим — сбрасывать lastIndex
:var i, log = console.log,
re = /male$/ig,
string = '123male';
log( re.lastIndex ); // 0
log( re.test(string) ); // true
log( re.lastIndex ); // 7
log( re.test(string) ); // false
log( re.lastIndex ); // 0
log( re.test(string) ); // true
log( re.lastIndex ); // 7
re.lastIndex = 0;
log( re.test(string) ); // true
+1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Валидация форм в JavaScript ч.1