Формы. Ваше веб-приложение HTML не сможет работать без них — они являются основой большинства пользовательских данных, передаваемых между браузером и сервером. Вы, несомненно, читали много статей, описывающих теги форм и проверку данных с помощью HTML5 или JavaScript. Однако сегодня мы обсудим, как проверить, изменил ли пользователь данные формы.
Зачем проверять наличие обновлений форм?
Есть много причин, по которым вы можете проверить, изменилась ли форма. Например, если пользователь обновил одно или несколько полей, но щелкнул их по странице, вы можете отобразить предупреждение «обновления не были сохранены». Вы даже можете дать им возможность сохранить данные (через Ajax). Кроме того, если обновления не выполняются, эффективность вашего приложения может быть улучшена, если не пытаться проверять или повторно сохранять данные на сервере.
Событие JavaScript OnChange — и почему его нельзя использовать
Вы можете прикрепить обработчик события onchange JavaScript к любому элементу формы HTML. Хотя этот метод представляется жизнеспособным — и я видел его в других местах — у этого подхода есть ряд проблем:
- Если пользователь изменяет значение, а затем меняет его обратно, приложение все равно будет думать, что произошло обновление.
- Если значение формы обновляется с использованием JavaScript, обработчик события onchange не будет запущен.
- Добавление обработчиков onchange к каждому элементу в больших формах приводит к накладным расходам обработки в браузере.
- Если элементы добавляются или удаляются из формы, вам необходимо соответствующим образом прикрепить и отсоединить обработчики событий.
- Событие onchange для флажков и переключателей не работает должным образом в определенном браузере. (Я подозреваю, что вы можете догадаться, какой из них!)
- Есть гораздо более простой способ …
Сравнение значений по умолчанию
К счастью, нам не нужно проходить через сложную обработку сложных событий. Каждый элемент формы имеет значение по умолчанию, связанное с его объектом, т. Е. Данные, отображаемые элементом управления формы при загрузке страницы. Это можно проверить по текущему значению, чтобы узнать, было ли внесено изменение.
К сожалению, свойства значений по умолчанию отличаются между типами элементов формы…
Текстовые поля <input> и <textarea>
Давайте начнем с простых элементов. Все теги textarea
и input
которые не являются типами «checkbox» или «radio», имеют свойство defaultValue. Мы можем сравнить эту строку с текущим значением, чтобы определить, произошло ли изменение, например:
<!-- name input --> <input type="text" id="name" name="name" value="Jonny Dough" /> <script> var name = document.getElementById("name"); if (name.value != name.defaultValue) alert("#name has changed"); </script>
Если вы используете HTML4 или XHTML, вашими типами ввода текста будут «текст», «скрытый», «пароль» или «файл». Новые типы, введенные в HTML5, также имеют свойство defaultValue и могут быть проверены в том же самом путь. Это включает в себя электронную почту, телефон, URL, диапазон, дату, цвет и поиск.
Флажки и радио кнопки
Флажки и переключатели имеют свойство defaultChecked. Это будет либо true, либо false, и его можно сравнить со свойством проверенного элемента, например:
<!-- newsletter opt-in --> <input type="checkbox" id="optin" name="optin" checked="checked" /> <script> var optin = document.getElementById("optin"); if (optin.checked != optin.defaultChecked) alert("#optin has changed"); </script>
Обратите внимание, что флажки и переключатели также имеют свойство defaultValue, но это то, что было присвоено атрибуту значения, а не текущее состояние кнопки.
Раскрывающиеся <select> Ящики
Если вы используете поле select
, оно, скорее всего, будет тем, которое позволяет пользователю выбрать один элемент из выпадающего списка.
Вот где это становится немного сложнее. Само поле выбора не предоставляет свойства значения по умолчанию, но мы можем проверить его (массивную) коллекцию элементов option
. Когда страница загружена, для свойства с атрибутом «selected» свойство defaultSelected имеет значение true.
Мы можем получить индексный номер текущей выбранной опции из свойства selectedIndex узла select. Поэтому, если для этого параметра установлено значение defaultSelected, равное false, поле выбора должно быть изменено, например:
<!-- job title select box --> <select id="job" name="job"> <option>web designer</option> <option selected="selected">web developer</option> <option>graphic artist</option> <option>IT professional</option> <option>other</option> </select> <script> var job = document.getElementById("job"); if (!job.options[job.selectedIndex].defaultSelected) alert("#job has changed"); </script>
Этот код будет работать для любого поля выбора с одним выбором, где один параметр имеет атрибут «выбранный». К сожалению, есть несколько уловов:
- Если ни у одного параметра нет атрибута selected, браузер по умолчанию будет первым, но его свойство defaultSelected будет иметь значение false.
- Если два или более параметра имеют атрибут selected (нелогично, но возможно), для всех свойств defaultSelected будет установлено значение true, но браузер может по умолчанию использовать только последний.
- Поле множественного
select
позволяет пользователю выделить любое количество параметров:
<!-- skills multi-select box --> <select id="skills" name="skills" multiple="multiple"> <option selected="selected">HTML</option> <option selected="selected">CSS</option> <option selected="selected">JavaScript</option> <option>PHP</option> </select>
Блоки выбора с множественным выбором не популярны — вероятно, потому, что ряд флажков предлагает более удобный интерфейс. Однако, когда они используются, для свойства по умолчанию для нескольких option
может быть установлено значение true. Свойство selectedIndex узла select недопустимо, поэтому мы должны последовательно просмотреть каждую опцию, чтобы определить, соответствует ли выбранное свойство свойству defaultSelected.
Следующий код проверяет наличие изменений в любом окне выбора независимо от того, как определены параметры:
var skills = document.getElementById("skills"), c = false, def = 0, o, ol, opt; for (o = 0, ol = n.options.length; o < ol; o++) { opt = skills.options[o]; c = c || (opt.selected != opt.defaultSelected); if (opt.defaultSelected) def = o; } if (c && !skills.multiple) c = (def != skills.selectedIndex); if (c) alert("#skills has changed");
Вот как вы проверяете, изменился ли какой-либо элемент формы.
Но разве не было бы замечательно, если бы у нас была общая, многократно используемая функция JavaScript, которая могла бы обнаруживать изменения в любой форме, работала во всех браузерах и не требовала объемной библиотеки? Следите за SitePoint — он скоро появится!