Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Скрипт проверки правильности заполнения формы.


 javascript.aho.ru Javascript в браузерах: разработка, документация, примеры. Выпуск # 5, 2006-05-14
краткое содержание

Скрипт проверки правильности заполнения формы.

(1) Проверка правильности заполнения форм. Часть 2-я. (2) Генерация палитры цветов - компактнее и быстрее, чем выдавать HTML-страницу.
Существует дней: 24
Автор: 12345c
Другие выпуски:
Рассылка 'Упражнения по яванскому письму. Javascript.'
 
Примечание
12.05.06

О выпуске.

Завершаем тему проверки форм, начатую в прежнем выпуске рассылки. Смотрим примеры, в которых проверка происходит после каждого нового символа.

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

Что делать с примерами кодов?

Если Вы - разработчик HTML-страниц, привыкайте не бояться проверки примеров. Они для того приводятся, чтобы проверять. Копируем текст примера себе в файл, называем его с расширением *.htm и просматриваем в браузере (если не уточнено, в каком, то в любом).

Уровень: для начинающих.
-v---

Статья.
12.05.06

Проверка заполнения форм. 2.

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

Конечно, и о теме проверки формы при отправке можно говорить много и привести много примеров. Впоследствии, примеры на эту тему будут складываться в ресурсы скриптов на сайте, а сейчас рассмотрим другой вариант, "более жёсткую" проверку правильности текста после каждого введённого символа. Поможет в этом событие onkeyup - отпускание клавиши клавиатуры.

Надо сразу упомянуть 3 момента. 1. Проверка поля после ввода каждого символа не означает, что проверка при отправке формы не нужна. Она нужна в зависимости от задачи. Пример: надо ввести 2 слова, разделённых пробелом. "ааа БББ". Пока мы ввели "ааа<пробел>", проверка каждого символа должна этот текст пропустить, но отправлять этот текст пока нельзя, в чём поможет проверка при отправке. Второй момент - проверки в JS не отменяют необходимости проверки введённых данных на сервере, потому что пользователь всегда может сознательно отправить такой ответ, который обойдёт проверку (отключить JS, сломать скрипт, написать или внедрить в страницу свою форму). 3-й. Не забывайте, что вводить символы можно ещё 4 способами: по Ctrl-V, через меню браузера Edit-Paste, через контекстное меню, вызываемое по правой кнопке мыши: Paste. Перехватить это событие (onpaste) позволяет только IE (проверьте: <input onpaste=alert(0)>), поэтому при написании скрипта надо помнить, что во время следующей проверки может появиться не 1 новый символ, а много. 4-й способ - ввести значение в поле другим скриптом (или программой автозаполнения форм).

Кроме скриптов, в проверке полей поможет атрибут maxlength html-тега input (максимальное число введённых символов), работающий независимо от скриптов. (Он не работает в textarea, о чём имеется обыкновение забывать.)

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

Перечислим задачи, примеры решения которых будут приведены. В решениях выберем сигнализацию ошибки через покраснение фона поля ввода. Это чуть сложнее, но лучше, чем выдавать alert(), прерывая работу.

  1. Сигнализировать о вводе не-числа.
  2. Блокировать ввод нецифры.
  3. Сигнализировать о вводе не-имени (не цифра, не буква (рус. или лат.), не знак подчёркивания, не дефис; начинается с буквы).
  4. Разрешать ввод слов из строго заданного списка.
  5. Ввести не более 2 слов, каждое длиной не более 15 символов, разделённые только 1 пробелом.
  6. Проверка диапазона вводимого числа. (От 5 до 150, например.)

(Посмотреть все работающие примеры к статье.)

