crautcher Проблема с обработкой ошибочного заполнения формы. На данный момент имеется форма добавления объявления. Ситуация такая , если пользователь ошибся или не заполнил одну графу , а остальные правильно , открывается страница с сообщением о неверно заполненной графе и предлагается вернуться обратно и заполнить ее.
ОДНАКО , вот и наступает проблема. Все те поля ,которые были правильно заполнены оказываются пустыми. И приходится по новой заполнять их.
Помогите пожалуйста , кто нибудь((( за спасибо или за пиво)). Нужно применить сессии и чтобы при ошибке в той же форме рядом с «ошибочной» графой выводилось предупреждение об ошибке. Сам пробовал , не получается. Самоучка(((
Добавлено через 2 минуты
crautcher, Спасибо Вам огромное , буду пробовать. Просто никогда не применял сам сессии. Если что-то не получится я еще обращусь к Вам)) Но Надеюсь , что справлюсь. Еще раз , благодарю . Радости не будет предела.
Добавлено через 9 минут
Сообщение от crautcher
Затем выводи, где нужно $_SESSION[‘LastError’]
Это в форме я так понимаю ? Рядом с «ошибочным» полем ? Можете на одном примере показать ? К примеру графа «имя»
В этой статье будет рассмотрена ситуация, когда необходимо сделать не слишком замороченную интерактивную валидацию формы сайта для отправки сообщений. В статье я делюсь своим опытом и не претендую на звание супер эксперта. Всем приятного прочтения.
Постановка задачи
Необходимо сделать форму для отправки заявки на регистрацию пользователя. Форма должна содержать следующие поля:
- Имя (длина не более 25 символов, не может быть пустым)
- E-mail (только mail.com, не может быть пустым)
- Пароль (не менее 5 и не более 10 символов, не может быть пустым)
- Подтвердить (должен совпадать с паролем, не может быть пустым)
- Информация (в свободной форме, не более 250 символов, не может быть пустым)
Отправка данных осуществляется кнопкой «Отправить заявку», при условие что все поля заполнены правильно.
Используемые технологии
Для реализации поставленной задачи будем использовать:
- HTML 5 (doc)
- CSS 3 (doc)
- jQuery 1.12.0 (doc)
- Notify.js (doc)
Каркас (HTML)
Первым делом выставим кодировку и добавим jQuery и Notify.js:
<head>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>
<script src="http://rawgit.com/notifyjs/notifyjs/master/dist/notify.js"></script>
</head>
Теперь добавляем добавим тело страницы с формой:
<body>
<form action="/reg" method="POST" id="regForm">
<lable id="title">Запрос на регистрацию</lable>
<table>
<tboby>
<tr>
<td class="lbl">Имя:</td>
<td><input type="text" name="name" id="name" class="textbox"/>
</tr>
<tr>
<td></td>
<td><lable class="help">максимум 25 символов</lable></td>
</tr>
<tr>
<td class="lbl">E-mail:</td>
<td><input type="text" name="mail" id="mail" class="textbox"/>
</tr>
<tr>
<td></td>
<td><lable class="help">только @mail.com</lable></td>
</tr>
<tr>
<td class="lbl">Пароль:</td>
<td><input type="password" name="password1" id="password1" class="textbox"/>
</tr>
<tr>
<td></td>
<td><lable class="help">от 5 до 10 символов</lable></td>
</tr>
<tr>
<td class="lbl">Полтвердить:</td>
<td><input type="password" name="password2" id="password2" class="textbox"/>
</tr>
<tr>
<td></td>
<td><lable class="help">должен совпадать с паролем</lable></td>
</tr>
<tr>
<td class="lbl">Информация:</td>
<td><textarea maxlength="250" name="info" id="info" class="textbox"></textarea>
</tr>
<tr>
<td></td>
<td><lable class="help">в свободной форме, максисум 250 символов</lable></td>
</tr>
</tbody>
</table>
<input type="button" id="send" value="Отправить заявку"/>
</form>
</body>
В результате на странице появляется вот такая страшная штука:
Оформление (CSS)
Для того чтобы облагородить наш будущий шедевр, прикрутим стили:
body {
background-color:rgb(0, 0, 0);
}
form {
display:block;
width:450px;
height:auto;
margin:50px auto;
padding:10px;
border-radius:15px;
background-color:rgb(84, 84, 84);
font-size:16px;
font-family:'Arial';
color:rgb(255, 255, 255)
}
table {
margin:0 auto;
}
table td {
vertical-align: top;
}
table td.lbl {
padding-top:12px;
}
#title {
display:block;
margin:0;
padding: 20px;
text-align:center;
font-size:20px;
color:rgb(0, 184, 246);
}
.textbox {
width:200px;
height:auto;
margin-left:10px;
padding:10px;
border:none;
border-radius:10px;
box-shadow: 0 0 10px rgba(0,0,0,0.5);
background-color:rgb(190, 190, 190);
font-size:16px;
color:rgb(63, 63, 63);
}
.errtextbox {
box-shadow: 0 0 10px rgb(255,0,0);
}
.help {
width:190px;
display:block;
margin-bottom:25px;
padding-left:25px;
font-size:12px;
color:rgb(140, 140, 140);
}
#info {
height:100px;
resize:none;
}
#send {
display:block;
margin:0 auto 10px;
padding:7px;
border:none;
border-radius:10px;
background-color:rgb(0, 128, 174);
font-size:16px;
color:rgb(255, 255, 255);
}
В итогу получаем вот такой внешний вид формы:
Валидация (jQuery + NotifyJS)
Вывод красивых сообщений об ошибке осуществляется Notify.js. На официальном сайте представлена достаточно подробная документация по использованию (ссылка выше в разделе используемые технологии).
Ниже приведены основные функции:
$.notify("Ошибка!", "error"); // выводит сообщение об ошибки
$.notify("Информация", "info"); // выводит информационное сообщение
$.notify("Обратите внимание", "warn"); // выводит предупреждение
$.notify("Выполнено", "success"); // выводит сообщение об удачном завершение
Все эти сообщения выводятся по умолчанию в верхнем левом углу экрана, для того чтобы привязать вывод сообщения к элементу делаем следующее:
$("#elementId").notify("BOOM!", "error");
elementId — id того элемента, к которому делаем привязку. При таком написание сообщение будет выводиться под элементом, если необходимо, то позицию можно задать вручную.
Например, выведем сообщение справа от элемента:
$("#elementId").notify( "Сообщение справа", { position:"right" });
И наконец самое интересное, добавим блок jQuery для обработки ошибок заполнения формы в реальном времени.
/* Изначально форма не заполнена и по этому считаем что все возможные ошибки есть */
var errorNull = true, errorMail = true, errorPass = true;
/* Для удобства и уменьшения размера кода выносим функцию проверки поля на null в отдельную переменную */
var checkNull = function(){
$(this).val($(this).val().trim());
if ($(this).val() =="") {
/* Выводим сообщение об ошибке под элементом.
This в данном случае это элемент, который инициировал вызов функции */
$(this).notify("Поле нужно заполнить", "error");
$(this).addClass("errtextbox");
errorNull = true;
} else {
errorNull = false;
$(this).removeClass("errtextbox");
}
};
/* Проверяем значения полей Имя и Информация на null в момент когда они теряют фокус */
$("#name").focusout(checkNull);
$("#info").focusout(checkNull);
/* Проверка поля Имя на соответствие длинны */
$("#name").keyup(function(){
var value = $(this).val();
if (value.length > 24){
$(this).notify("Максимум 25 символов", "info");
$(this).val(value.slice(0,24));
}
});
/* Проверяем корректность E-mail */
$("#mail").focusout(function(){
var value = $(this).val().trim();
/* Для этого используем регулярное выражение */
if (value.search(/^[a-z0-9]{3,}@mail.com$/i) != 0) {
$(this).notify("E-mail введён не корректно", "error");
$(this).addClass("errtextbox");
errorMail = true;
} else {
$(this).removeClass("errtextbox");
errorMail = false;
}
});
/* Проверяем длину пароля */
$("#password1").focusout(function(){
var value = $(this).val();
if (value.length <= 4) {
$(this).notify("Минимум 5 символов", "error");
$(this).addClass("errtextbox");
errorPass = true;
} else {
if (value.length > 9) {
$(this).notify("Миксимум 10 символов", "error");
$(this).addClass("errtextbox");
errorPass = true;
} else {
errorPass = false;
$(this).removeClass("errtextbox");
}
}
});
/* Проверяем соответствие пароля и подтверждения */
$("#password2").focusout(function(){
var value = $(this).val();
if (value != $("#password1").val()) {
$(this).notify("Пароль не совпадает", "error");
$(this).addClass("errtextbox");
errorPass = true;
} else {
errorPass = false;
$(this).removeClass("errtextbox");
}
});
/* В результате клика по кнопке отправить если ошибок заполнения нет то форма отправляется иначе получаем сообщение об ошибке */
$("#send").click(function(){
if (!(errorNull || errorMail || errorPass)) {
$("#regForm").submit();
} else {
$(this).notify("Форма пустая или заполнена не корректно", "error");
}
});
Заключение
Вот что получилось в результате
Результат можно посмотреть на codepen.
Дорогие читатели, если статья понравилась и вам интересен подобный материал, то пишите в комментариях. Если у вас есть замечания по качеству кода или полезные советы — буду рад, тоже пишите. Спасибо за внимание.
Ни для кого не секрет, что онлайн-формы могут стать серьёзным испытанием для пользователей. Особенно когда они выглядят как список полей для ввода без каких-либо подсказок. Однако мы, как разработчики, можем значительно облегчить жизнь посетителям наших сайтов.
Используем CSS
В CSS существует четыре специальных псевдокласса, применимых к полям формы: :valid
(валидное поле), :invalid
(невалидное), :required
(обязательное) и :optional
(необязательное). Их можно использовать, чтобы добавлять некоторые — хотя и весьма ограниченные — подсказки пользователям, заполняющим форму.
Используя :valid
и :invalid
, мы можем показать пользователю, правильно ли заполнено поле по мере ввода.
input:valid {
border-color: green;
}
input:invalid {
border-color: red;
}
Однако с этим способом связана одна проблема: стили применяются до того, как пользователь начнёт работу с формой. Поля, обязательные для заполнения, сразу подсветятся нам как :invalid
, а необязательные — как :valid
. Это значит, что пользователь, даже не приступив к заполнению формы, может сразу же получить негативную обратную связь. Не очень-то хорошо.
Стилизация состояний :required
и :optional
сама по себе не особо полезна, поскольку эта информация обычно указывается в подписях к полям формы. Однако мы можем объединить эти состояния с псевдоклассами :valid
/ :invalid
и стилизовать их комбинации. Например, мы хотим показывать лишь положительный результат, когда валидно обязательное к заполнению поле.
input:required:valid {
border-color: green;
}
Используем JavaScript
JavaScript даёт намного больше возможностей для улучшения работы пользователей с формами. Давайте рассмотрим в качестве примера три числовых поля, у каждого из которых установлен минимум в 10, максимум в 100 и шаг в 10 единиц.
<form>
<label>
Number Input 1
<input type="number" min="10" max="100" step="10">
</label>
<label>
Number Input 2
<input type="number" min="10" max="100" step="10">
</label>
<label>
Number Input 3
<input type="number" min="10" max="100" step="10">
</label>
<input type="submit">
</form>
Устанавливая атрибуты min
, max
и step
, мы можем быть уверены в правильности значения только тогда, когда пользователь использует специальные контролы числового поля. Но что мешает пользователю ввести вручную некорректные данные? Вот что произойдёт, если он вставит 1
, 12
и 123
в три поля и отправит форму:
В результате всё, что получит пользователь — это сообщение об ошибке для первого поля. Кроме того, в этом сообщении будет указано лишь одно несоответствие из двух требуемых. Такое поведение можно исправить, изменяя показываемые валидатором сообщения.
Добавляем несколько сообщений об ошибках в один тултип
Валидируя поля, браузер проверяет их по определённому списку потенциальных ошибок. В каждом поле содержится специальный объект validity
, включающий в себя список булевых значений, характеризующих ту или иную проверку на валидность. Например, вот такой validity
-объект будет у поля, когда пользователь введёт в него 1
:
input.validity = {
valid: false // Поле валидно
customError: false // Установленно специальное сообщение ошибки
patternMismatch: false // Значение не удовлетворяет шаблону, установленному в атрибуте pattern
rangeOverflow: false // Значение превосходит атрибут max
rangeUnderflow: true // Значение меньше атрибута min
stepMismatch: true // Значение не соответствует указаному шагу
tooLong: false // Значение слишком длинное
tooShort: false // Значение слишком короткое
typeMismatch: false // Значение не соответствует указаному атрибуту type
valueMissing: false // Отсутствует обязательное значение
};
Примечание переводчика: Слово «mismatch» переводится как «несоответствие». Поэтому в значениях patternMismatch
, stepMismatch
и typeMismatch
обратная логика: true
— значение не удовлетворяет атрибуту, false
— удовлетворяет.
По умолчанию браузер отобразит лишь одну ошибку. Что мы можем сделать, так это проверить все эти значения самостоятельно и, если найдутся ошибки, сохранить их. Как только мы сохраним все ошибки для одного поля, мы можем отобразить весь их список в виде специального сообщения об ошибке при помощи функции setCustomValidity()
.
function CustomValidation() { }
CustomValidation.prototype = {
// Установим пустой массив сообщений об ошибках
invalidities: [],
// Метод, проверяющий валидность
checkValidity: function(input) {
var validity = input.validity;
if (validity.patternMismatch) {
this.addInvalidity('This is the wrong pattern for this field');
}
if (validity.rangeOverflow) {
var max = getAttributeValue(input, 'max');
this.addInvalidity('The maximum value should be ' + max);
}
if (validity.rangeUnderflow) {
var min = getAttributeValue(input, 'min');
this.addInvalidity('The minimum value should be ' + min);
}
if (validity.stepMismatch) {
var step = getAttributeValue(input, 'step');
this.addInvalidity('This number needs to be a multiple of ' + step);
}
// И остальные проверки валидности...
},
// Добавляем сообщение об ошибке в массив ошибок
addInvalidity: function(message) {
this.invalidities.push(message);
},
// Получаем общий текст сообщений об ошибках
getInvalidities: function() {
return this.invalidities.join('. n');
}
};
// Добавляем обработчик клика на кнопку отправки формы
submit.addEventListener('click', function(e) {
// Пройдёмся по всем полям
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
// Проверим валидность поля, используя встроенную в JavaScript функцию checkValidity()
if (input.checkValidity() == false) {
var inputCustomValidation = new CustomValidation(); // Создадим объект CustomValidation
inputCustomValidation.checkValidity(input); // Выявим ошибки
var customValidityMessage = inputCustomValidation.getInvalidities(); // Получим все сообщения об ошибках
input.setCustomValidity(customValidityMessage); // Установим специальное сообщение об ошибке
} // закончился if
} // закончился цикл
});
Теперь при попытке отправить форму мы увидим вот это:
Отображаем несколько ошибок в одном тултипе
Стало лучше, поскольку теперь будут показываться все сообщения об ошибках, связанные с конкретным полем. Однако другая проблема всё ещё не решена: ошибки по-прежнему показываются лишь для первого поля.
Это ограничение валидации, устанавливаемое браузером. Чтобы его побороть, нам нужно пойти другим путём.
Показываем все ошибки для всех полей
Вместо того, чтобы использовать встроенный тултип, мы можем добавлять сообщения об ошибках напрямую в DOM. Таким образом, все ошибки будут выводиться рядом с соответствующим полем.
Этого можно добиться какой-то парой дополнительных строчек в нашем коде:
CustomValidation.prototype.getInvaliditiesForHTML = function() {
return this.invalidities.join('. <br>');
}
// Добавляем обработчик клика на кнопку отправки формы
submit.addEventListener('click', function(e) {
// Пройдёмся по всем полям
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
// Проверим валидность поля, используя встроенную в JavaScript функцию checkValidity()
if (input.checkValidity() == false) {
var inputCustomValidation = new CustomValidation(); // Создадим объект CustomValidation
inputCustomValidation.checkValidity(input); // Выявим ошибки
var customValidityMessage = inputCustomValidation.getInvalidities(); // Получим все сообщения об ошибках
input.setCustomValidity(customValidityMessage); // Установим специальное сообщение об ошибке
// Добавим ошибки в документ
var customValidityMessageForHTML = inputCustomValidation.getInvaliditiesForHTML();
input.insertAdjacentHTML('afterend', '<p class="error-message">' + customValidityMessageForHTML + '</p>')
stopSubmit = true;
} // закончился if
} // закончился цикл
if (stopSubmit) {
e.preventDefault();
}
});
Вот что происходит при клике на submit теперь:
Используем нестандартные проверки валидности
Иногда встроенной в браузер валидации бывает недостаточно. Нам может понадобиться, чтобы вводимые данные удовлетворяли некоторым дополнительным правилам. Например, чтобы в текстовом поле требовалось указать особые символы.
Так как мы уже проверяем все возможные ошибки вручную в нашей функции CustomValidation.prototype.checkValidity
, мы можем просто-напросто добавить туда ещё несколько проверок.
CustomValidation.prototype.checkValidity = function(input) {
// Тут идут встроенные проверки валидности
// А тут специальные
if (!input.value.match(/[a-z]/g)) {
this.addInvalidity('At least 1 lowercase letter is required');
}
if (!input.value.match(/[A-Z]/g)) {
this.addInvalidity('At least 1 uppercase letter is required');
}
};
Валидация в реальном времени
Хотя текущий способ выглядит намного лучше, он тоже не без изъянов. Наихудший из недочётов заключается в том, что пользователь не сможет увидеть никаких сообщений, пока не нажмёт на кнопку отправки формы. Было бы гораздо лучше, если бы валидация поля происходила сразу же при его заполнении. Можно выделить три правила для того, чтобы с формой было удобно работать:
- Требования для каждого поля чётко видны до того, как пользователь начал печатать.
- Как только пользователь начинает вводить данные, соблюдая требования, он сразу видит индикатор успешного заполнения поля или подсказки, если есть ошибки.
- Нужно отображать сообщения об ошибках таким образом, чтобы пользователь не мог отправить некорректно заполненную форму.
Если вы хотите попробовать свои силы (и даже сделать получше), вы можете воспользоваться вот этим шаблоном.
«Доктайп» — журнал о фронтенде. Читайте, слушайте и учитесь с нами.
ТелеграмПодкастБесплатные учебники
Регистрируясь может допустить ошибки, нужно что бы все допущеные пользователем ошибки выводились, ниже скрипт выводит только по одной
function output_errors($errors){
$errors = implode("<br>",$errors);
return '<ul><li>' . implode('</li><li>',$errors) . '</li></ul>';
}
if($_SERVER["REQUEST_METHOD"]=="POST"){
if(empty($fn)){
$errors[]= "заполните имя";
}
elseif(empty($ln)){
$errors[]= "заполните фамилию";
}elseif(empty($un)){
$errors[]= "заполните логин";
}elseif(empty($em)){
$errors[]= "заполните email";
}elseif(empty($pswd)){
$errors[]= "пароль не должен быть пустым";
}elseif(!filter_var($em, FILTER_VALIDATE_EMAIL)){
$errors[]= "введите корректно email";
}elseif(email_exists($em)==true){
$errors[]= "$em используется";
}elseif($em!=$em2){
$errors[]= "email должен совпадать с введеным";
}elseif(strlen($pswd)<6 or strlen($pswd)>32){
$errors[]= "пароль должен быть больше 6 и меньше 32 символов";
}elseif($pswd!=$pswd2){
$errors[]= "пароли дожны совпадать";
}elseif(user_exists($un)==true){
$errors[]= "$un уже используется";
}elseif(strpos($un,0x20)!=false){
$errors[]= "логин не должен содержать пробелы";
}elseif(strlen($un)<6 or strlen($un)>32){
$errors[]= "Логин должен быть не меньше 6 символов и не больше 32";
}elseif(strlen($fn)<3 or strlen($fn)>32){
$errors[]= "имя должно быть не меньше 3 символов и не больше 32";
}elseif(strlen($ln)<3 or strlen($ln)>32){
$errors[]= "Фамилия должна быть не меньше 3 символов и не больше 32";
}else{
$query = array (
'username' => trim($_POST['username']),
'password' => $_POST['password'],
'first_name' => trim($_POST['fname']),
'last_name' => trim($_POST['lname']),
'email' => $_POST['email'],
'email_code' => md5($_POST['username']+ microtime()),
'bio' => 'write somesing'
);
register_user($query);// отправляет на ємейл сгенерированный код
die("<h2>регистрация завершена, активируйтесь</h2>");
}
if(empty($errors)===false){
echo output_errors($errors);//выводит ошибки
}
}
Deleted
3711 золотой знак5 серебряных знаков13 бронзовых знаков
задан 10 фев 2013 в 13:42
Уберите elseif
, замените на else
, в массив $errors
кидайте ключ ошибки и её обозначение, потом смотрите массив, если он пустой, то рег., нет, то выводите сообщение об ошибке
if(empty($_POST['lname']))
{
$error[1] = 'Введите логин';
}
if(empty($_POST['email']))
{
$error[2] = 'Введите емайл';
}
и так далее
Потом:
if(!empty($error))
{
foreach($error as $value)
{
echo 'Ошибка:'.$value;
}
}
else
{
// Заносим в базу
}
Deleted
3711 золотой знак5 серебряных знаков13 бронзовых знаков
ответ дан 10 фев 2013 в 13:50
angers777angers777
4621 золотой знак7 серебряных знаков20 бронзовых знаков
2
Отображение сообщений об ошибках при заполнении полей формы
Если данные формы перед отправкой на сервер проверяются на правильность,
то непременно возникает необходимость показывать пользователю сообщения об ошибках.
Функция alert в этом случае неудобна, особенно если в форме допущены сразу
несколько ошибок (представьте себе, что пользователю будут показаны сразу несколько алертов подряд,
он может потом просто забыть, что ему нужно исправить).
Идеальным выходом в этой ситуации может послужить выведение сообщений об ошибках прямо в форме,
возле поля, вызвавшего ошибку.
Если установить относительное позиционирование для тегов label,
то в этом случае, установив для класса errorMsg абсолютное позиционирование,
можно помещать сообщение в любом месте относительно поля.
В функции showError сразу создается элемент span с ошибкой errorMessage,
которому присваивается имя класса errorMsg для установки стиля сообщений об ошибках.
Затем добавляется этот элемент внутрь тега label.
field — поле, возле которого нужно вывести сообщение об ошибке;
errorMessage — сообщение об ошибке.
Нажмите кнопку «Отправить», чтобы увидеть результат.
Исходный код этого примера:
<style>
form p {
margin-bottom: 20px;
}
form label {
position: relative;
}
.errorMsg {
position: absolute;
left: 0;
top: 40px;
width: 200px;
color: red;
font-size: 12px;
font-style: italic;
}
</style>
<form id="frm" action="" onsubmit="return checkForm()">
<p>
<label for="firstName">Имя:</label><br>
<input id="firstName" name="firstName" value="">
</p>
<p>
<label for="lastName">Фамилия:</label><br>
<input id="lastName" name="lastName" value="">
</p>
<p>
<input type="submit" name="go" value="Отправить">
</p>
</form>
<script>
//Функция проверки полей формы
function checkForm() {
showError('firstName', 'Неверно заполнено поле!');
return false;
}
// функция сообщения об ошибке
function showError(field, errorMessage) {
var errorSpan = document.createElement("span");
var errorMessage = document.createTextNode(errorMessage);
errorSpan.appendChild(errorMessage);
errorSpan.className = "errorMsg";
var fieldLabel = document.getElementById(field).previousSibling;
while (fieldLabel.nodeName.toLowerCase() != "label") {
fieldLabel = fieldLabel.previousSibling;
}
fieldLabel.appendChild(errorSpan);
}
</script>