Бібліотека, що полегшує розробку форм на сайтах (v3)

Привіт, Хабр!
Як-то, рік назад я писав про свою невеликий бібліотеці, яка полегшує розробку форм на сайтах. Нещодавно я випустив 3-ю версію, яка, по-суті, була переписана з нуля, щоб стати правильніше і зручніше. Але у своїй статті я не буду повторювати README і ДЕМО, а краще покажу на практиці, яким чином вона допомагає писати менше коду.

Але перш хотілося б дати трохи інформації про нової версії. В ній, я позбувся залежності malsup jquery.form для відправлення файлів, і один великий репозитарій я розділив на кілька дрібних самостійних репозитаріїв, зберігши, при цьому, загальну збірку "все-в-одному":

Додаткові події форм

У другій версії бібліотеки я зіткнувся з проблемою необхідності дотримання певного порядку підключення скриптів. Наприклад, раніше не можна було підключати даний скрипт перед стандартним скриптом валідації Yii2, справа в тому, що на подію submit навішуються всі скрипти, які так чи інакше повинні обробити відправку, зокрема провести валідацію, і немає ніякої гарантії, що хтось це подія не перерве викликом
preventDefault()
. Тому, у разі невірного порядку підключення, спочатку відбувалася блокування форми, а потім валідація, і, якщо були помилки валідації, повторно надіслати форму було вже не можна. form-extra-events вирішує цю проблему, він надає кілька нових типів подій форми, одне з яких гарантує те, що форма відправляється, і цей процес вже не можна перервати. Крім того, генеруються події початку та завершення передавання форми, що використовується у всіх інших можливостях бібліотеки.

Сайт-прототип

Для демонстрації корисності бібліотеки, я накидав прототип типового інтернет-магазину на Bootstrap:
http://paulzi.ru/paulzi-form-site/
З скриптів використовуємо тільки jQuery, bootstrap і paulzi-form.all.js. В цьому прототипі ми не використовуємо ні строчки JS-коду, написаного спеціально для сайту-прототипу.

Html5 form-атрибути

У чому може знадобитися HTML5 form-атрибути? Наприклад, в кошику передбачається кілька дій над відібраними товарами — додати в обране, відправити на Email, скачати. Звичайно, можна було б зробити єдиний action, а в параметрах передавати, що конкретно потрібно зробити. Але це негарно, т. к. породжує використання
switch($action)
, замість того, щоб відразу направити на конкретний action (наприклад, в Yii2). А якщо ви відкриєте модальне вікно, то побачите, що кнопку відправки довелося зробити поза самої форми, тим не менш, вона продовжує функціонувати, так як їй був вказаний атрибут
form
. А найголовніше, дані атрибути сильно виручають в ситуаціях, коли у великій формі потрібно зробити маленьку форму, що стандарт HTML забороняє.

Не відправляти порожні поля

Тепер, звернемо увагу на фільтр каталозі. Якщо відзначити галочкою «Intel Core i5 та відправити цю форму, навіть якщо інші поля не заповнені, ми все одно отримаємо довгу простирадло з параметрів після переходу:
?proce_from=&proce_to=&tdp_from=&tdp_from=&line[]=i5

Використовуючи бібліотеку, якщо додати до форми атрибут
data-submit-empty="false"
незаповнені поля не будуть відправлятися, і в результаті вийде більше людині зрозумілий URL:
?line[]=i5


Блокування повторної відправки

Розглянемо форму замовлення зворотного дзвінка. Якщо ви зробите подвійне клацання по кнопці відправки форми, форма у вас відправиться двічі, і вам прийде два листи. Це неправильно, тому скрипт за замовчуванням блокує можливість повторної відправки форми, до тих пір, поки запит не виконається. Приклад коректної роботи можна побачити в формі «Написати нам». Регулюється це поведінка шляхом установки атрибута
data-lock="false"


Індикація стану відправки

Іноді, процес відправки форми може займати тривалий час (відправлення файлу, процессороемкий обробник, повільний інтернет), і якщо ніяк не відобразити, що форма відправляється, користувач рано чи пізно подумає, що він не натиснув кнопку, або щось зависло, і натисне кнопку повторно. Приклад такої форми — форму «Написати нам». В бібліотеці передбачено кілька варіантів, в прототипі я використовував атрибути
data-loading-text
та
data-loading-icon
, які змінюють текст кнопки і додають іконку. Також до форми і кнопці додаються класи
form-loading
та
btn-loading
, це дозволяє застилизовать стан через CSS.

