Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Отправка формы после валидации (https://javascript.ru/forum/events/52866-otpravka-formy-posle-validacii.html)

beebop 10.01.2015 18:04

Отправка формы после валидации
 
Помогите, 2 часа уже мучаюсь(
Как по-нормальному убрать обработчик submit с формы? Он убирается, но форма отправляется со второго раза (т.е. 1й раз при нажатии на submit ничего не происходит).

http://jsfiddle.net/gwnhzez9/2/

beebop 10.01.2015 19:27

Надо не аяксом отправить, т.е. убрать обработчик .on()

danik.js 10.01.2015 19:37

$form.on('submit', function(e) {
    var isValid = твоиПроверки();
    if (!isValid)
        e.preventDefault();
});

danik.js 10.01.2015 19:39

validateFields лучше чтоб возвращала true если все ок. Так логичнее.

danik.js 10.01.2015 19:43

Ты не правильно это делаешь. У тебя ущербная разметка. Учись:
<style>
.site-form label{display: block;}
</style>
<form id="feedback-form" class="site-form no-ajax">
	<label>
		<span class="field-title">Представьтесь, пожалуйста</span>
		<input type="text" name="NAME" required>
	</label>
	<label>
		<span class="field-title">Контактный E-mail</span>
		<input type="email" name="EMAIL" required>
	</label>
	<label>
		<span class="field-title">Номер контактного телефона</span>
		<input type="tel" class="phone" name="PHONE" required>
	</label>
	<label>
		<span class="field-title">Ваше письмо</span>
		<textarea name="MESSAGE" required></textarea>
	</label>
	<div class="submit">
		<input type="submit" name="submit" value="Отправить письмо">
	</div>
</form>

Попробуй заслать без значений!

В новых браузерах все без всяких скриптов будет работать. В старых нужен костыль типа твоего скрипта. Хотя есть и готовые, не кривые, в отличие от твоего.

danik.js 10.01.2015 20:03

Вот однажды начал было делать простой скрипт кастомизации (заодно и полифилл) html5 валидации:
http://jsfiddle.net/danya_postfactum/p1zde8v3/

К сожалению не сделал вывод сообщения об ошибке. Есть:
- поддержка required и pattern
- валидация поля по мере ввода
- добавление css-класса при валидации
- передача фокуса первому неверному полю
- поддержка кастомных правил валидации (через js код, не через разметку - не знаю хорошо это или плохо)
- независимость от сторонних либ

Минусы:
- зависимость от classList.js и addEventListener.js
- какие-то траблы вроде были с IE старыми
- не сделаны сообщения об ошибке
- не сделана дефолтная валидация поля типа email (и наверно еще каких-то)
- необходимость запуска функции для инициализации (хотя это не всегда минус)

Эт скорее для меня памятка.

beebop 10.01.2015 20:15

Цитата:

Сообщение от danik.js (Сообщение 350630)
Ты не правильно это делаешь. У тебя ущербная разметка. Учись:
<style>
.site-form label{display: block;}
</style>
<form id="feedback-form" class="site-form no-ajax">
	<label>
		<span class="field-title">Представьтесь, пожалуйста</span>
		<input type="text" name="NAME" required>
	</label>
	<label>
		<span class="field-title">Контактный E-mail</span>
		<input type="email" name="EMAIL" required>
	</label>
	<label>
		<span class="field-title">Номер контактного телефона</span>
		<input type="tel" class="phone" name="PHONE" required>
	</label>
	<label>
		<span class="field-title">Ваше письмо</span>
		<textarea name="MESSAGE" required></textarea>
	</label>
	<div class="submit">
		<input type="submit" name="submit" value="Отправить письмо">
	</div>
</form>

Попробуй заслать без значений!

В новых браузерах все без всяких скриптов будет работать. В старых нужен костыль типа твоего скрипта. Хотя есть и готовые, не кривые, в отличие от твоего.



1. В старых ie все-таки нужен скрипт.
2. Сообщение об ошибке должно быть таким, каким его нарисовал дизайнер, а не таким, какой его браузер выведет.
3. Из скрипта и верстки я выложил только часть, чтобы было понятно, о чем речь. Там и добавление классов, и фокус на поле с ошибкой и много всего. Можешь называть костылем, но он работает так, как мне нужно.
4. Не тебе меня учить. И в данном случае ущербна твоя разметка.

Не следует так завышать ЧСВ, а то создается ощущение, что у тебя болт меньше, чем девушка хочет.

beebop 10.01.2015 20:18

Цитата:

Сообщение от danik.js (Сообщение 350624)
validateFields лучше чтоб возвращала true если все ок. Так логичнее.

Это уже кому как удобно.

beebop 10.01.2015 20:20

Цитата:

Сообщение от danik.js (Сообщение 350621)
$form.on('submit', function(e) {
    var isValid = твоиПроверки();
    if (!isValid)
        e.preventDefault();
});

Как-то была проблема, что форма с бОльшим количеством полей и проверок отправляется до того как валидатор возвращал значение.

danik.js 10.01.2015 20:26

beebop, читай мое последующее сообщение. Там решение двух из трех проблем.
Цитата:

Сообщение от beebop
Не тебе меня учить. И в данном случае ущербна твоя разметка.

Видимо учить тебя придется... К чему дибильные классы типа email required если есть атрибут type=email и required? Встроенная валидация при этом вырубается одной строчкой. Зато не надо ниче выдумывать. А еще - есть шибко умные люди, навроде меня, ставящие NoScript. Так вот даже с ним все будет отлично работать. И еще - в любом случае должна быть еще и серверная валидация. Это еще и как запасной вариант сработает.

Цитата:

Сообщение от beebop
Не следует так завышать ЧСВ,

Извини, написал грубовато немного. Но по разметке в целом я прав, ты не прав. Если думаешь иначе - подумай еще раз.

В свой корявый FormValidator завтра постараюсь добавить сообщение об ошибке и исправить косяк с IE. Хотя addEventListener и classList - спорный момент, но jQuery - однозначно не вариант. Стараюсь выпиливать эту дрянь отовсюду (да, я знаю, это не дрянь, это палочка-выручалочка:) ).

danik.js 10.01.2015 20:28

Цитата:

Сообщение от beebop
Как-то была проблема, что форма с бОльшим количеством полей и проверок отправляется до того как валидатор возвращал значение.

Чепуха. У тебя там выпадала где-то ошибка значит. Если руки все-таки кривоваты - оберни в try..catch :dance:

beebop 11.01.2015 14:14

Цитата:

Сообщение от danik.js (Сообщение 350646)
beebop, читай мое последующее сообщение. Там решение двух из трех проблем.
Видимо учить тебя придется... К чему дибильные классы типа email required если есть атрибут type=email и required? Встроенная валидация при этом вырубается одной строчкой. Зато не надо ниче выдумывать. А еще - есть шибко умные люди, навроде меня, ставящие NoScript. Так вот даже с ним все будет отлично работать. И еще - в любом случае должна быть еще и серверная валидация. Это еще и как запасной вариант сработает.


Извини, написал грубовато немного. Но по разметке в целом я прав, ты не прав. Если думаешь иначе - подумай еще раз.

В свой корявый FormValidator завтра постараюсь добавить сообщение об ошибке и исправить косяк с IE. Хотя addEventListener и classList - спорный момент, но jQuery - однозначно не вариант. Стараюсь выпиливать эту дрянь отовсюду (да, я знаю, это не дрянь, это палочка-выручалочка:) ).

