Проверка количества введённых символов в большое поле HTML формы, проверка правильных символов пароля (латинские буквы и цифры), шаблон адреса e-mail (mailbox)

DHTML: проверка формы

В предыдущей статье dhtml.aspx мы сформулировали ряд причин, по которым бывает необходимо изменять HTML страницу после её открытия в браузере. Повторяем здесь список этих причин:

Для чего нужен Dynamic HTML

  1. Улучшить восприятие страницы и сделать работу с ней более удобной.
    • Скрыть-отобразить часть текста.
      • Выпадающее меню.
      • Скрыть-показать примечания (сноски).
      • Свернуть-развернуть ряд произвольных элементов.
      • Поиск по списку (отбор элементов).
    • Изменить оформление при наведении мыши.
      • Изменение формы курсора.
      • Изменение цвета активных элементов.
      • Изменение цвета строк таблицы.
      • Всплывающие подсказки.
    • Проверка вводимых пользователем данных (валидация) до отправки на сервер.
    • Хранение настроек пользователя.
    • Невидимая (ненавязчивая) защита от спама.
    • Визуальный (wysiwyg) редактор HTML.
    • Уменьшение объёма страницы и трафика (дублирование элементов).
    • Редактирование большой таблицы базы данных.
  2. Для оптимизации взаимодействия веб-сервера с клиентом.
    • Фоновые http-запросы с помощью динамического элемента script (или так называемого Ajax'а).
    • Исправление ошибок или небрежностей серверных скриптов (движка).
  3. Для создания инструментов разработки.
    • Отображение объектов DOM.
    • Отображение скорости работы браузера.
    • Редактирование большой таблицы базы данных.

10. Как проверить вводимые пользователем в форму данные?

На вопрос нельзя ответить, потому что он неточно сформулирован. Зачем вообще проверять вводимые пользователем данные? Чего мы этим хотим добиться?

Мы хотим добиться пользы для пользователя (кому фраза кажется некрасивой, читайте: пользы для посетителей сайта). Точнее, мы хотим минимизировать вред, который пользователь нечаянно или умышленно может нанести себе и сайту. Рассмотрим несколько примеров.

  1. В поле формы по какой-то причине надо вводить ограниченное число символов. Такое бывает, например, при отправке СМС через сайт или при добавлении отзывов в гостевую книгу. Если не ограничить пользователя в самой форме, сообщение будет обрезано на сервере, о чём пользователь может узнать с опозданием (и с большим удивлением). Пример простого удаления лишних букв мы привели в первом вопросе первой части обзора (http://www.ir2.ru/dhtml.aspx). Корме грубого удаления можно ещё показывать пользователю, сколько букв он уже ввёл или сколько осталось (так обычно и делают на хороших сайтах):

    В это поле можно ввести не более 30-ти букв:

    можно ещё ввести: 30

    Код всей конструкции:

     <input style="width:26em;" name="address" onkeyup="
     var len=this.value.length; 
     document.getElementById('countsymb').firstChild.nodeValue=30-len; 
     if (len>30) this.value=)this.value.substr(0,30);
     "> 
      можно ещё ввести: <span id='countsymb'>30</span>
  2. При анализе любого другого свойства вводимого текста (кроме длины) нам понадобятся регулярные выражения. Даже для такого небольшого улучшения, как удаление лишнего слова (вместо "слепого" отсечения букв). Код станет длиннее, поэтому правильнее, конечно, на событие onkeyup повесить функцию (onkeyup="testlen(this)"), и описать потом эту функцию отдельно. Выглядеть всё будет внешне точно так же:

    можно ещё ввести: 30

    Но код функции testlen(obj) увеличится очень существенно:

    var countsymb=document.getElementById("countsymb");
    var maxlen=Number(countsymb.firstChild.nodeValue);
    
    function testlen(obj) {
     //укорачивание строки с учётом границ слов
     var val=obj.value;
     var bukva="a-zа-яёЁ0-9_"; //вместо буржуйской \w
     var re=/^[\s\xa0]+|[\s\xa0]+$/g; //trim
     var re2=new RegExp("([^"+bukva+"])["+bukva+"]*$","ig");
     var re3=/[\s\xa0]+/g; //trim
     if (val.length>maxlen) {
      val=val.replace(re,""); //trim
      val=val.replace(re3," "); //двойные пробелы внутри
      if (val.length>maxlen) {
       //просто отрезать справа с запасом 1
       val=val.substr(0,maxlen+1);
       val=val.replace(re,""); //trim
       if (val.length>maxlen) {
        //отбрасывание справа до ближайшей не-буквы
        val=val.replace(re2,"$1");
        //...и если это не помогло (все - буквы)
        if (val.length>maxlen) {
         val=val.substr(0,maxlen);
        }
       }
      }
      obj.value=val;
     }
     //показываем, сколько букв ещё можно ввести
     countsymb.firstChild.nodeValue=maxlen-val.length;
    }

    Файл с примерами javascript, описанными на данной странице: dhtml2.js. К тому же мы добавили на событие onbeforepaste функцию sval(), которая заменяет разрывы строк на простые пробелы:

    document.body.onbeforepaste=sval;
    //чтобы не писать onbeforepaste в тексте страницы
    function sval() {
     //В ИЕ разрыв строки, вставляемый в INPUT 
     //через буфер обмена, фатален.
     //Перед вставкой из буфера запускаем эту функцию
     var text=clipboardData.getData("Text");
     var re3=/\r?\n+/g; //для ИЕ
     text=text.replace(re3," ");
     clipboardData.setData("Text", text);
    }

    Потому что в ИЕ невозможно через буфер обмена вставить в элемент input текст с разрывами строк. В других браузерах нет события onbeforepaste и функция sval() запускаться не будет. Но другие браузеры при копировании-вставке разрывы строк автоматом заменяют на пробелы, поэтому там и проблемы не возникнет.

    Алгоритм работы основной функции:

    1. удаляются "пробельные символы" в начале и в конце строки (аналог trim PHP);
    2. если длина больше нормы, строка обрезается до норма+1 символ методом substr(); опять делается trim;
    3. если длина больше нормы, ищется ближайшая к правому краю "не-буква" и текст обрезается справа до неё;
    4. если после этих операций длина всё ещё больше нормы, в строке нет "не-букв", и строка просто обрезается до нужной длины методом substr().
  3. Следующая проверка – на простое равенство текста в двух разных полях. Такое бывает нужно, например, во время регистрации – при вводе и подтверждении пароля.

    Пароль (латинские буквы и арабские цифры, не менее 6 символов):

    , подтверждение: ok.

    Заодно здесь возникает ещё одна задача: проверить, не попал ли в поле ввода недопустимый символ. Решается она с помощью регулярного выражения:

    /^[a-z\d]+$/i

    Читается так: от начала (знак ^) до конца (знак $) строка (пароля) должна содержать в себе один или более (знак +) символов, перечисленных в квадратных скобках [буквы в диапазоне от a до z и цифры – знак \d]. Если введённый пароль соответствует данному шаблону, всё в порядке, функция продолжает работу дальше и проверяет равенство полей пароля и подтверждения. Если пользователь введёт символ не из перечисленных в квадратных скобках, функция прерывает работу и подсвечивает рекомендацию насчёт латинских букв. Вот эта функция:

    //чтобы не писать onkeyup в тексте страницы
    var pw=document.getElementById("p1");
    var pwc=document.getElementById("p2");
    pw.onkeyup=testpw; 
    pwc.onkeyup=testpw;
    //функция валидации поля типа password
    function testpw() {
     var pwok=document.getElementById("pwok");
     var lat=document.getElementById("lat");
     if (pw.value && !/^[a-z\d]+$/i.test(pw.value)) {
      lat.style.color="#900";
      lat.style.fontWeight="600";
      return;
     }
     else {
      lat.style.color="";
      lat.style.fontWeight="";
     }
     if (pw.value.length>5 && pw.value==pwc.value) {
      pwok.style.display="inline";
      pwc.style.color="";
     }
     else {
      pwok.style.display="none";
      pwc.style.color="red";
     }
    }

    (Спасибо Илье Кантору за страничку http://javascript.ru/paste - после неё код выглядит гораздо красивее).

  4. Другие проверки вводимых значений, как правило, тоже бывают на соответствие определённому шаблону: даты, веб-сайта, электронной почты... Шаблон для "русской" даты может быть, например, таким:

    /\d\d\.\d\d\.\d\d/

    Шаблон адреса электронной почты достаточно сложен, чтобы составить его идеально, корни правильного наименования mailbox нужно искать где-то в недрах RFC (в каких частях адреса какие символы допустимы). Идеальный шаблон e-mail адреса, однако, на сайте не очень-то и нужен. Ведь для чего проверяются значения, вводимые пользователем? Если, например, он введёт недопустимый пароль, такой пароль может при попытке поместить его в базу данных вызвать ошибку (или при корректной обработке на сервере просто не попасть в БД) и испортить процесс регистрации.

    Электронный адрес, который должен куда-то там ввести пользователь, как правило, уже существует в готовом виде, уже где-то зарегистрирован (и значит наверняка валиден, правилен). Если пользователь захочет ввести выдуманный адрес (или сделает в своём адресе ошибку ненамеренно), ничто не мешает ему сделать это по правильному шаблону. Нет смысла использовать для проверки "идеальный" шаблон, потому что содержательные ошибки тут важнее. Достаточно чего-нибудь вроде:

    /^\w+@[a-z\.\-]+\.([a-z]){2,4}$/

    Справа налево: ([a-z]){2,4} – от двух до четырёх латинских букв (например, ru, com, info); [a-z\.\-]+\. – точка, и слева от точки любое количество латинских букв с точками и чёрточками; \w+@ – "собака" и слева от неё "слово" – любое количество латинских букв и знаков почёркивания. Это очень приближённый вариант (в нём, например, допустим такой адрес: ab@-.ru), он рассчитан всё-таки на добросовестного пользователя, которому может иногда дать полезную подсказку при опечатке.

    А "идеальный" шаблон e-mail адреса нужен не для валидации, а для хакеров-спамеров, чтобы с помощью этого шаблона извлекать адреса из многочисленных текстов веб-страниц и справочников.

  5. Чаще всего на практике встречается предельно простая проверка на наличие-отсутствие в полях формы каких-либо данных. Например, пользователь пытается отправить комментарий к статье, а ему выскакивает надпись: "не заполнено обязательное поле Автор!". В этом случае, конечно, лучше не просто проверять if (author.value==false), а приблизительно учитывать длину вводимого текста. Если ник "автора" ещё может в пределе состоять из одной буквы, то сам текст сообщения из одной буквы вряд ли имеет смысл (будет только засорять форум); правильнее, наверное, проверять наличие хотя бы 5-ти букв:

    if (message.value.length<5)
© 2010, «Деловая неделя», Михаил Гутентог

Комментарии

Guru 04.12.2013 09:01:21

Вот здесь http://phpguru.com.ua/posts.php?id=39 больше написано на эту тему. И примеры потыкать можно

аф 04.07.2013 22:34:00

єє круто

н88 23.03.2011 11:38:20

899г09-0г98 н79п86пнпрпорми

Sanja 11.08.2010 04:59:28

good и познавательно

укуеук 16.03.2010 00:18:15

куекуеку