AJAX-відправка форми

Ну і найголовніше, це можливість відправки форми через AJAX. Дійсно, у нас в прототипі є дві форми модальних вікнах, логічно при натисканні на кнопку відправки здійснювати переходи між сторінками, а просто закрити модальний і вивести повідомлення про успіх. І тут все дуже легко — додаємо атрибут
data-via="ajax"
, і вуаля, форма відправляється через AJAX. І мало того, ті, хто хоч раз займався передачею через AJAX файлів знає, що зробити це не так просто, оскільки підтримка відправки файлів з'явилося тільки починаючи з XMLHttpRequrest 2. Для цього часто підключають сторонні бібліотеки, які часто вимагають написання на серверної частини особливих обробників, зберігати файли в тимчасовій папці, а потім при відправленні форми в окремому запиті їх звідти забирати. У нашому ж випадку, про це практично не треба замислюватися — все йде так, як якщо б форма відправлялася стандартним способом. При необхідності можна легко вивести відсоток відправлених даних, подцепившись на подію
uploadprogress
.

Обробка AJAX-відповідей

Подивимося на приклад складніше — кнопка додавання в корзину на сторінці каталогу. При натисканні на неї треба не просто виконати запит і вивести повідомлення — потрібно оновити короткий список вмісту корзини при наведенні і оновити лічильник кількості товарів у ній. Цей момент теж враховано, і я постарався зробити максимально гнучкий обробник AJAX-відповідей. Розглянемо відповідь, яка спадає при натисканні на «В кошик» в прототипі:
відповідь на запит
<span class="badge" data-insert-context="document" data-insert-to=".cart-block .badge" data-insert mode="replaceWith">43</span>
<div class="alert alert-success alert-dismissible" role="alert" data-insert-context="document" data-insert-to=".alert-fixed">
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">&times;</span></button>
Товар додано в кошик!
</div>
<div class="cart-block-hover" data-insert-context="document" data-insert-to=".cart-block-hover" data-insert mode="replaceWith">
<div class="row">
<div class="col-xs-6 text-left">AMD K6</div>
<div class="col-xs-6">10 шт.</div>
</div>
<div class="row">
<div class="col-xs-6 text-left">Intel Celeron</div>
<div class="col-xs-6">12 шт.</div>
</div>
<div class="row">
<div class="col-xs-6 text-left">Intel Core i7</div>
<div class="col-xs-6">1 шт.</div>
</div>
<div class="row cart-block-total">
<div class="col-xs-6 text-left">Загальна:</div>
<div class="col-xs-6"><span class="price"><span>117 000</span> ₽</span></div>
</div>
</div>

Як бачите, відповідь складається з трьох елементів html з атрибутами
data-insert-to
,
data-insert-context
,
data-insert mode
. Ці атрибути визначають як і в яке місце вставити кожен елемент, наприклад, для першого
span.badge
data-insert-context="document" data-insert-to=".cart-block .badge" data-insert mode="replaceWith"
означає, що даним елементом потрібно замінити елемент
.cart-block .badge
і зона пошуку даними селектором — весь документ. Все це дозволяє провести описані вище дії без єдиної рядки коду.

Сценарії

Повернемося на сторінку кошика. Як вже було розглянуто вище, на неї є декілька кнопок, які передбачають різні дії. Наприклад, при натисканні на "оформити" логічно відправити форму стандартним механізмом, після чого здійснити редирект на сторінку з інформацією про замовлення. А ось при натисканні на "У вибране", навпаки, краще не йти зі сторінки, а просто відправити форму через AJAX і вивести повідомлення про успіх або помилку. Для цього реалізовані сценарії — для будь-якої кнопки можна вказати
data-via
атрибут, який вкаже як відправляти форму при натисканні на неї.

Налаштування

Якщо вам щось не подобається, або виникають якісь конфлікти, в бібліотеці можна багато чого змінити через налаштування. Наприклад, чи потрібно блокувати повторну відправку всіх форм за замовчуванням. Всі назви атрибутів також можна поміняти.

Висновок

У підсумку, підключивши бібліотеку розміром 10 кб, ви отримуєте найголовніше — потрібно менше писати код для різних дрібних форм (а то і зовсім не писати), а в доважок отримуєте кілька приємних можливостей, такі як додаткові події форм, iframe-транспорт, AJAX-відправка файлів і ін
Перейти на сторінку проекту в Github»
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.