Любой уважающий себя сайт обожает предлагать посетителям заполнить какую-нибудь форму, будь то подписка на новости, регистрация, или оформление заказа. А вот посетители бывают разные; заполняя предлагаемые поля, они нередко склонны давать волю фантазии, посылая порой на сервер такие данные, которые ставят обработчик в тупик. Конечно, хорошо написанный скрипт, принимающий форму, должен уметь проверять поля и заставлять пользователя перезаполнить некорректные данные. Однако куда лучше эту проверку делать непосредственно в момент заполнения формы, чтобы не перегружать сервер лишними запросами, да и время заполняющего сэкономить. |
Все мы когда-нибудь заполняли формы. Кое-кто даже обрабатывал собранные ими результаты, будь то сделанные в интернет-магазине заказы, или обратка по сервису. Прося пользователя заполнить какую-либо информацию, мы хотим, чтобы она соответствовала определенному формату, особенно если в дальнешем она обрабатывается CMS вроде 1C bitrix, WorldPress, и так далее. Ведь если в графе телефон пользователь зачем-то запишет свой логин Skype, может возникнуть ошибка обработки данных: они не запишутся, и пользователя снова выбросит на страницу заполнения формы. Следовательно, возникает вопрос о том, как бы провести проверку введенных данных в режиме он-лайн и не допустить отправку некорректных данных.
Работу описываемого решения, разработанного нами, можно сразу оценить на примере процедуры оформления заказа на сайте компании "Ньюком". А ниже начнем повествование о процессе его разработки, а так же приведем еще несколько примеров.
Сделать простенькую javascript-проверку полей формы перед ее отправкой на сервер – дело пары минут. Только вот когда эту простенькую пишешь десятый раз для одного только сайта, невольно задумаешься об автоматизации этого процесса. В какой-то момент мысли об этом стали столь навязчивы, что пришлось сесть и накатать миниатюрную библиотеку, разбирающуюся с полями.
Если разбить задачу на блоки, то получится примерно следующая схема:
Какие поля чаще всего встречаются в формах?
Раз уж мы взялись писать более-менее универсальный скрипт, то нужно подумать и о извращенных необычных конструкциях, которые в дальнейшем будут называться «группы». Под этим словом будем подразумевать связанные друг с другом поля. Например, если пользователь поставил флажок «Присылать на почту новости» - становится обязательным к заполнению пункт «e-mail», или телефон нередко любят разделять на код и сам номер – тогда корректность должна проверяться по всем полям, а некорректность одного влечет за собой ошибку в обоих. Да и сообщение об ошибки надо выводить не у всех полей групы, а только у одного, иначе от их количества начнет в глазах рябить.
Какой вывод можно сделать?
Надо организовать обычную проверку на текстовое поле, проверку на email и «цифровые» поля вроде телефона, возраста,
итп. Чекбоксы и радиокнопки проверяем на свойство checked, выпадающие списки – по значению. Чтобы удовлетворить
хитрые группы – написать обработчик и для них. Кроме того, обеспечить возможность проверки некоторых полей
какой-нибудь пользовательской функцией для особо замороченных случаев.
На мой взгляд, вариантов хранения тут всего два:
JS-объект будет быстрее работать, да и смотреться куда корректнее, нежели какие-то нестандартные атрибуты в тегах. Скажем, выглядеть он будет так:
var checkThis={ handle: "$("[name=\"someName \" ]")",//указатель на проверяемое поле type: "email",//тип проверки: обычная, емейл, цифра title:"введите сюда емейл, например",//хинт об ошибке nesess: true,//флаг обязательности group: false,//указатель группы }; var AllChecks=[checkThis];//а это - массив, где хранились бы все проверяемые объекты
Если программист добирается до сайта, когда он уже полностью сверстан (то есть действие происходит в фантастическом романе) – такой подход прекрасен. Но зачастую что-то обязательно будет доделываться, в том числе могут дописываться дополнительные поля или создаваться новые формы, а оставлять добавление обработчиков полей на совесть верстальщиков, даже при наличии написанного конструктора, - значит обрекать себя на постоянные обращения с их стороны в стиле «а у меня тут все поломалось». И тогда о главном постулате задумки, автоматизации (ну, точнее, избавлении себя-любимого от ненужных телодвижений), придется забыть.
Тогда можно попробовать засовывать данные о проверке в нестандартные атрибуты, превращая лаконичное
в громоздкого монстра вроде Остановимся мы именно на этом варианте. Мы же за универсальность.Затем введем следующие обрабатываемые теги:
title | Он, конечно, стандартный, но сюда мы запишем сообщение об ошибочном заполнении поля. И выводить будем в стиле «Укажите »+title |
cfm_check | Флаг проверки, именно по нему мы и будем искать проверяемые поля. А значения он может принимать следующие:
|
cfm_confirminfo | По умолчанию ошибки будут выводиться сразу после проверяемого элемента, что не всегда удобно. Так пусть же в
этом атрибуте мы укажем jq-селектор на элемент, после которого выводить ошибку. Например, cfm_confirminfo=’#placeForErrors’ |
cfm_function | Чтобы не усложнять перегруженный cfm_check, сюда мы запишем название нестандартной функции-проверки поля |
Информацию мы получили, осталось лишь ее обработать. Алгоритм здесь не замороченный:
Наверное, уже пора выдать js-код, реализующий функционал хотя бы частично, раз уж отписана такая куча текста?
if(typeof cFM_classError === "undefined")//сюда запишем css-класс, приписывающийся неправильным полям var cFM_classError="cFM_wrong"; function cFM_checktrueAttr(parent)//подготавливает данные к обработке //(parent – jq-указатель на форму, или объединяющий блок) { var error=true; //подчищаем за вызванной ранее функцией $("div."+cFM_classError).remove();//убираем подсказки $("."+cFM_classError).each(function(){//убираем подсветку ошибок $(this).removeClass(cFM_classError); }); //ищем поля для проверки var inputsToHandle=false; if(typeof parent !== "undefined") inputsToHandle=parent.find("[cFM_check]"); else inputsToHandle=$("[cFM_check]");//ну, а если родитель не задан – давайте уж все проверим //хватаем найденные элементы и наблюдаем их inputsToHandle.each(function(){ if(error) error=cFM_prepareChecking(this);//проверяем объекты, ищем хотя бы единственную ошибку else cFM_prepareChecking(this); }); return error;//возвращаем true, если все элементы прошли ошибку, и false, если кто-то завалился } function cFM_prepareChecking(handle)// запускает проверку конкретного элемента и маркерует ошибочные { var error=true;/*возвращаемое значение; смысл - просто показать, что есть ошибка принимает значение: true - нет ошибок; false - поле не заполнено; "wrong" - поле заполнено неправильно;*/ //определяемся с подписью поля в случае обнаружения в нем ошибки. По умолчанию будет выводиться //"Укажите значение поля", если title не задан var title = " значение поля"; if(typeof $(handle).attr("title") !== "undefined" && $(handle).attr("title").length>0) title=$(handle).attr("title"); var after = handle;//куда лепить сообщение об ошибке var attribute = $(handle).attr("cFM_check");//значение великого атрибута cFM_check //а не задали ли какую хитрую функцию для проверки поля? if(typeof $(handle).attr("cFM_function") !== "undefined") var chkFunk=$(handle).attr("cFM_function"); //наконец, проверяем поле if(typeof chkFunk !== "undefined") error=window[chkFunk]($(handle)); else error=cFM_checkFullness(handle); //коль ошибка закралась к нам if(error!==true) { //определяем, куда лепим сообщение об ошибке if(typeof $(handle).attr("cFM_confirmInfo") !== "undefined") { after=$(handle).attr("cFM_confirmInfo"); if(after.indexOf("self")===0)//если вдруг селфы непойми зачем прилепили after=after.substr(4); } if(error==="wrong")//коль поле заполнено неправильно $(after).after("Неверное значение поля"); else{ if(error===false)//коль не заполнено вообще $(after).after("Укажите "+title+"");//html ошибки else//если особая проверка с особой html $(after).after(""+error+""); } $(handle).addClass(cFM_classError);//добавление класса ошибки if($(handle).attr("type")=="radio")//дорабатываем радиокнопки $("[name=""+$(handle).attr("name")+""]").addClass(cFM_classError); error=false; } return error; } function cFM_checkFullness(handle)//а это стандартная функция проверки { var error = true; //считываем данные с атрибутов var attribute = $(handle).attr("cFM_check"); //флаг обязательности var required = true; if(attribute.indexOf("Y")===-1) required=false; //проверка на формат var format=attribute; if(required) format=attribute.substr(2); switch($(handle).attr("type"))//смотрим, что же у нас за элемент такой { case "checkbox": if(!$(handle).prop("checked")) error=false; break; case "radio"://обещанная проблема с radio if(!$(handle).prop("checked") && $("[name=""+$(handle).attr("name")+""]:checked").length==0) error=false; else error=true; break; //и text, и select, и textarea здесь идентичны default: if(($(handle).val().trim().length==0 || $(handle).val()=="0") && required) error=false; else { if(format==="num")//проверка на число { var regCheck = new RegExp("[^0-9\s-]+"); if(regCheck.test($(handle).val())) error="wrong"; } if(format==="email")//проверка на е-мейл { var regCheck = new RegExp("^([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$"); if(!regCheck.test($(handle).val())) error="wrong"; } } break; } return error; }
В качестве примера приведем так же особую функцию проверки, например, проверяющую на наличие двух слов в инпуте (Имя Фамилия или Имя,Фамилия). Инпут, запускающий проверку по этой функции реализуется таким образом:
А функция проверки будет выглядеть, например, так:function checkName(handle) { var handleValue=handle.val().trim(); //как показывает практика, пользователи чем только не отделяют свое имя от фамилии if(handleValue.indexOf(" ")!==-1 || handleValue.indexOf(",")!==-1 || handleValue.indexOf(".")!==-1) return true; else return false; }Ну и стиль надо бы какой-нибудь нашей проверке задать:
div.cFM_wrong { color:red; font-size:10px; position:absolute; width:140px; } input.cFM_wrong{ background: #ffd9d9; border-color:#d3adad; }
Теперь в случае успешного выполнения функции cFM_checkFullness() (то есть возвращения true) скрипт должен отсылать форму на обработку. Как это реализовать - зависит уже от конкретной формы. Если подтверждение на отправку идет через кнопку submit - то можно подписаться на событие отправки формы (onsubmit) и в зависимости от результата проверки отсылать ее или нет. Например, так:
Если же отправка идет с помощью ajax"а - то тут вообще все просто: вызывать его в зависимости от результата работы функции cFM_checktrueAttr($(this));
В приведенном выше коде отсутствует проверка на группы (ибо громоздкость кода возрастает в разы, а размер полосы
прокрутки данной статьи итак наверняка отпугнул многих посетителей). Различия же в алгоритме будут незначительны:
проверка элементов по группам должна запускаться в отдельном блоке, и в зависимости от работы всего блока выдавать
сообщение об ошибке в конкретном элементе.
Правда, на этом моменте стоит притормозить и задуматься: а действительно ли необходимо дорабатывать код для
поддержки групп, или можно ограничиться написанием отдельной функции проверки для пары сложных полей?
Что же мы имеем в итоге? Подключая пару файлов (.js и .css), получаем функционал проверки свойств, который можно со спокойной душой кидать на любые сайты, при условии подключенного jquery. Ведь куда приятнее иметь под рукой набор готовых инструментов, чем тратить кучу времени на их производство перед каждой однотипной задачей.
Во-первых нам понадобится библиотека jquery. Скачать ее можно, например, с официального сайта.
Или же просто вставить в шапку (то, что внутри тега <head>) вашего сайта строку
<script type="text/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>Затем качаем (правой клавишей -> понравившийся пункт со словом «сохранить») отсюда файл с js-кодом и, если нужно, файл с css-стилями для ошибочных полей отсюда.
<script type="text/javascript" src="/путьКСкрипту/ipol_cFM.js"></script> <link type="text/css" rel="stylesheet" href="/путьКCss/ipol_cFM.css">Теперь нужно расставить атрибуты полям формы согласно таблице, в зависимости от того, какую проверку вы хотите совершить.
Давайте теперь попробуем реализовать проверку такой простенькой формы:
Посмотреть кодОценить применение скрипта можно так же на сайте mosavtotrade, на всех формах стоит именно эта проверка.
На сим поток информации иссяк.
В качестве домашней работы можете взять следующие пункты: