Опубликован: 28.02.2016 | Уровень: для всех | Доступ: платный
Лекция 7:

Работа с формами

< Лекция 6 || Лекция 7 || Лекция 8 >

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

Для начала, стоит напомнить события с которыми чаще всего придётся работать:

change — изменение значения элемента

submit — отправка формы

В каких же случаях они нам помогут? Да всё просто – отслеживание change позволяет обрабатывать такие события как изменение selectbox'а, или radiobutton'а, что потребуется для динамического изменения формы. И самый простой пример тому – это на странице регистрации выбор страны, затем по выбранной стране должен быть подгружен список регионов, по региону – список городов и так далее. Отслеживание submit потребуется для проверки правильности заполнения формы, а так же для отправки формы посредством AJAX. Форму возьмём попроще:

<form action="/save/">
<input type="text" name="name" value="Ivan"/> <select name="role">
<option>User</option> <option>Admin</option>
</select>
<input type="submit"/> </form>

А примеры будут идти в обратном порядке, вот отправка формы AJAX'ом по ссылке из "action":

$('form').submit(function(){
// чуть позже расскажу подробнее о AJAX
$.post(
$(this).attr('action'), // ссылка куда отправляем данные
$(this).serialize() // данные формы
);
// отключаем действие по умолчанию
return false;
});

Вот и первый метод – "serialize()" – он в ответе за "сбор" данных с формы в удобном для передачи данных формате:

name=Ivan&role=Admin

Так же есть метод "serializeArray()" – он собранные данные представляет в виде объекта:

[
{
name:"name",
value:"Ivan"
},
{
name:"role",
value:"Admin"
},
]

Теперь стоит добавить в данный код немного проверки данных:

$('form').submit(function(){
if ($(this).find('input[name=name]').val() == '') {
alert('Введите имя пользователя');
return false;
}
// кусок кода с отправкой
// ...
});

Вот еще один метод, который нам будет частенько нужен:

val() – получение значения первого элемента формы из выборки

val(value) – установка значение всем элементам формы из выборки

Данный метод отлично работает практически со всеми элементами формы, вот только с radiobutton'ами установить значение таким образом не получится, тут потребуется небольшой workaround:

$('input[type=radio][name=choose][value=2]').prop('checked', true)

Можно конечно же использовать и метод "click()" дабы эмулировать выбор необходимо пункта, но это вызовет все обработчики события "click", что не желательно

С checbox'ами чуть-чуть попроще:

$('input[name=check] ').prop('checked', true)

Проверяем "чекнутость" простым скриптом:

$('input[name=check] ').prop('checked')
// или чуть более наглядным способом
$('input[name=check] ').is(':checked')

Проверять и отправлять форму AJAX'ом теперь умеем, теперь осталось решить вопрос с динамическим изменением формы, и для этого у нас уже есть все необходимые знания, вот, к примеру, добавление выпадающего списка:

$('form').append('<select name="some"></select>');

А если потребуется изменить список? Есть на все случаи жизни:

