Работа с модальными окнами

03.08.2014

Часто поступают вопросы по поводу моего старого перевода про работу с модальными окнами в yii. Информация несколько устаревшая, поэтому давайте рассмотрим пару вариантов, которыми я пользуюсь сейчас.

Итак, ниже мы рассмотрим работу с CJuiDialog и Bootstrap modal. Скажу сразу что мне больше нравится работать с бутстрапом.

Примеры у меня в гитхабе (большие участки кода в статье кликабельны).

Пускай нам нужна модалка с какой-то формой и кнопкой отправить, кликая по которой данные формы мы передаем на сервер. Работу с модалками я разделяю 3 этапа:

  1. Подготовка модалки и формы
  2. Кликнули по ссылке - получили форму, положили её в модалку и показали модалку.
  3. Отправили данные формы на сервер и закрыли модальное окно.

1. Модальные окна в twitter bootstrap

Первое что делаем - подключаем бутстрап в лайоуте проекта на yii. Давайте создадим BsModalController в индексе которого будет рендерить страничку с одной ссылкой:

Страница с ссылкой на ajax форму

На этой же странице добавляем див модалки:

div-модального окнаИменно в этот див мы будем класть код формы, который получим по клику.Теперь нужно написать немного JS’a для обработки клика по ссылке:

$('.getForm').click(function() {
    var url = $(this).attr('href');
    var modal = $('.modal');
    $.get(url, function(data) {
        modal.html(data).modal('show');
    });
    return false;
});

Из кода выше видно, что нашей ссылке нужно задать класс getForm и указать url до экшена, в котором делается renderPartial самой формы:

Правильная ссылка до формы

Ну и ок, давайте напишем экшен getForm и саму форму:

public function actionGetForm() {
    $this->renderPartial('getForm');
}

И файл getForm.php

Код формы

Давайте посмотрим, что у нас получилось:

Итоговая форма на twitter bootstrap

Всё отлично, осталось теперь только написать обработчик клика по кнопке Сохранить:

$('.modal').on('click', '.sendForm', function() {
    var form = $(this).closest('form');
    $.post(
        form.attr('action'),
        form.serialize(),
        function(data) {
            //window.location.reload();
            $('.modal').modal('hide');
        }
    );
    return false;
});

На кнопку сохранить вешаем класс sendForm и теперь данные формы сериализуются и отправляются на сервер, где с ними можно работать через обычный $_POST[...].

Итак, мы написали 2 универсальных скрипта - один загружает данные в модалку и показывает, а другой отправляет заполненную форму на сервер. Главное правильно проставлять классы.

2. Использование CJuiDialog для работы с модальными окнами

Далее пойдет речь о встроенных в yii обертках для jquery-ui. Скажу сразу, что я не очень люблю этот вариант, как-то проще всё сделать на бутстрапе, но этот вариант тоже нужно знать.

Создаем новый контроллер JuiController, где в индексе также рендерим одну кнопку и скрытый CJuiDialog:

Код для CJuiDialog

Суть такая - при клике по классу getJuiForm мы должны получить форму, положить её в div#dialog-body и отобразить диалог.

И вот главный минус! - У этого компонента КУЧА свойств! Можно добавлять кнопки в диалог, но надо будет ещё и дописывать код для них. Я просто не могу столько свойств запомнить, надо вспомнить как их в опциях указать, какой js туда засунуть…. В общем это ужас просто!

Но мы делаем всё по-простому:

$('.getJuiForm').click(function() {
    var url = $(this).attr('href');
    $.get(url, function(data) {
        $('#juiDialog #dialog-body').html(data);
        $('#juiDialog').dialog("open");
    });
    return false;
});

Т.е. код практически идентичный, только другие id-шники. Вот что получаем при клике:

Пример диалога на CJuiDialogЗакрытие и сохранение я уже описывать не буду, они абсолютно одинаковые с модалками от бутстрапа.

Д/З: разобратсья как динамически назначать title модалки, как работать с кнопками, встроенными в CJuiDialog, посмотреть какие вообще есть свойства у этого виджета.

И теперь становится ясно как же сделать редактирование записей в модалке? - в getForm выбираем модель для редактирования (внутрь экшена параметры можно передать через тот же url или data-атрибутом, как удобнее), через CActiveForm заполняем форму и выводим её в модалке. Далее при сохранении работаем с $_POST как при обычном сохранении без аякса! Единственное дорабатывает проверку на ошибки при сохранении, но тут уже подумайте сами как сделать.По-поводу скринов с html кодом, уж извиняйте, очень лень делать чтобы была возможность напрямую лепить, смотрите если что на гитхабе всё!

blog comments powered by Disqus
Наверх