Дебильные классы нужны для css, это их основное предназначение. Сереверная валидация есть, я ее не затрагивал в этой теме.

По разметке ты неправ. Я знаю возможности html5, мне это решение не подходит. Ошибки должны быть оформлены так, как нарисовал дизайнер, я уже писал об этом.
Далее. Никакой разницы в данном случае нет, где писать required, если все равно браузерную валидацию буду отключать. Точнее есть. по сути, надо включить возможность валидации html5, а потом отключить. Где смысл? А для телефона вообще нужно использовать masked.input, потому что в дизайне так нарисовано и написано в тз.


Цитата:

Чепуха. У тебя там выпадала где-то ошибка значит. Если руки все-таки кривоваты - оберни в try..catch
Откуда у тебя такая манера критиковать то, что ты не видел? Я, правда, не могу сейчас вспомнить, почему мне такой вариант не подходил, но я не случайно стал по-другому делать.

Special for you. Мне нужен ответ на вопрос, который я задал в самом начале. Чисто гипотетически предположи, что валидация будет происходить на сервере, а ее результат будет приходить аяксом. Тогда такое не прокатит:
if(error) e.preventDefault()

beebop 11.01.2015 14:17

И насчет использования jquery, noscript и пр. Это тема холиваров по всему интернету, не надо здесь это обсуждать.