// возьмём список заранее, поберегу чернила
var $select = $('form select[name=Role]');
// добавить новый элемент в выпадающий список
$select.append('<option>Manager</option>');
// выбрать необходимый элемент
$select.val('Value 1');
// или по порядковому номеру, начиная с 0
$select.find('option:eq(2)').prop('selected', true);
// очищаем список
$select.remove('option');
// преобразуем в multiple
// не забываем, что имя такого селекта, должно быть с [], т.е.
// myselect[], иначе сервер получит, лишь одно значение
$('select').attr('size',
$('select option').length

Хорошо, работать с формой теперь можем, осталось прикрутить более вменяемый вывод ошибок (да-да, за "alert()" да по рукам):

if ($(this).find('input[name=user]').val() == '') {
$(this).find('input[name=user]')
.before('<div class="error">Введите имя</div>');
return false;
}

При повторной отправки формы не забудьте убрать сообщения оставшиеся от предыдущей проверки:

$(this).find('.error').remove()

Теперь можно объединить кусочки кода и получить следующий вариант:

$('form').submit(function(){
// чистим ошибки
$(this).find('.error').remove();
// проверяем поля формы
if ($(this).find('input[type=name]').val() == '') {
$(this).find('input[name=user]')
.before('<div class="error">Введите имя</div>');
return false;
}
// всё хорошо – отправляем запрос на сервер
$.post(
$(this).attr('action'), // ссылка куда отправляем данные
$(this).serialize() // данные формы
);
return false;
});

Теперь стоит вернуться к списку событий формы, и перечислить недостающие:

focus — фокус на элементе, для работы с данным событием так же есть "shorthand" метод "focus()"; может потребоваться, если надо вывести подсказку к элементу формы при наведении

blur — фокус ушёл с элемента + метод "blur()", для работы с ним; пригодится при валидации формы по мере заполнения полей

select — выбор текста в "textarea" и "input[type=text]" + метод "select()"; если соберётесь разрабатывать свой WYSIWYG, то познакомитесь очень плотно

submit — отправка формы + метод "submit()"; будете использовать частенько

Примеры работы данных методов:

<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Работа с формой</title>
    <link rel="profile" href="http://gmpg.org/xfn/11"/>
    <link rel="shortcut icon" href="http://anton.shevchuk.name/favicon.ico"/>
    <link rel="stylesheet" href="css/styles.css"/>
    <script type="text/javascript" src="js/jquery.js"></script>
    <script type="text/javascript" src="js/code.js"></script>
    <script type="text/javascript">
        $(function(){
            $('form').submit(function(){
                $(this).find('.error').remove();
                if ($(this).find('[name=text]').val() == '') {
                    $(this).find('[name=text]').before('<div class="error">Введите имя</div>');
                    return false;
                }
                out($(this).serialize()+'\n'+$(this).serializeArray());
                return false;
            })
        });
    </script>
    <style>
        form {
            padding: 10px;
        }
    </style>
</head>
<body>
    <div id="content" class="wrapper box">
        <menu label="Try...">
            <a href="height.html" title="go prev" class="button alignleft" rel="prev">← Prev </a>
            <a href="index.html" title="back to Index" class="button alignleft" rel="index">Index §</a>
            <a href="#" title="reload" class="button alignleft" onclick="window.location.reload();return false">Reload ¤</a>
            <hr/>
            <h3>Text input</h3>
            <pre><code contenteditable="true">$(<span>'input[type=text]'</span>).val(<span>'new text'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre data-out="1"><code>$(<span>'input[type=text]'</span>).val()</code></pre>
            <button type="button" class="code">Run Code</button>

            <h3>Text area</h3>
            <pre><code contenteditable="true">$(<span>'textarea'</span>).val('Some text')</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre data-out="1"><code>$(<span>'textarea'</span>).val()</code></pre>
            <button type="button" class="code">Run Code</button>
            <h3>Selectbox</h3>
            <pre><code contenteditable="true">$(<span>'select'</span>).val('Option 2')</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre data-out="1"><code>$(<span>'select'</span>).val()</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>$(<span>'select option:eq(2)'</span>).prop(<span>'selected'</span>, true)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>$(<span>'select option:eq(2)'</span>).prop(<span>'selected'</span>, false)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code contenteditable="true">$(<span>'select'</span>).append(<span>'<option>New Option</option>'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>$(<span>'select'</span>).attr(<span>'size'</span>,
    $(<span>'select option'</span>).length
)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>$(<span>'select option'</span>).remove()</code></pre>
            <button type="button" class="code">Run Code</button>

            <h3>Checboxes</h3>
            <pre><code>$(<span>'input[type=checkbox]'</span>).prop(<span>'checked'</span>, true)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre data-out="1"><code>$(<span>'input[type=checkbox]'</span>).is(<span>':checked'</span>)</code></pre>
            <button type="button" class="code">Run Code</button>
            <h3>Radiobuttons</h3>
            <pre><code>$(<span>'input[type=radio][name=choose][value=2]'</span>)
    .prop(<span>'checked'</span>, true)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre><code>$(<span>'input[type=radio][name=choose][value=2]'</span>)
    .prop(<span>'checked'</span>, false)</code></pre>
            <button type="button" class="code">Run Code</button>
            <pre data-out="1"><code>$(<span>'input[type=radio][name=choose]:checked'</span>).val()</code></pre>
            <button type="button" class="code">Run Code</button>
        </menu>
        <header>
            <h1>Работа с формой</h1>
            <h2>Попробуйте изменить данные, и получить данные</h2>
        </header>
        <div id="output">
            <h3>Output</h3>
            <pre></pre>
        </div>
        <article>
			<form action="">
				<fieldset>
					<input type="text" name="text"/>
					<textarea name="editor" cols="64" rows="16">Lorem ipsum dolor sit amet, consectetur adipiscing lit. Phasellus rutrum,
lectus eu varius consectetur, libero velit hendrerit augue, ut posuere enim neque
in libero. Donec eget sagittis nibh. Suspendisse sed tincidunt urna. Cras quis
euismod neque. Maecenas auctor ultricies posuere. Pellentesque luctus pulvinar dui
eget semper. Donec sodales odio eu sapien varius luctus. Donec dictum feugiat diam
at malesuada. Sed nec massa in augue condimentum faucibus quis ut diam. Quisque
nisl sem, semper nec vulputate vel, mattis sit amet justo. Aliquam purus felis,
tempor at scelerisque quis, tincidunt in neque. Etiam ut risus diam. Pellentesque
fermentum risus id elit feugiat cursus. Ut fringilla dictum diam, sed iaculis
lorem pulvinar ut. Cras vel elit id velit commodo viverra sit amet vel orci.</textarea>

					<select name="select">
					  <option>Option 1</option>
					  <option>Option 2</option>
					  <option>Option 3</option>
					</select>
					<hr/>
					<label><input type="checkbox" name="check" value="1"/> checkbox</label><br/>
					<hr/>
					<label><input type="radio" name="choose" value="1"/> choose 1</label><br/>
					<label><input type="radio" name="choose" value="2"/> choose 2</label><br/>
					<label><input type="radio" name="choose" value="3"/> choose 3</label><br/>
					<hr/>
					<input type="submit" name="submit" class="button"/>

				</fieldset>
			</form>
        </article>
        <footer>
            ©copyright 2014 Anton Shevchuk — <a href="http://anton.shevchuk.name/jquery-book/">jQuery Book</a>
        </footer>
        <script type="text/javascript">
            var _gaq = _gaq || [];
            _gaq.push(['_setAccount', 'UA-1669896-2']);
            _gaq.push(['_trackPageview']);
            (function() {
             var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
             ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
             var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
            })();
         </script>
	</div>
</body>
</html>

Вот так мы и расправились с "ужасными" формами, возможно я ещё приведу несколько примеров из реальной жизни, но это будет уже в последующих версиях данного учебника :)

< Лекция 6 || Лекция 7 || Лекция 8 >
Наталья Маркова
Наталья Маркова
Ярослав Гаевой
Ярослав Гаевой

10 марта 2016 c 20:13 до 22:39 я сдавал экзамен. Однако, за два месяца статус не изменился: "Задание не проверено"

Когда ожидать проверки?

Руслан Жанбосынов
Руслан Жанбосынов
Россия
Дмитрий Молокоедов
Дмитрий Молокоедов
Россия, Новосибирск, НГПУ, 2009