Шаг 166.
Библиотека jQuery.
Интерактивные формы. Улучшение простой формы. Окончательная версия

    На этом шаге мы приведем окончательную версию приложения.

    Ниже приводится окончательная версия сценария для формы ввода контактной информации:

$(document).ready(function() { 
  // Добавить оформление элементов формы.
  $('legend').each(function(index) { 
    $(this).replaceWith('<h3>' + $(this).text() + '</h3>');
  });

  var requiredFlag = ' * ';
  var conditionalFlag = ' ** ';

  var requiredKey = $('input.required:first')
                               .next('span').text();
  var conditionalKey = $('input.conditional:first')
                               .next('span').text();
  
  requiredKey = requiredFlag + 
             requiredKey.replace(/^\((.+)\)$/,'$1');
  conditionalKey = conditionalFlag + 
            conditionalKey.replace(/\((.+)\)/,'$1');

  $('<p></p>')
    .addClass('field-keys')
    .append(requiredKey + '<br />')
    .append(conditionalKey)
    .insertBefore('#contact');


  $('form :input')
    .filter('.required')
      .next('span').text(requiredFlag).end()
      .prev('label').addClass('req-label').end()
    .end()
    .filter('.conditional')
      .next('span').text(conditionalFlag);

  // Переключение флажков условно-обязательных полей ввода.  
  $('input.conditional').next('span').andSelf().hide()
  .end().end()
  .each(function() {
    var $thisInput = $(this);
    var $thisFlag = $thisInput.next('span');
    $thisInput.prev('label').find(':checkbox')
    .attr('checked', false)
    .click(function() {
      if (this.checked) {
        $thisInput.show().addClass('required');
        $thisFlag.show();
        $(this).parent('label').addClass('req-label');
      } else {
        $thisInput.hide().removeClass('required').blur();
        $thisFlag.hide();
        $(this).parent('label').removeClass('req-label');
      }
    });
  });

  // Проверка полей по событию blur.
  $('form :input').blur(function() {
    $(this).parents('li:first').removeClass('warning')
    .find('span.error-message').remove();
    
    if ($(this).hasClass('required')) {
      var $listItem = $(this).parents('li:first');
      if (this.value == '') {
        var errorMessage = 'Это обязательное поле';
        if ($(this).is('.conditional')) {
          errorMessage += ', когда установлен флажок';
        }

        $('<span></span>')
          .addClass('error-message')
          .text(errorMessage)
          .appendTo($listItem);
        $listItem.addClass('warning');
      }
    }

    if (this.id == 'email') {
      var $listItem = $(this).parents('li:first');
      if ($(this).is(':hidden')) {
        this.value = '';
      }
      if (this.value != '' && 
      !/.+@.+\.[a-zA-Z]{2,4}$/.test(this.value)) {
        var errorMessage = 'Неверный e-mail формат'
               + ' (пример формата: joe@example.com)';
        $('<span></span>')
          .addClass('error-message')
          .text(errorMessage)
          .appendTo($listItem);
        $listItem.addClass('warning');
      }
    }

  });

  // Проверка полей по событию submit.
  $('form').submit(function() {
    $('#submit-message').remove();
    $(':input.required').trigger('blur');
    var numWarnings = $('.warning', this).length;
    if (numWarnings) {
        var fieldList = [];
        $('.warning label').each(function() {
          fieldList.push($(this).text());
        });
        $('<div></div>')
        .attr({
          'id': 'submit-message', 
          'class': 'warning'
        })
        .append('Исправьте ошибки в ' + 
                  numWarnings + ' полях:<br />')
        .append('• ' + fieldList.join('<br />• '))
        .insertBefore('#send');
      return false;
    };
  });

  // Флажки
  $('form :checkbox').removeAttr('checked');

  // Флажки с дополнительным флажком Отметить все (Снять все отметки)
  $('<li></li>')
  .html('<label><input type="checkbox" id="discover-all" />' + 
                                ' <em>Отметить все</em></label>')
  .prependTo('li.discover > ul');
  $('#discover-all').click(function() {
    var $checkboxes = $(this) .parents('ul:first')
                                    .find(':checkbox');
    if (this.checked) {
      $(this).next().text(' Снять все отметки');
      $checkboxes.attr('checked', true);
    } else {
      $(this).next().text(' Отметить все');
      $checkboxes.attr('checked', '');
    }
  })
  .parent('label').addClass('checkall');
});

Рис.1. Окончательная версия

Полный текст этого примера можно взять здесь.

    Несмотря на существенные усовершенствования формы ввода контактной информации, здесь еще много чего можно было бы сделать. Например, могли бы быть реализованы различные варианты проверки. Для большей гибкости можно было бы использовать модуль расширения, реализующий проверки, сведения о котором можно найти по адресу: http://plugins.jquery.com/project/validate/.

    Со следующего шага мы начнем рассматривать компактные формы.




Предыдущий шаг Содержание Следующий шаг