JavaScript Notes
Описание
В системе используется Twitter Bootstrap, который позволяет достаточно быстро разрабатывать прототипы интерфейсов, идеально подходит для интерфейсов панели администратора.
С большинством простых задач идеально справляется jQuery.
Так же в системе используется RequireJS для организации AMD.
На данный момент, пакетный менеджер для JS зависимостей не используется, но в конфигурации composer.json указаны ссылки на дистрибутивы используемых библиотек, и они устанавливаются автоматически при вызове composer create-project bluzphp/skeleton, при вызове composer install или composer update все библиотеки будут лишь скачаны в папку vendor/public.
Настройки
Настройки RequireJS находятся в файле public/js/config.js
Использование
В довесок к Twiter Boostrap и RequireJS в системе есть еще несколько полезных вещей, о которых стоит помнить.
Confirm dialog
Элемент с data-confirm при клике по нему запросит подтверждение действия, в качестве текста будет использоваться значение data-confirm либо сообщение по умолчанию Are you sure?:
<a href="/cache/clean" data-confirm="Are you want clean the cache?">Clean cache!</a>
AJAX links
Ссылка с атрибутом data-ajax будет стучаться по указанному URL посредством XMLHttpRequest:
<a data-ajax href="/ping">Click Me!</a>
Так же существуют следующие возможности:
- добавить данные для передачи на заданный URL используя
dataатрибуты (т.е.data-id="2"эквивалентно?id=2) - указать метод доставки, используя атрибут
data-ajax-method, по умолчанию - POST - указать тип ожидаемых данных -
data-ajax-type, по умолчанию - JSON - совместить с диалогом
data-confirm
События:
-
success.ajax.bluz- при удачном завершении AJAX запроса -
error.ajax.bluz- при ошибке в AJAX запросе
<a id="ping" data-ajax data-confirm href="/ping">Click Me!</a> <script> $('#ping') .on('success.ajax.bluz', function() { console.log("OK") }) .on('error.ajax.bluz', function() { console.log("KO") }); </script>
AJAX form
Форма с атрибутом data-ajax будет отправлена посредством XMLHttpRequest по указанному в action URL:
<form class="ajax" action="/save/" method="post"> ... </form>
Опции:
- указать метод доставки используя атрибут
method, по умолчанию - GET - указать тип ожидаемых данных -
data-ajax-type, по умолчанию - JSON
События:
-
success.ajax.bluz- при удачном завершении AJAX запроса -
error.ajax.bluz- при ошибке в AJAX запросе -
success.form.bluz- при удачной отправки формы -
error.form.bluz- при ошибке в отправке формы (вернулся ответ в котором естьerrors), это возможно при проверке данных
AJAX load
Клик по ссылке или кнопке с атрибутом data-ajax-load подгружает HTML контент со страницы указанной в атрибуте href или data-ajax-load в элемент по селектору указанному в атрибуте data-ajax-target (обязательный атрибут):
<button data-ajax-load="/get/five" data-ajax-target="#load">Five!</button> <div id="load">...</div>
Опции:
- добавить данные для передачи на заданный URL используя
dataатрибуты - указать метод доставки -
data-ajax-method
События:
-
success.ajax.bluz- при удачном завершении AJAX запроса -
error.ajax.bluz- при ошибке в AJAX запросе
Modal dialog
Элемент атрибутом data-ajax-dialog открывает модальный диалог, контент которого в формате HTML будет доставлен посредством XMLHttpRequest:
<a data-ajax-dialog href="/dialog">Click Me!</a>
Опции:
- добавить данные для передачи на заданный URL используя
dataатрибуты - указать метод доставки -
data-ajax-method - задать стиль модального окна -
data-modal-style="modal-lg"
События:
-
success.ajax.bluz- при удачном завершении AJAX запроса -
error.ajax.bluz- при ошибке в AJAX запросе -
shown.bluz.modal- при наступлении событияshown.bs.modalу созданного модального окна -
hidden.bluz.modal- при наступлении событияhidden.bs.modalу созданного модального окна
Autocomplete
Для организации автодополнения использует виджет autocomplete из библиотеки jQueryUI, для подключение потребуется один вызов:
<script> require(['bluz.autocomplete']); </script>
Дальнейшие настройки осуществляются посредство data атрибутов:
- указать источник -
data-ajax-load - указать метод доставки -
data-ajax-method - указать элемент, значение которого будет изменяться -
data-ajax-target - какое поле из JSON-ответа использовать в качестве значение, по умолчанию -
id - какое поле из JSON-ответа использовать в качестве заголовка, по умолчанию - имя текущего поля
<input type="text" class="form-control" name="login" value="ad" data-ajax-load="/users/search" data-ajax-target="#userId" data-ajax-item-id="id" data-ajax-item-label="login" autocomplete="off" required /> <input type="hidden" id="userId" name="userId" value=""/>
В данном примере на сервер отправится запрос /users/search/?login=ad%, а из массива ответа будет составлен список для автодополнения.
Tooltips
Автоматическая инициализация Tooltips для элементов с data-toggle="tooltip":
<a href="#" data-toggle="tooltip" title="User Role">Username</a>
Image Preview
Для ссылок с атрибутом data-ajax-preview, где href указывает на полноразмерную картинку реализован просмотр картинок:
<a href="/uploads/123.jpg" data-ajax-preview> <img src="/uploads/123-small.jpg" class="img-polaroid"/> </a>
Аналогично, для элементов с атрибутом data-ajax-preview, где атрибут указывает на полноразмерную картинку:
<img src="/uploads/123-small.jpg" data-ajax-preview="/uploads/123.jpg"/>
Серверная часть
Со стороны сервера передача данных не требует от нас чего-либо экстраординарного, просто назначаем переменные в шаблон:
<?php return function() { $this->assign('test', 123); }
Ответ будет содержать JSON объект:
Стоит предостеречь разработчиков при создании универсального контроллера для обычных и
XMLHTTPRequest- не стоит в таких контроллерах закидывать информацию во view as is. Приведу пример - вы закидываете$view->user = $userObject- в HTML вы контролируете какие поля отображаете пользователям, а используя этот же код для ajax - нет.
Как и при работе с обычными контроллерами, мы можем использовать пакет Messages:
<?php return function() { $this->getMessages()->addNotice('Notice Text'); $this->getMessages()->addSuccess('Success Text'); $this->getMessages()->addError('Error Text'); }
В данном случае в ответ сервера будут добавлен заголовок Bluz-Notify и все сообщения в JSON формате:
Bluz-Notify: {"error":["Error Text"],"success":["Success Text"],"notice":["Notice Text","Method POST"]}
Можно принудительно перезагрузить текущую страницу:
<?php return function() { Response::reload(): }
За это будет отвечать заголовок Bluz-Redirect:
Bluz-Redirect: http://my.current.location
Или отправить куда-нибудь:
<?php return function() { Response::redirect("http://google.com"): }
Заголовок Bluz-Redirect:
Bluz-Redirect: http://google.com
Размышления
Есть мысль перевесить управление с классов на data-spy (по аналогии с Twitter Bootstrap)? Но тут я вижу сразу два недостатка, которые есть в самом Bootstrap:
- обработчики вешаются независимо на data-spy[scroll] и data-spy[affix]
- нет возможности использовать их одновременно для одного элемента
Думаю было бы правильно, чтобы был следующий функционал (где-то должен быть уже реализован, нутром чую), начну с HTML:
<div data-helper="ajax confirm"></div>
Далее должна быть регистрация хэлперов в JavaScript:
$.helper.register('ajax', { 'click': function(element){/*click logic*/} } ); $.helper.register('confirm', { 'click': function(element){/*click logic*/} } );
И собственно инициализация обработчика:
$(body).on('click.bluz.helper', '[data-bluz-helper]', function(){ var helpers = $(this).data('bluz-helper').split(' '); var chain = null; for (helperName in helpers) { if ($.helper.isRegistered(helperName )) { var helper = $.helper.get(helperName); if (helper.click) { chain = helper.click(this, chain); // or use apply? if (false === chain) return; } } } });