This commit is contained in:
Ilya Kantor 2015-11-18 16:15:29 +03:00
parent 4bca225593
commit 547854a151
1655 changed files with 847 additions and 89231 deletions

View file

@ -1,21 +0,0 @@
Модальное окно делается путём добавления к документу `DIV`, полностью перекрывающего документ и имеющего больший `z-index`.
В результате все клики будут доставаться этому `DIV'у`:
Стиль:
```css
#cover-div {
position: fixed;
top: 0;
left: 0;
z-index: 9000;
width: 100%;
height: 100%;
background-color: gray;
opacity: 0.3;
}
```
Самой форме можно дать еще больший `z-index`, чтобы она была над `DIV'ом`. Мы не помещаем форму в контейнер, чтобы она не унаследовала полупрозрачность.

View file

@ -1,155 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#prompt-form {
display: inline-block;
padding: 5px 5px 5px 70px;
width: 200px;
border: 1px solid black;
background: white url(https://js.cx/clipart/prompt.png) no-repeat left 5px;
vertical-align: middle;
}
#prompt-form-container {
position: fixed;
top: 0;
left: 0;
z-index: 9999;
display: none;
width: 100%;
height: 100%;
text-align: center;
}
#prompt-form-container:before {
display: inline-block;
height: 100%;
content: '';
vertical-align: middle;
}
#cover-div {
position: fixed;
top: 0;
left: 0;
z-index: 9000;
width: 100%;
height: 100%;
background-color: gray;
opacity: 0.3;
}
#prompt-form input[name="text"] {
display: block;
margin: 5px;
width: 180px;
}
</style>
</head>
<body style="height:3000px">
<h1>Нажмите на кнопку ниже</h1>
<input type="button" value="Нажмите для показа формы ввода" id="show-button">
<div id="prompt-form-container">
<form id="prompt-form">
<div id="prompt-message"></div>
<input name="text" type="text">
<input type="submit" value="Ок">
<input type="button" name="cancel" value="Отмена">
</form>
</div>
<script>
// Показать полупрозрачный DIV, затеняющий всю страницу
// (а форма будет не в нем, а рядом с ним, чтобы не полупрозрачная)
function showCover() {
var coverDiv = document.createElement('div');
coverDiv.id = 'cover-div';
document.body.appendChild(coverDiv);
}
function hideCover() {
document.body.removeChild(document.getElementById('cover-div'));
}
function showPrompt(text, callback) {
showCover();
var form = document.getElementById('prompt-form');
var container = document.getElementById('prompt-form-container');
document.getElementById('prompt-message').innerHTML = text;
form.elements.text.value = '';
function complete(value) {
hideCover();
container.style.display = 'none';
document.onkeydown = null;
callback(value);
}
form.onsubmit = function() {
var value = form.elements.text.value;
if (value == '') return false; // игнорировать пустой submit
complete(value);
return false;
};
form.elements.cancel.onclick = function() {
complete(null);
};
document.onkeydown = function(e) {
if (e.keyCode == 27) { // escape
complete(null);
}
};
var lastElem = form.elements[form.elements.length - 1];
var firstElem = form.elements[0];
lastElem.onkeydown = function(e) {
if (e.keyCode == 9 && !e.shiftKey) {
firstElem.focus();
return false;
}
};
firstElem.onkeydown = function(e) {
if (e.keyCode == 9 && e.shiftKey) {
lastElem.focus();
return false;
}
};
container.style.display = 'block';
form.elements.text.focus();
}
document.getElementById('show-button').onclick = function() {
showPrompt("Введите что-нибудь<br>...умное :)", function(value) {
alert("Вы ввели: " + value);
});
};
</script>
</body>
</html>

View file

