Наверх

Проверка валидности формы на JavaScript и HTML5 - это легко

Опубликовано:
6919
1 2 3 4 5
(95%) / 4

HTML5 представляет несколько новых атрибутов для реализации проверки на основе браузера. pattern Атрибут является регулярным выражением , которое определяет диапазон допустимых входов для textarea элементов и большинство типов inputrequired Атрибут определяет, требуется ли поле. Для устаревших браузеров, которые не реализуют эти атрибуты, мы можем использовать их значения в качестве основы для полифилла. Мы также можем использовать их для обеспечения более интересного усовершенствования - мгновенной проверки формы.

Мы должны быть очень осторожны, чтобы не увлечься, создавая чрезмерно агрессивную проверку, которая нарушает естественное поведение браузера и попадает на людей. Например, я видел формы, в которых невозможно нажать Tab, то есть исключить перейти на другой input. Очень злоупотребляется javascript, чтобы заставить фокус оставаться внутри поля, пока он не будет действительным. Это очень плохое использование и прямо противоречит рекомендациям по доступности.

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

Неверная индикация поля в Firefox 16

Конечно, это не происходит сразу. Если бы это было так, то по умолчанию каждое обязательное поле имело бы эту схему. Вместо этого эти контуры отображаются только после того, как вы взаимодействовали с полем, которое в основном (хотя и не точно) аналогично onchange событию.

Так вот что мы собираемся делать, используя onchange в качестве запуска событие. В качестве альтернативы мы могли бы использовать oninput событие, которое срабатывает, как только любое значение набирается или вставляется в поле. Но это действительно слишком быстро, так как данный метод будет запускать и отключать многие типы событий в быстрой последовательности при наборе текста, создавая эффект мигания, который будет раздражать или отвлекать для некоторых пользователей. И, в любом случае, oninput не срабатывает от программного ввода, который onchange делает, и нам может понадобиться, чтобы обрабатывать такие вещи, как автозаполнение от сторонних надстроек.

 

Определение HTML и CSS

 Итак, давайте посмотрим на нашу реализацию, начиная с HTML, на которой она основана:

<form action="#" method="post">
  <fieldset>

    <legend><strong>Add your comment</strong></legend>

    <p>
      <label for="author">Name <abbr title="Required">*</abbr></label>
      <input 
        aria-required="true"
        id="author"
        name="author"
        pattern="^([- \w\d\u00c0-\u024f]+)$"
        required="required"
        size="20"
        spellcheck="false"
        title="Your name (no special characters, diacritics are okay)"
        type="text"
        value="">
    </p>

    <p>
      <label for="email">Email <abbr title="Required">*</abbr></label>
      <input 
        aria-required="true"
        id="email"
        name="email"
        pattern="^(([-\w\d]+)(\.[-\w\d]+)*@([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2})$" 
        required="required"
        size="30"
        spellcheck="false"
        title="Your email address"
        type="email"
        value="">
    </p>

    <p>
      <label for="website">Website</label>
      <input
        id="website"
        name="website"
        pattern="^(http[s]?:\/\/)?([-\w\d]+)(\.[-\w\d]+)*(\.([a-zA-Z]{2,5}|[\d]{1,3})){1,2}(\/([-~%\.\(\)\w\d]*\/*)*(#[-\w\d]+)?)?$"
        size="30"
        spellcheck="false"
        title="Your website address"
        type="url"
        value="">
    </p>

    <p>
      <label for="text">Comment <abbr title="Required">*</abbr></label> 
      <textarea
        aria-required="true"
        cols="40"
        id="text"
        name="text"
        required="required"
        rows="10"
        spellcheck="true"
        title="Your comment"></textarea>
    </p>

  </fieldset>
  <fieldset>

    <button name="preview" type="submit">Preview</button>
    <button name="save" type="submit">Submit Comment</button>

  </fieldset>
</form>

 

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

Спецификация ARIA также определяет атрибут, и это то, что мы собираемся использовать, чтобы указать, когда поле является недопустимым (для которого нет эквивалентного атрибута в HTML5). Атрибут, очевидно, обеспечивает доступную информацию, но он может быть также использован в качестве CSS крюка , чтобы применить красный контур:aria-invalid

input[aria-invalid="true"], textarea[aria-invalid="true"] {
  border: 1px solid #f00;
  box-shadow: 0 0 4px 0 #f00;
}

 

Мы могли бы просто использовать и не беспокоиться об этом, и, откровенно говоря, это выглядело бы лучше, но тогда у нас не было бы никаких признаков в браузерах, которые не поддерживают теней коробок, таких как IE8.box-shadow border

 

Добавление JavaScript