1. <style>.err{background-color:#E9C0B6}</style>
<input value=12 onkeyup=this.className=isNaN(this.value)?'err':''>

А без классов нельзя?

Можно (this.style.backgroundColor='#E9C0B6';), но с классами отделяется оформление (дизайн) от скриптов, что удобнее в дальнейшей вёрстке.

Пример хорошо иллюстрирует, что блокировать не-число не всегда полезно. Попробуйте ввести "-5" или "1e6" (1 * 10 в шестой степени, миллион в экспоненциальном представлении). Одиночный знак "-" показывает ошибку, "e" без цифр после неё - тоже.

2. (стиль тот же)
<input value=12345
  onkeyup=this.className=/\D/.test(this.value)?'err':''>

(Это код сигнализации, код с блокировкой ниже.)

Теперь ищем в строке не-цифру (\D) и немедленно сигнализируем о результате.

Можно было анализировать и код нажатой клавиши (event.keyCode), но текст программы будет длиннее, и если вынесем её в обработчик прерывания (т.е. избавимся от onkeyup в теге), то в для доступа к объекту события event для Gecko (Mozilla, Firefox) возникнут дополнительные сложности. Рассмотрение вариантов с обработчиком в нашу задачу не входит, но так, как записано, будет компактнее и очевиднее.

Всё понятно, но что за вопросики и двоеточия в коде? (анекдот такой про знак бесконечности: всё понятно, но почему восьмёрки боком?)

Запись оператора if-else, называется "(?:)" см. учебник: (?:).

Да и о регулярных выражениях надо упомянуть. Учебники их не очень жалуют вниманием, всё больше традиционные функции рассматривают: indexOf(), substring(). Между тем, они стали сильным и полноправным членом многих языков. В онлайне читайте здесь.

2. (стиль тот же) Решение с блокировкой.
<input value=12345 onkeyup=ff(this)>
<script>
ff=function(t){
  t.className=/\D/.test(t.value)?'err':'';
  if(/\D/.test(t.value))t.value=t.defaultValue;
  else t.defaultValue=t.value;
}</script>

Чтобы не придумывать лишних переменных, воспользовались стандартным свойством полей defaultValue. Если строка проверку прошла, она в него запоминается, и последующая ошибка проверки возвращает поле value к ранее запомненному. На экране успеваем увидеть ошибочный текст, что даже нагляднее, чем если бы действий не было. Но дополнительно помечаем ошибку цветом фона, как договорились. Пометка остаётся висеть далее на правильном тексте. Неплохо бы её через некоторое время снять:

2. (стиль тот же) Решение с блокировкой и временным показом ошибки.
<input value=12345 onkeyup=ff2(this)>
<script>
ff2=function(t){
  t.className=/\D/.test(t.value)?'err':'';
  if(/\D/.test(t.value)){t.value=t.defaultValue;
    if(self.ww)clearTimeout(ww);
    o=t;
    ww=setTimeout("o.className='';",999);
  }else t.defaultValue=t.value;
}</script>

Суеты становится больше; оно и понятно, добавляется новое измерение - время.

Что за операции с ww? self?

ww - переменная, хранящая состояние таймера (скрытого формата). Вначале её не существует, поэтому делаем проверку на существование, чтобы не было ошибки скрипта. self - то же, что window, но на 2 буквы короче. Без него if(ww) всё равно даст ошибку, проверки не получится.

Зачем o=t; ?

Запомнить this в статический объект под именем o, потому что с ним через 999 мс произойдёт операция, а передать его внутри setTimeout() можем только по имени.

3. Проверка ввода имени.
<input value=12345 onkeyup=ff3(this)>
<script>
ff3=function(t){
  /[a-zA-Zа-яА-ЯёЁ][\wа-яА-ЯёЁ]*/.test(t.value);
  t.className=RegExp.lastMatch!=t.value?'err':'';
}</script>

Действие основано на том, что опознанное по рег.выр. имя должно совпадать с введённой строкой. "Строка == имя". Решение возможно не в единственном этом виде (такой вид первым попался, раз уж использовали выше .test() ).

4. Ввод слов из строго заданного списка.
Допустимые значения: 
<script>
strng=',050,095,066,067,097,096,063,038,068';
document.write(strng.substring(1));
chkStrng=function(){    var v=document.f1.i1;
    if(isNaN(v.value)||strng.search(','+v.value)<0)
        {v.value=v.defaultValue;return!1;}
    else v.defaultValue=v.value;
}
</script><br>
<form name=f1 ... onsubmit=return(chkStrng())>
   <input name=i1 onKeyUp=chkStrng()
   onpaste=chkStrng() maxlength=3>
</form>

Было такое обсуждение и такой вариант скрипта. Проверяется совпадение с каким-либо из начал образцов, перечисленных в строке. Перестаёт вводиться, если нет ни одного совпадения.

Следующая задача взята тоже из свежего обсуждения способов решения задачи. В конце получилось краткое решение (после выбрасывания необязательных сущностей).

5. Не более 2 слов, каждое длиной до 15 символов,
   разделённых 1 пробелом.
<input size=36 onkeyup=ff5()><br>
<span id=s2></span>
<script>
ff5=function(t){
  var a=(t=this.value).match(/[\wа-яА-ЯёЁ]{1,15}/g);
    //получили массив слов или пусто
  document.getElementById('s2').innerHTML=
    a!=null         //условие проверки: хотя бы одно слово, но:
    && (a.length==2 && t==a.join(' ')        //или 2 с пробелом
      || a.length==1 &&  t.replace(/ /,'')==a[0]);   //или одно
</script>

Признак ошибки, для разнообразия, отображается в строке под полем ввода. При желании его можно преобразовать в любой другой.

В исходном коде примера на странице демонстрации, кстати, можно увидеть ту же функцию, но записанную не в 6 строк, а в одну, длиной 170 символов. В тексте статьи такой формат не помещается, да и нечитабелен, и без комментариев, но факт, что возможна запись как в поле атрибута "onkeyup", так и в вызове отдельной функции. Для рабочих страниц это не имеет значения, и предпочтителен краткий формат (если только не идёт отладка скрипта с проблемами вследствие краткого формата).

Следующий пример - полуфабрикат для использования проверки при отправке формы. Использует метод onblur для выполнения действий. В конечном продукте эти действия, очевидно, должны находиться в onsubmit формы или быть встроены в немедленную проверку другим способом. Сейчас же видим, что пользователь для наблюдения эффекта должен сделать неочевидное действие - покинуть поле ввода, щёлкнув мышью вне поля или нажать Tab.

6. Ограниченный диапазон ввода числа.
  Вместо сигнализации - корректировка значения поля.
<input onblur=ff6()>
<script>
ff6=function(t){
  max=150;  min=5;
  if(isNaN(this.value))this.value='isNaN';
  else {if(this.value > max)this.value=max;
  else if(this.value < min)this.value=min;
}
</script>

 

Получилось много текстов с примерами, а ещё не рассмотрены очень популярные варианты проверки на ввод почтового адреса, правильного УРЛ страницы, проверка на "не менее 3 символов". Но, так как они популярны, то и ответы нетрудно найти по форумам или учебникам. Если не написать самому. К примеру, условие проверки на правильный (относительно) почтовый адрес:

/([\w\.-]{1,25}@[\w-\.]+(?:\.[a-zA-Z]{2,3}))/.test(переменная)

Лучше освоить программирование и управление объектами помогут упражнения в модификациях приведённой группы примеров.

Уровень: для начинающих.
-v---

Статья
12.05.06

Генерация палитры цветов.

Они иногда применяются, чтобы дизайнер посмотрел, как выглядит цвет на веб-странице. Эту функцию с успехом заменяют палитры в html- и графических редакторах. Часто они нужны в онлайновых веб-редакторах, чтобы в окне браузера выбрать нужный цвет. Оказывается, генерировать скриптом их значительно выгоднее, чем передавть html-код таблицы, составляющей палитру.

Если цвета палитры генерировать автоматически, в виде палитры безопасных цветов, код генерации оказывается совсем компактным. Древний код, который мог работать в NN3, занимал 1.5 кбайта, а генерировал таблицу, которая занимала бы размер 15 Кбайт. Более гибкая в настройке палитра - та, в которой цвета задаются явно. Перечислив цвета, указываем их расположение в матрице. Подобный код, генерирующий таблицу из 140 цветов, имеющих собственные названия, имел размер 3.8 Кба (с указанием имён цветов). На странице иллюстрации можем посмотреть вид этих древних таблиц, которые позволяли сравнивать видимость текста разных цветов на общем фоне выбранного цвета. Обратите внимание, что простого механизма смены цвета текста не существовало, и симметричной операции просмотра текста выбранного цвета на разных фонах нет. (Сейчас это сделать легко, есть и стили, и innerHTML.) Механизм состоял из 4 таблиц - 2 из "безопасных" цветов, 2 из имеющих собственные названия. Пары различались шириной генерируемых таблиц: экраны были маленькие, окна - ещё меньше, поэтому суженные таблицы были практичны.

Для выбора цвета фона ничего не мешает сделать размер ячейки палитры небольшим. Поэтому следующем примере выбираем размер ячейки в 6 пикселей. Если надо оценить видимость цветного шрифта на разных цветовых фонах, придётся сделать палитру достаточно большую, чтобы разместить в ней множество примеров текста разных оттенков, как сделано в тех древних таблицах.

Перенесём построение палитр на базе массивов заданных цветов в следующий выпуск, а сейчас рассмотрим автоматическую генерацию 216 "безопасных" (т.е. одинаково хорошо отображаемых и различимых в разных браузерах) цветов в виде таблицы из 36х6 квадратиков. "Безопасность" с совершенствованием отображения цвета в программах становится постепенно менее актуальной, но всё равно существует как признанный стандарт.

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

Итого, программа состоит из 2 частей: генерация таблицы и обработка прерываний (событий). Сделаем генерацию таблицы не обязательно при загрузке (тогда бы пользовались document.write() ), а в любой удобный момент, например, по клику на кнопке. Код табицы вставляется через свойство элемента innerHTML в нужное место страницы. Если нужно будет строить таблицу при загрузке страницы, сгенерированный код можно вставить или по document.write() на этапе загрузки, или во время события onload страницы через innerHTML.

Приводимый ниже код, скажем заранее по секрету, отлаживался на многих примерах, в том числе и на генерации таблицы по списку цветов, что будет темой следующего выпуска. Поэтому он краток, реализует много идей и будет использоваться в дальнейшем. Если вы возьмётесь делать подобный код заново, не будет минусом то, что он окажется в 2-3 раза больше по объёму.

<input type=button value=Генерировать onClick=gen6('7')><br>
<script>d=document;
gen6=function(p){b='FFCC99663300'.match(/../g); //массив,6 элем.
s='';j=0;
while(j<216)      //сначала ячейки и строки таблицы в s
  s+=(j%36?'':'<tr>')+'<td bgColor='
    +b[(j-j%36)/36]+b[(j-j%6)/6%6]+b[j%6]
    +' style="font-size:4px" width=6 height=6></td>'
  +(++j%36?'':'</tr>');
d.body.innerHTML+=      //затем обрамление таблицы в конец док.
  '<table bgColor=black cellpadding=0 cellspacing=1 id=t'
  +p+'>'+s+'</table><input id=it'+p+'>';
}</script>

В этом коде таблица для простоты помещается в конец документа. Время генерации на процессоре 2 ГГц занимает около 0.3-0.5 с.

Если в IE будет !DOCTYPE, вместо свойства .body будет .documentElement. Код придётся немного переделать. Параметр p функции создан для того, чтобы при нескольких таблицах каждая знала своё поле ввода. С каждым новым кликом туда следует вписывать новое имя или число.

Осталось добавить функции обработчиков событий.

<script> clicked=0; //признак: показывать/фиксировать код цвета
d.onmouseover=function(e){  t=d.all?event.srcElement:e.target;
  if(clicked||t.tagName!='TD')return;
      //отсечка обработки не-ячеек таблицы,
      //d.all?.. - для совместимости Gecko/IE
  if(t.bgColor)
    d.getElementById('i'+t.offsetParent.id).value=t.bgColor;
}
d.onclick=function(e){  t=d.all?event.srcElement:e.target;
  if(t.tagName!='TD'&&t.tagName!='TABLE')return;
  clicked=1-clicked;
}</script>

Без них получим просто красивую палитру, а с ними она начнёт работать.

if(t.bgColor) здесь из-за того, что на странице попадаются другие таблицы с неопределённым bgColor.

В onclick обрабатываем не только tagName=='TD', но и таблицу по той понятной причине, что клики могут попасть на границу ячеек, а реакцию на них всё равно надо выполнить, в отличие от первой функции, где требуется только событие над ячейкой.

Для автоматической генерации таблицы:

<script>onload=gen6;</script>

Почему нет d. (document.) ?

Событие относится к окну, поэтому можно было писать window.onload, но, как известно, объект окна задан для всех свойств и методов по умолчанию.

Как можно заметить, отсутствие параметра в gen6() нормально переносится при запуске. Единственное неудобство, что при 2 таких таблицах их id станут одинаковыми; следует переделать процедуру, если таких таблиц будет больше 1 на странице.

Работающий пример генерации палитры - там, же, где остальные демострации примеров текущего выпуска.

Уровень: для программистов
-v---

 javascript.aho.ru , © I.Svetlov, 2005-2006 
Текущая очерёдность плана статей (подписчики могут корректировать через голосование).
7. Палитры цветов для веб-редакторов. Выбор цвета фона, цвета текста.
2. Автоматический выбор группы опций в мультиселект-списке, многоуровневое меню в <select>,
3. Как писать тексты с доступом через JS без экранирования специальных символов (&lt; и другие).
4. select и list - в них есть много общего. Как и с меню навигации. Эмулятор селекта.
5. Древовидное меню, подход к данным, отделение данных от представления.
6. Многонедельный календарь со ссылками. (По списку строится календарь.)

Если обнаружилось, что приходили не все письма, пожалуйста, сообщите об этом автору рассылки, чтобы помочь разобраться, какие коды некоторые почтовые серверы не пропускают. Было замечено, что HTML-коды одного примера не проходили через POP-сервер с программой SpamAssassin версии 3.1.0 .

 


В избранное