@ -1,65 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#prompt-form {
display: inline-block;
padding: 5px 5px 5px 70px;
width: 200px;
border: 1px solid black;
background: white url(https://js.cx/clipart/prompt.png) no-repeat left 5px;
vertical-align: middle;
}
#prompt-form-container {
position: fixed;
top: 0;
left: 0;
z-index: 9999;
width: 100%;
height: 100%;
text-align: center;
}
#prompt-form-container:before {
display: inline-block;
height: 100%;
content: '';
vertical-align: middle;
}
#prompt-form input[name="text"] {
display: block;
margin: 5px;
width: 180px;
}
</style>
</head>
<body>
<div id="prompt-form-container">
<form id="prompt-form">
<div id="prompt-message">Введите, пожалуйста...
<br>Что-то..</div>
<input name="text" type="text">
<input type="submit" value="Ок">
<input type="button" name="cancel" value="Отмена">
</form>
</div>
</body>
</html>

View file

@ -1,34 +0,0 @@
# Модальное диалоговое окно
[importance 5]
Создайте функцию `showPrompt(text, callback)`, которая выводит форму для ввода с сообщением `text` и кнопками `ОК/Отмена`.
<ul>
<li>При отправке формы (OK/ввод в текстовом поле) -- должна вызываться функция `callback` со значением поля.</li>
<li>При нажатии на `Отмена` или на клавишу [key Esc] -- должна вызываться функция `callback(null)`. Клавиша [key Esc] должна закрывать форму всегда, даже если поле для ввода сообщения не в фокусе.</li>
</ul>
Особенности реализации:
<ul>
<li>Форма должна показываться в центре окна (и оставаться в центре при изменении его размеров, а также при прокрутке окна!).</li>
<li>Текст может состоять из нескольких строк, возможен любой HTML</li>
<li>При показе формы остальные элементы страницы использовать нельзя, не работают другие кнопки и т.п, это окно -- *модальное*.</li>
<li>При показе формы -- сразу фокус на `INPUT` для ввода.</li>
<li>Нажатия [key Tab]/[key Shift+Tab] переключают в цикле только по полям формы, они не позволяют переключиться на другие элементы страницы.</li>
</ul>
Пример использования:
```js
showPrompt("Введите что-нибудь<br>... умное :)", function(value) {
alert( value );
});
```
Демо в ифрейме:
[iframe src="solution" height=160 border=1]
Исходный HTML/CSS для формы с готовым fixed-позиционированием - в песочнице.

View file

@ -1,118 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
td select,
td input {
width: 150px;
}
label {
display: block;
}
.error input,
.error textarea {
border: 1px solid red;
}
.error {
color: red;
}
</style>
</head>
<body>
<form>
<table>
<tr>
<td>От кого</td>
<td>
<input name="from" type="text">
</td>
</tr>
<tr>
<td>Ваш пароль</td>
<td>
<input name="password" type="password">
</td>
</tr>
<tr>
<td>Повторите пароль</td>
<td>
<input name="password2" type="password">
</td>
</tr>
<tr>
<td>Куда</td>
<td>
<select name="to">
<option></option>
<option value="1">Отдел снабжения</option>
<option value="2">Отдел разработки</option>
<option value="3">Директору</option>
</select>
</td>
</tr>
</table>
Сообщение:
<label>
<textarea name="message" style="display:block;width:400px;height:80px"></textarea>
</label>
<input type="button" onclick="validate(this.form)" value="Проверить">
</form>
<script>
function showError(container, errorMessage) {
container.className = 'error';
var msgElem = document.createElement('span');
msgElem.className = "error-message";
msgElem.innerHTML = errorMessage;
container.appendChild(msgElem);
}
function resetError(container) {
container.className = '';
if (container.lastChild.className == "error-message") {
container.removeChild(container.lastChild);
}
}
function validate(form) {
var elems = form.elements;
resetError(elems.from.parentNode);
if (!elems.from.value) {
showError(elems.from.parentNode, ' Укажите от кого.');
}
resetError(elems.password.parentNode);
if (!elems.password.value) {
showError(elems.password.parentNode, ' Укажите пароль.');
} else if (elems.password.value != elems.password2.value) {
showError(elems.password.parentNode, ' Пароли не совпадают.');
}
resetError(elems.to.parentNode);
if (!elems.to.value) {
showError(elems.to.parentNode, ' Укажите, куда.');
}
resetError(elems.message.parentNode);
if (!elems.message.value) {
showError(elems.message.parentNode, ' Отсутствует текст.');
}
}
</script>
</body>
</html>