Теперь, когда у нас есть статический код, мы можем добавить скрипты. Первое, что нам понадобится, - это основная функция: addEvent()

function addEvent(node, type, callback) {
  if (node.addEventListener) {
    node.addEventListener(type, function(e) {
      callback(e, e.target);
    }, false);
  } else if (node.attachEvent) {
    node.attachEvent('on' + type, function(e) {
      callback(e, e.srcElement);
    });
  }
}

 

Затем нам понадобится функция для определения того, должно ли данное поле быть проверено, что просто проверяет, что он не отключен и не читается, и что он имеет либо атрибут, patter nлибо required атрибут:

function shouldBeValidated(field) {
  return (
    !(field.getAttribute("readonly") || field.readonly) &&
    !(field.getAttribute("disabled") || field.disabled) &&
    (field.getAttribute("pattern") || field.getAttribute("required"))
  );
}

 

Первые два условия могут показаться многословными, но они необходимы, потому что элементы disabled и readonly свойства не обязательно будут отражать  состояния атрибутов. В Opera, например, поле с жестко закодированным атрибутом по- прежнему будет возвращаться для своего свойства (свойство dot только соответствует состояниям, которые задаются через скрипты).readonly="readonly"undefinedreadonly

Как только мы получим эти утилиты, мы можем определить основную функцию проверки, которая проверяет поле и затем выполняет фактическую проверку, если это применимо:

function instantValidation(field) {
  if (shouldBeValidated(field)) {
    var invalid =
      (field.getAttribute("required") && !field.value) ||
      (field.getAttribute("pattern") &&
        field.value &&
        !new RegExp(field.getAttribute("pattern")).test(field.value));
    if (!invalid && field.getAttribute("aria-invalid")) {
      field.removeAttribute("aria-invalid");
    } else if (invalid && !field.getAttribute("aria-invalid")) {
      field.setAttribute("aria-invalid", "true");
    }
  }
}

Таким образом поле недействительно если оно требуется, но не имеет значения, или оно имеет шаблон и значение, но значение не соответствует шаблону.

Поскольку patternу же задан строковым регулярным выражением, то нам нужно передать эту строку RegExp конструктору и создать объект регулярного выражения, который мы можем проверить по значению. Но нам нужно предварительно проверить значение, чтобы убедиться, что оно не пустое, так что самому регулярному выражению не нужно учитывать пустые строки.

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

addEvent(document, "change", function(e, target) {
  instantValidation(target);
});

Однако для того, чтобы работать, onchange события должны пузыриться (используя технику, которая обычно известна как делегирование событий ), но в Internet Explorer 8 и ранее onchange события не пузырятся . Мы могли бы просто игнорировать эти браузеры, но я думаю, что это был бы позор, особенно когда проблема настолько проста в обходе. Это просто означает немного более сложный код - нам нужно получить коллекции input и textarea элементы, перебрать их и связать onchange событие с каждым полем отдельно:

var fields = [
  document.getElementsByTagName("input"),
  document.getElementsByTagName("textarea")
];
for (var a = fields.length, i = 0; i < a; i++) {
  for (var b = fields[i].length, j = 0; j < b; j++) {
    addEvent(fields[i][j], "change", function(e, target) {
      instantValidation(target);
    });
  }
}

 

Смотрим что получилось

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

Вы можете посмотреть демо ниже:

После того, как этот скриптинг будет реализован, на самом деле у нас всего лишь пара пропусков и удалений от полного полигона. Такой сценарий выходит за рамки этой статьи, но если вы хотите его развивать дальше, все базовые блоки есть - проверка того, нужно ли проверять поле, проверять поле против шаблона и / или требовать, а также связать триггер Мероприятия.

Я должен признаться, я не уверен, что это действительно того стоит! Если у вас уже есть это усовершенствование (которое работает во всех современных браузерах обратно в IE7), и учитывая, что у вас нет другого выбора, кроме как выполнить проверку на стороне сервера, а также с учетом того, что браузеры, которые поддерживают pattern и required уже используют их для проверки перед отправкой - Учитывая все это, действительно ли есть какая-то точка, добавляющая еще один полиполк?



Дорогой web-мастер.
Для меня очень важна обратная связь от Вас в виде лайков или рейтинга.
Пожалуйста оцените эту публикацию или поставь лайк за старание.
Статья подготовлена для Вас сайтом kisameev.ru
Перевел: Кисамеев Дмитрий
Статью просмотрели: 6919
Понравилось:
Поделится ссылкой
Теги:
Комментариев...
Оставьте его первым.

Для вставки кода используйте комментарии от ВК или FB:

Похожие публикации

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

Нашли баг или ошибку?

Выдели текст
мышкой и нажми:
Нашел ошибку