В этой главе мы рассмотрим элементы управления и научимся с помощью JavaScript обрабатывать данные, введенные пользователем.
Командная кнопка является наиболее часто используемым элементом управления. При нажатии кнопки мы можем выполнить какую-либо операцию. Кнопка вставляется с помощью тега <input>
или <button>
. При использовании тега <button>
текст на кнопке можно сделать цветным, имеется возможность отобразить значок, а также можно задать клавишу быстрого доступа. Пример создания кнопок:
<input type="button" value="Текст на кнопке">
<button type="button">Текст на кнопке</button>
В параметре type
указывается тип кнопки:
button
— обычная командная кнопка;reset
— кнопка, при нажатии которой вся форма очищается (элементы формы примут значения по умолчанию);submit
— кнопка, при нажатии которой происходит отправка данных формы.Кнопки поддерживают следующие основные свойства:
value
— текст, отображаемый на кнопке (для тега <input>
);disabled
— если задано значение true
, то кнопка является неактивной (отображается серым цветом);type
— тип кнопки.Методы:
blur()
— убирает фокус ввода;focus()
— устанавливает фокус ввода.События:
onblur
— наступает при потере фокуса ввода;onclick
— возникает при нажатии кнопки;onfocus
— происходит при получении фокуса ввода.Пример обработки нажатия кнопки приведен в листинге 8.1.
Листинг 8.1. Обработка нажатия кнопки
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' 'unsafe-inline'">
<title>Командная кнопка</title>
</head>
<body>
<input type="button" value="Кнопка 1" id="btn1">
<button type="button" id="btn2">Кнопка 2</button>
<button type="button" id="btn3">Неактивная кнопка</button>
<script>
let btn1 = document.getElementById('btn1');
btn1.addEventListener('click', () => {
console.log('Нажата кнопка 1');
});
let btn2 = document.getElementById('btn2');
btn2.addEventListener('click', () => {
console.log('Нажата кнопка 2');
});
document.getElementById('btn3').disabled = true;
</script>
</body>
</html>
Однострочные поля вставляются с помощью тега <input>
. Параметр type
может принимать следующие значения:
text
— обычное текстовое поле;password
— текстовое поле для ввода пароля (все введенные символы заменяются точками);search
— поле ввода подстроки для поиска;url
— текстовое поле для ввода URL Значение автоматически проверяется. Форма отправляется только в случае, если поле не заполнено или содержит корректное значение URL. Существование URL не проверяется. Если нужно исключить пустое значение, то следует дополнительно указать параметр required
;email
— текстовое поле для ввода E-mail. Значение автоматически проверяется. Форма отправляется только в случае, если поле не заполнено или содержит корректное значение E-mail. Существование E-mail не проверяется. Если нужно исключить пустое значение, то следует дополнительно указать параметр required
;tel
— текстовое поле для ввода телефона;date
— поле для ввода даты. Справа от поля выводится значок, с помощью которого можно отобразить календарь;time
— поле для ввода времени. Справа от поля выводится значок, с помощью которого можно отобразить возможные значения;datetime-local
— поле для ввода даты и времени. Справа от поля выводится значок, с помощью которого можно отобразить календарь;month
— поле для ввода месяца и года. Справа от поля выводится значок, с помощью которого можно отобразить возможные значения;week
— поле для ввода номера недели и года. Справа от поля выводится значок, с помощью которого можно отобразить возможные значения.С помощью параметра value
мы можем указать значение по умолчанию, а с помощью параметра placeholder
— текст подсказки:
<input type="text" value="Значение по умолчанию">
<input type="text" placeholder="Текст подсказки">
Если указан параметр autofocus
, то после загрузки поле получит фокус ввода:
<input type="text" autofocus>
Параметр required
указывает, что поле обязательно для заполнения:
<input type="text" required>
С помощью параметра pattern
мы можем ограничить вводимое значение шаблоном регулярного выражения:
<input type="tel" placeholder="+0 (000) 000-00-00" required
pattern="\+[1-9] \([0-9]{3}\) [0-9]{3}-[0-9]{2}-[0-9]{2}">
Поля имеют следующие основные свойства:
value
— значение элемента формы;defaultValue
— начальное значение, заданное параметром value
;disabled
— если задано значение true
, то поле является неактивным (отображается серым цветом);maxLength
— максимальное количество символов, которое может быть введено в поле;type
— тип элемента;readOnly
— если задано значение true
, текст в поле нельзя редактировать, если false
— можно.Методы:
blur()
— убирает фокус ввода с текущего элемента;focus()
— помещает фокус на текущий элемент;select()
— выделяет текст в поле.Поддерживаются следующие события:
onblur
— происходит при потере фокуса элементом формы;onchange
— наступает после изменения данных в поле и при переводе фокуса ввода на другой элемент либо при отправке данных формы. Наступает перед событием onblur
;onfocus
— возникает при получении фокуса ввода.Кроме перечисленных событий можно использовать стандартные события мыши и клавиатуры.
Поле для ввода многострочного текста, описываемое парным тегом <textarea>
, поддерживает те же свойства, методы и события, что и простое поле ввода, за исключением свойства maxLength
. Кроме того, поддерживается еще одно свойство:
wrap
— режим переноса слов. Может принимать следующие значения:off
— не переносить слова;physical
— слова переносятся как на экране, так и при передаче данных серверу;virtual
— слова переносятся только на экране, но не при передаче данных серверу.Для примера рассмотрим возможность добавления слов из текстового поля в поле для ввода многострочного текста (листинг 8.2). Добавить слово можно с помощью кнопки Добавить слово или с помощью клавиши <Enter>. Так как по умолчанию нажатие клавиши <Enter> приводит к отправке данных формы, то всплывание события прерывается. При нажатии кнопки Значение поля выводится текущее значение тега <textarea>
.
Листинг 8.2. Добавление слов из текстового поля в поле <textarea>
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' 'unsafe-inline'">
<title>Пример использования поля <TEXTAREA></title>
<script>
function frmSubmit() {
let v = document.getElementById('txt1').value;
console.log('Текущее значение: \n' + v);
return false;
}
function btnClick() {
let txt2 = document.getElementById('txt2');
let text = txt2.value;
if (text != '') {
document.getElementById('txt1').value += text + '\n';
txt2.value = '';
txt2.focus();
}
else {
console.log('Поле не заполнено!');
txt2.focus();
}
}
window.onload = function () {
document.getElementById('txt2').onkeypress = function(e) {
if (e.keyCode == 13) {
btnClick();
e.preventDefault();
}
}
}
</script>
</head>
<body>
<form action="#" id="frm" onsubmit="return frmSubmit()">
<div>
Слово:<br>
<input type="text" name="txt2" id="txt2"><br>
<textarea name="txt1" id="txt1" cols="15" rows="10"></textarea>
<br><input type="button" value="Добавить слово"
onclick="btnClick()"><br>
<input type="submit" value=" Значение поля ">
</div>
</form>
</body>
</html>
Поле для ввода числового значения реализуется с помощью тега <input>
, параметр type
которого имеет значение number
. Справа от поля Web-браузер отображает две кнопки с помощью которых можно увеличить или уменьшить значение на шаг, указанный в параметре step
. Значение автоматически проверяется. Форма отправляется только в случае, если поле не заполнено или содержит положительное или отрицательное число. Если нужно исключить пустое значение, то следует дополнительно указать параметр required
:
<input type="number" step="5" required>
<input type="number" step="0.5" required>
Если в параметре type
указать значение range
, то отобразится ползунок, с помощью которого можно выбрать числовое значение из диапазона. Элемент не содержит маркеров и меток, поэтому выставить значение можно только примерно. Для информирования пользователя о точном текущем значении нужно использовать дополнительные скрипты. Минимальное значение задается параметром min
, максимальное — параметром max
, текущее — параметром value
, а шаг — параметром step
:
<input type="range" min="0" max="100" value="10" step="2">
Элементы number
и range
поддерживают следующие основные свойства:
value
— текущее значение;min
— минимальное значение;max
— максимальное значение;step
— шаг.Тег <select>
создает список с возможными значениями:
<select>
<option>Элемент1</option>
<option>Элемент2</option>
</select>
Основные свойства объекта списка:
disabled
— если задано значение true
, то список является неактивным (отображается серым цветом);length
— количество пунктов в списке (доступно и для записи);multiple
— true
, если из списка можно выбрать сразу несколько элементов одновременно;options
— ссылка на коллекцию пунктов в списке;selectedOptions
— ссылка на коллекцию выбранных пунктов списка;selectedIndex
— номер выбранного пункта (нумерация начинается с нуля);size
— число одновременно видимых элементов списка;type
— тип элемента формы (select-multiple
или select-one
);value
— значение пункта, выбранного в списке.Свойства пункта списка:
defaultSelected
— пункт списка, выбранный изначально;index
— номер пункта в списке;selected
— true
, если пункт выбран в списке;disabled
— если задано значение true
, то пункт списка является неактивным (отображается серым цветом);text
— текст пункта списка;value
— значение пункта, выбранного в списке.Методы:
blur()
— убирает фокус ввода с текущего элемента формы;focus()
— помещает фокус на текущий элемент формы.События:
onblur
— наступает при потере фокуса элементом формы;onchange
— происходит после выбора нового пункта списка;onfocus
— наступает при получении фокуса ввода элементом формы.Рассмотрим пример работы со списками. Документ, приведенный в листинге 8.3, демонстрирует следующие возможности:
Листинг 8.3. Обработка списков
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' 'unsafe-inline'">
<title>Пример обработки списков</title>
</head>
<body>
<form action="#" id="frm">
<!-- Добавление пункта в список -->
<script>
function addOption() {
let txt1 = document.getElementById('txt1');
let txt2 = document.getElementById('txt2');
let select1 = document.getElementById('select1');
if (txt1.value != '' && txt2.value != '') {
let i = select1.length++;
select1.options[i].text = txt1.value;
select1.options[i].value = txt2.value;
txt1.value = '';
txt2.value = '';
txt1.focus();
}
else {
console.log('Поле не заполнено!');
txt1.focus();
}
}
function press1(e) {
if (e.keyCode == 13) {
document.getElementById('txt2').focus();
e.preventDefault();
}
}
function press2(e) {
if (e.keyCode == 13) {
addOption();
e.preventDefault();
}
}
</script>
<div>
<b>Добавление пункта в список:</b><br><br>
Текст пункта:<br>
<input type="text" id="txt1" onkeypress="press1(event)">
<br>Значение пункта:<br>
<input type="text" id="txt2" onkeypress="press2(event)">
<br><select id="select1">
</select><br>
<input type="button" value="Добавить"
onclick="addOption()"><br><br>
<!-- Список со множественным выбором -->
<script>
function multi() {
let msg = '';
let select2 = document.getElementById('select2');
if (select2.selectedOptions) {
let obj = select2.selectedOptions;
let count = obj.length;
for (let i = 0; i < count; i++) {
msg += obj[i].value + ' - ';
msg += obj[i].text + '\n';
}
}
else {
let count = select2.length;
for (let i = 0; i < count; i++) {
if (select2.options[i].selected) {
msg += select2.options[i].value + ' - ';
msg += select2.options[i].text + '\n';
}
}
}
console.log(msg);
}
</script>
<b>Список со множественным выбором:</b><br><br>
<select id="select2" size="5" multiple>
<option value="1" selected>Элемент1</option>
<option value="2">Элемент2</option>
<option value="3">Элемент3</option>
<option value="4">Элемент4</option>
<option value="5">Элемент5</option>
<option value="6">Элемент6</option>
</select><br>
<input type="button" value="Значения списка"
onclick="multi()"><br><br>
<!-- Взаимосвязанные списки -->
<script>
let arr = [];
arr[1] = ['Тема1 Элемент1', 'Тема1 Элемент2'];
arr[2] = ['Тема2 Элемент1', 'Тема2 Элемент2',
'Тема2 Элемент3'];
let value1 = [];
value1[1] = ['1', '2'];
value1[2] = ['3', '4', '5'];
function change1() {
let index = document.getElementById('select3').value;
let select4 = document.getElementById('select4');
let count = arr[index].length;
select4.length = count;
for (i = 0; i < count; i++) {
select4.options[i].value = value1[index][i];
select4.options[i].text = arr[index][i];
}
}
function change2() {
let sel = document.getElementById('select4');
let msg = 'Значение: ' +
sel.options[sel.selectedIndex].value;
msg += '\nТекст: '
+ sel.options[sel.selectedIndex].text;
console.log(msg);
}
</script>
<b>Взаимосвязанные списки:</b><br><br>
<select name="select3" id="select3" size="5"
onchange="change1()">
<option value="1">Тема1</option>
<option value="2">Тема2</option>
</select><br>
<select name="select4" id="select4" onchange="change2()">
<option value="1" selected>Тема1 Элемент1</option>
<option value="2">Тема1 Элемент2</option>
</select>
</div>
</form>
</body>
</html>
Флажок и переключатели вставляются с помощью тега <input>
, параметр type
которого может принимать следующие значения:
checkbox
— поле для установки флажка;radio
— элемент-переключатель.Флажки и переключатели имеют следующие свойства:
value
— значение текущего элемента формы;checked
— true
, если флажок или переключатель находится во включенном состоянии;defaultChecked
— флажок или переключатель установлен по умолчанию. Содержит true
или false
;disabled
— если задано значение true
, то элемент является неактивным (отображается серым цветом);indeterminate
— если true
, то флажок находится в неопределенном состоянии, и false
— в противном случае;type
— тип элемента.Методы:
blur()
— убирает фокус ввода с текущего элемента формы;focus()
— помещает фокус на текущий элемент формы.События:
onblur
— наступает при потере фокуса элементом формы;onclick
— возникает при выборе элемента;onfocus
— происходит при получении фокуса ввода элементом формы.Чтобы найти выбранный элемент-переключатель в группе, необходимо перебрать все переключатели в цикле. Получить значение выбранного переключателя можно указав внутри квадратных скобок индекс элемента в группе. Рассмотрим это на примере (листинг 8.4).
Листинг 8.4. Обработка флажков и переключателей
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' 'unsafe-inline'">
<title>Пример использования флажков и переключателей</title>
<script>
function btnClick() {
let msg = '';
if (document.getElementById('check1').checked) {
msg = 'Флажок установлен\n';
msg += 'Значение: ' +
document.getElementById('check1').value + '\n';
}
else {
msg = 'Флажок снят\n';
}
let value1 = '';
let count = document.frm.radio1.length;
for (i = 0; i < count; i++) {
if (document.frm.radio1[i].checked) {
value1 = document.frm.radio1[i].value;
break;
}
}
if (value1 == 'male') {
msg += 'Пол: Мужской\n';
}
else {
msg += 'Пол: Женский\n';
}
console.log(msg);
}
</script>
</head>
<body>
<form action="#" name="frm" id="frm">
<div>
<input type="checkbox" name="check1" id="check1"
value="yes" checked>
Текст<br><br>
Укажите ваш пол:<br>
<input type="radio" name="radio1" id="radio1"
value="male" checked>Мужской
<input type="radio" name="radio1" id="radio2"
value="female">Женский
<br><br>
<input type="button" value="Вывести значения"
onclick="btnClick()">
</div>
</form>
</body>
</html>
Поле для выбора файла вставляется с помощью тега <input>
, параметр type
которого имеет значение file
:
<input type="file">
Поле для выбора файла поддерживает следующие параметры:
multiple
— если параметр указан, то можно выбрать сразу несколько файлов:<input type="file" multiple>
accept
— задает поддерживаемые MIME-типы или расширения файлов (значения перечисляются через запятую):<input type="file" accept="image/jpeg,image/png,image/gif">
<input type="file" accept="image/*">
<input type="file" accept=".gif,.jpg,.jpeg">
Все выбранные файлы доступны через коллекцию files
. Если файлы выбраны, то свойство length
будет иметь значение больше 0
. Получить путь к выбранному файлу позволяет свойство path
(листинг 8.5).
Листинг 8.5. Поле для выбора файла
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' 'unsafe-inline'">
<title>Поле для выбора файла</title>
</head>
<body>
<input type="file" id="file1">
<button type="button" id="btn1">Проверить</button>
<script>
document.getElementById('btn1').addEventListener('click', () => {
let file1 = document.getElementById('file1');
if (file1.files.length === 0) {
console.log('Файл не выбран');
}
else {
console.log(file1.files[0].path);
}
});
</script>
</body>
</html>
Элемент для выбора цвета реализуется с помощью тега <input>
, параметр type
которого имеет значение color
. При щелчке на элементе отображается диалоговое окно, в котором можно выбрать цвет или ввести его значение вручную. Текущее значение задается с помощью параметра value
в формате #RRGGBB
:
<input type="color" value="#000000" id="color1">
Получить выбранное значение позволяет свойство value
:
let color1 = document.getElementById('color1');
console.log(color1.value);
Парный тег <progress>
, позволяет в графической форме отобразить текущее состояние хода выполнения процесса. Тег имеет следующие параметры:
value
— текущее значение;max
— максимальное значение.Пример:
<progress max="100" value="50"></progress>
Все элементы управления можно поместить внутри формы. В этом случае внутри обработчика отправки формы (событие onsubmit
) можно выполнить автоматическую проверку данных, внесенных пользователем в элементы управления. Для этого к элементам управления добавляем параметр required
и правильно выбираем сам элемент, чтобы он соответствовал нашим требованиям. Например, для ввода E-mail выбираем элемент с типом email
, а не text
.
Выполнить проверку на корректность введенных данных сразу всех элементов позволяет метод checkValidity()
объекта формы (листинг 8.6). Он возвращает true
, если во все элементы управления формы занесены корректные данные, и false
— в противном случае.
Листинг 8.6. Проверка корректности введенных данных
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' 'unsafe-inline'">
<title>Проверка корректности введенных данных</title>
</head>
<body>
<form action="#" id="frm">
<input type="email" name="email" required>
<input type="submit" value="Проверить">
</form>
<script>
let frm = document.getElementById('frm');
frm.addEventListener('submit', (e) => {
e.preventDefault();
if ( !frm.checkValidity() ) {
console.log('Введите корректные данные!');
}
else {
console.log('Данные введены правильно');
}
});
</script>
</body>
</html>
Элементы управления поддерживают следующие свойства:
validationMessage
— возвращает текст сообщения об ошибке;validity
— сведения об ошибках. Содержит объект класса ValidityState
, который поддерживает следующие свойства:badInput
— true
, если введенное значение неполное;patternMismatch
— true
, если введенное значение не совпадает с заданным шаблоном регулярного выражения, из параметра pattern
);rangeOverflow
— true
, если введенное число больше указанного максимального значения;rangeUnderflow
— true
, если введенное число меньше указанного минимального значения;stepMismatch
— true
, если введенное число не укладывается в заданный интервал;tooLong
— true
, если введенная строка слишком длинная;typeMismatch
— true
, если введенное значение не соответствует требуемому типу;valueMissing
— true
, если обязательное поле пустое;customError
— true
, если было задано иное сообщение об ошибке ввода данных;valid
— true
, если введенное значение полностью корректно (и все перечисленные ранее свойства хранят значение false
);willValidate
— содержит true
, если значение элемента будет проверяться на корректность.Пример проверки корректности ввода значения для конкретного элемента управления приведен в листинге 8.7.
Листинг 8.7. Свойство validity
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' 'unsafe-inline'">
<title>Свойство validity</title>
</head>
<body>
<input type="email" name="email" id="email" required>
<input type="button" id="btn1" value="Проверить">
<script>
let btn1 = document.getElementById('btn1');
btn1.addEventListener('click', (e) => {
let email = document.getElementById('email');
if (!email.validity.valid) {
console.log('Введите корректные данные!');
console.log(email.validationMessage);
}
else {
console.log('Данные введены правильно');
}
});
</script>
</body>
</html>