danik.js 11.01.2015 16:04

jQuery - не обсуждаю.
noscript - не холивар. Он есть, его используют. Есть качественные сайты, разработчики которых знают об этом. Есть кривые сайты и те которые не знают или попросту плюют.
Че тут холиварить то? Это просто факты.

Цитата:

Сообщение от beebop
Откуда у тебя такая манера критиковать то, что ты не видел?

Ты сделал акцент на том что полей было много. Этот фактор не имеет никакого влияния. Причина может быть только одна - прерывание потока выполнения кода, то есть exception (предположил что ума хватило не втыкнуть return куда попало). Или ты знаешь другие причины? Что ж, приведи пример.
Цитата:

Сообщение от beebop
Мне нужен ответ на вопрос, который я задал в самом начале

Ответ был дан уже. Сейчас ты уже другие условия озвучил. Для случая асинхронной проверки делай так:

$form.on('submit', function(e) {
    e.preventDefault();
    var form = this;
    asyncValidation(function() {
        form.submit();
    });
});


Цитата:

Сообщение от beebop
Ошибки должны быть оформлены

form.noValidate = true

Цитата:

Сообщение от beebop
надо включить возможность валидации html5, а потом отключить. Где смысл?

Смысл в декларативном описании правил валидации, причем стандартизированном. А также как бонус - поддержка noscript. Это бонус - и он ничего не стоит.

Какая тебе блин разница как писать
if ($input.parent().hasClass('required'))

или
if ($input.attr('required'))

Цитата:

Сообщение от beebop
Дебильные классы нужны для css, это их основное предназначение

Если это действительно так, то все ок. Я просто предположил что они тебе нужны для описания правил валидации. Но тогда возникает вопрос - а где тогда эти правила описаны?

beebop 11.01.2015 16:47

Цитата:

Сообщение от danik.js (Сообщение 350822)
jQuery - не обсуждаю.
noscript - не холивар. Он есть, его используют. Есть качественные сайты, разработчики которых знают об этом. Есть кривые сайты и те которые не знают или попросту плюют.
Че тут холиварить то? Это просто факты.



form.noValidate = true

По поводу noscript поясню. Если в дизайне много функционала, который без js не сможет быть реализован, то нет смысла делать поддержку пользователей с отключенным js. Эти вещи сделаны не для красоты, а для удобства (всплывающие окна, та же валидация, ajax запросы). Конечно, можно добавить поддержку таких пользователей, но:
1. такие люди - исключение, и не факт, что они что-то будут покупать на сайте, если это магазин или сайт услуг.
2. это требует времени, но доплачивать не каждый заказчик захочет.

Конечно, если я буду делать сайт для себя, то сделаю возможность его функционирования без скриптов. Может быть.



Цитата:

Сообщение от danik.js (Сообщение 350822)
Ты сделал акцент на том что полей было много. Этот фактор не имеет никакого влияния. Причина может быть только одна - прерывание потока выполнения кода, то есть exception (предположил что ума хватило не втыкнуть return куда попало). Или ты знаешь другие причины? Что ж, приведи пример.

Вообще я сейчас покопался и не нашел сайт, на котором была эта проблема) Но дело точно не в ошибке. Скорее всего там что-то аяксом должно было вернуться до отправки.

Цитата:

Смысл в декларативном описании правил валидации, причем стандартизированном. А также как бонус - поддержка noscript. Это бонус - и он ничего не стоит.

Какая тебе блин разница как писать
if ($input.parent().hasClass('required'))

или
if ($input.attr('required'))

Вот именно - разницы никакой. Поэтому я сделал так. Просто не надо дополнительно писать
form.noValidate = true

А стандартизованная валидация не всегда подходит. Для того же телефона. Нужно, чтобы он был в формате +7xxxxxxxx.
Ну и кроме email, tel и url есть много типов полей, которые стандартами w3 не предусмотрены. Для них все равно придется писать валидатор.

