Skip to content
Anton edited this page Nov 24, 2017 · 26 revisions

Описание

В системе используется 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 объект:

{"test":123}

Стоит предостеречь разработчиков при создании универсального контроллера для обычных и 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;
            }
        }
    }
});