View file

@ -1,74 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
td select,
td input {
width: 150px;
}
label {
display: block;
}
/* ваши стили */
</style>
</head>
<body>
<form>
<table>
<tr>
<td>От кого</td>
<td>
<input name="from" type="text">
</td>
</tr>
<tr>
<td>Ваш пароль</td>
<td>
<input name="password" type="password">
</td>
</tr>
<tr>
<td>Повторите пароль</td>
<td>
<input name="password2" type="password">
</td>
</tr>
<tr>
<td>Куда</td>
<td>
<select name="to">
<option></option>
<option value="1">Отдел снабжения</option>
<option value="2">Отдел разработки</option>
<option value="3">Директору</option>
</select>
</td>
</tr>
</table>
Сообщение:
<label>
<textarea name="message" style="display:block;width:400px;height:100px"></textarea>
</label>
<input type="button" onclick="validate(this.form)" value="Проверить">
</form>
<script>
function validate(form) {
/* ваш код */
}
/* ваш код */
</script>
</body>
</html>

View file

@ -1,17 +0,0 @@
# Валидация формы
[importance 3]
Напишите функцию `validate(form)`, которая проверяет содержимое формы по клику на кнопку "Проверить".
Ошибки:
<ol>
<li>Одно из полей не заполнено.</li>
<li>Пароли не совпадают.</li>
</ol>
Ошибка должна сопровождаться сообщением у поля. Например:
[iframe height=280 src="solution"]

View file

@ -1,65 +0,0 @@
# Формы: отправка, событие и метод submit
Событие `submit` возникает при отправке формы. Наиболее частое его применение -- это *валидация* (проверка) формы перед отправкой.
Метод `submit` позволяет инициировать отправку формы из JavaScript, без участия пользователя. Далее мы рассмотрим детали их использования.
[cut]
## Событие submit
Чтобы отправить форму на сервер, у посетителя есть два способа:
<ol>
<li>**Первый -- это нажать кнопку `<input type="submit">` или `<input type="image">`.**</li>
<li>**Второй -- нажать Enter, находясь на каком-нибудь поле.**</li>
</ol>
Какой бы способ ни выбрал посетитель -- будет сгенерировано событие `submit`. Обработчик в нём может проверить данные и, если они неверны, то вывести ошибку и сделать `event.preventDefault()` -- тогда форма не отправится на сервер.
Например, в таком HTML оба способа выведут `alert`, форма не будет отправлена:
```html
<!--+ autorun height=80 no-beautify -->
<form onsubmit="alert('submit!');return false">
Первый: Enter в текстовом поле <input type="text" value="Текст"><br>
Второй: Нажать на "Отправить": <input type="submit" value="Отправить">
</form>
```
Ожидаемое поведение:
<ol><li>Перейдите в текстовое поле и нажмите Enter, будет событие, но форма не отправится на сервер благодаря `return false` в обработчике.</li>
<li>То же самое произойдет при клике на `<input type="submit">`.</li>
</ol>
[smart header="Взаимосвязь событий `submit` и `click`"]
При отправке формы путём нажатия Enter на текстовом поле, на элементе `<input type="submit">` везде, кроме IE8-, генерируется событие `click`.
Это довольно забавно, учитывая что клика-то и не было.
```html
<!--+ autorun height=80 -->
<form onsubmit="alert('submit');return false">
<input type="text" size="30" value="При нажатии Enter будет click">
<input type="submit" value="Submit" *!*onclick="alert('click')"*/!*>
</form>
```
[/smart]
[warn header="В IE8- событие `submit` не всплывает"]
В IE8- событие `submit` не всплывает. Нужно вешать обработчик `submit` на сам элемент формы, без использования делегирования.
[/warn]
## Метод submit
Чтобы отправить форму на сервер из JavaScript -- нужно вызвать на элементе формы метод `form.submit()`.
При этом само событие `submit` не генерируется. Предполагается, что если программист вызывает метод `form.submit()`, то он выполнил все проверки.
Это используют, в частности, для искусственной генерации и отправки формы.