У меня вместо type в таком случае используется класс (.phone, .email и т.д.). Не вижу ничего плохого в таком решении, оно гораздо более универсально, чем использование type. Опять же для совсем специфичных полей можно использовать data атрибуты (недавно надо было сделать ввод чисел, кратных 25). Этого ведь не предусмотрено в w3?

Цитата:

$form.on('submit', function(e) {
    e.preventDefault();
    var form = this;
    asyncValidation(function() {
        form.submit();
    });
});


Вот тут и всплывает то, что ты совершенно не понял проблему.
При событии form.submit() у тебя опять вызовется весь этот код
$form.on('submit', function(e) {
    e.preventDefault();
    var form = this;
    asyncValidation(function() {
        form.submit();
    });
});

И так будет до бесконечности. Ты его хоть пробовал запустить? Надо ипользовать .off(), чтобы убрать обработчик.

danik.js 11.01.2015 17:03

Цитата:

Сообщение от beebop
если это магазин

Тем более магазины. В них все должно работать и покупаться даже если зайти с холодильника. Все нормальные движки магазов по дефолту работают без скриптов. Помню компонент miniShop для MODx изначально не работал. Однако автор по по просьбе разработчиков (не помню, может даже по моей) быстро это исправил. И даже слова не сказал против.

Вообще, я недавно начал использовать NoScript, и честно сказать порой удивляюсь корректной работе некоторых сайтов. Хорошие сайты отображают сообщение о просьбе включить js. Причем это не тупой текст на весь сайт непонятно о чем, а в конкретном месте для конкретных целей (слайдер там какой-нибудь).

Но если заказчик не знает и слышать не хочет, и тем более доплачивать за это - то можно понять.

danik.js 11.01.2015 17:04

Цитата:

Сообщение от beebop
Ты его хоть пробовал запустить?

Дружище, вот как раз ты и не запускал его :)

<form action="javascript:'форма отправлена'">
    <button type="submit">Оптравить</button>
</form>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
var $form = $('form');
var asyncValidation = function(callback) {
    $form.text('Делаем проверки...');
    setTimeout(callback, 2000);
};


$form.on('submit', function(e) {
    e.preventDefault();
    var form = this;
    asyncValidation(function() {
        form.submit();
    });
});

</script>


form.submit не генерирует событий.

beebop 11.01.2015 17:26

Цитата:

Сообщение от danik.js (Сообщение 350837)
form.submit не генерирует событий.

Это я где-то упустил. Вот и ответ. А все остальное в теме - от лукавого)
Спасибо.

danik.js 11.01.2015 17:41

beebop, где можно посмотреть че ты там мудришь. Просто интересно подойдет моя стряпня FormValidator под твои задачи или нет. Или хотя бы просто атрибуты из HTML5 валидации заюзать получится или нет.

danik.js 11.01.2015 17:47

Обновил свой скрипт: http://jsfiddle.net/danya_postfactum/p1zde8v3/1/
Добавил сообщение. Правда там все далеко от идеала.

danik.js 11.01.2015 17:55

Цитата:

Сообщение от beebop
А стандартизованная валидация не всегда подходит. Для того же телефона. Нужно, чтобы он был в формате +7xxxxxxxx.
Ну и кроме email, tel и url есть много типов полей, которые стандартами w3 не предусмотрены. Для них все равно придется писать валидатор.

Формат проверяется только для email и url. tel не проверяется. Дело в том что ты можешь писать свои форматы:

<form>
<label>Телефон:</label>
<input type="tel" required pattern="\+7[0-9]{10}" title="Российский номер телефона в международном формате. Одиннадцать цифр" placeholder="+7xxxxxxxxxx"  />
<button type="submit">Отправить</button>
</form>


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

danik.js 11.01.2015 17:58

Удобство специализированных полей проявляется на устройствах с виртуальной клавиатурой (мобилы, планшеты). А трафик с них все растет и растет.
То есть плюсы использования налицо. Минусов никаких. Вывод - только дурак откажется от них.

beebop 12.01.2015 07:34

Цитата:

Сообщение от danik.js (Сообщение 350855)
beebop, где можно посмотреть че ты там мудришь. Просто интересно подойдет моя стряпня FormValidator под твои задачи или нет. Или хотя бы просто атрибуты из HTML5 валидации заюзать получится или нет.

Могу выложить как будет время


Часовой пояс GMT +3, время: 15:21.