Статья нашего сотрудника из его личного блога.

Разрабатывая модуль в админке мне понадобилось использовать модальные окна OpenCart для вывода определенной информации, а так же для показа формы. Мой опыт frontend на тот момент был так себе, однако коллега подсказал что в OpenCart используется jquery (2.1.1), а у этой библиотеки есть поддержка popup окон. Но не все так просто …

Уточним: модальное окно == всплывающее окно == popup.

Библиотека модальных окон

Кнопка при клике по которой показывается модальное окно

Для того чтобы использовать модальное окно OpenCart, надо определить какая библиотека предоставляет для этого функционал, используемый в этом движке. Разбирая админку OpenCart 3.0 (в 2.3 такой кнопки нет), в разделе Панель состояния была найдена кнопка, при клике по которой показалось всплывающее окно.

То что нужно, начинаем разбор :)

Модальное окно в админке OpenCart Настройки разработчика

Заходим на страницу "Панель состояния", открываем ее исходный код и смотрим в конце скрипт:

$('#button-setting').on('click', function() {
    $.ajax({
        url: 'index.php?route=common/developer&user_token=D9aTD65JQVdyOY9pcVxcRUx0M3eTefnr',
        dataType: 'html',
        beforeSend: function() {
            $('#button-setting').button('loading');
        },
        complete: function() {
            $('#button-setting').button('reset');
        },
        success: function(html) {
            $('#modal-developer').remove();
             
            $('body').prepend('<div id="modal-developer" class="modal">' + html + '</div>');
             
            $('#modal-developer').modal('show');
        },
        error: function(xhr, ajaxOptions, thrownError) {
            alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
        }
    }); 
}); 

Как видно, на кнопку с id button-setting вешается обработчик на клик, в котором ajax запрос, успешный результат которого показывается в popup окне. А для показа этого окна используется:

$('#modal-developer').modal('show');

Похоже на библиотеку jquerymodal. Однако в bootstrap тоже есть поддержка модальных окон. Пробуем выяснить через отладчик какая библиотека все-таки используется, ставим брекпоинт в вышеприведенном скрипте на методе modal.

Брекпоинт на методе modal

Нажимаем на кнопку (на первом скрине), попадаем на брекпоинт, шагаем внутрь и попадаем в bootstrap.min.js.

Стек привел в bootstrap.min.js

Всплывающие окна в OpenCart реализуются через bootstrap.

Использование popup окон в OpenCart

Проинспектировав окно выясняем, что оно уже содержит нужную нам логику закрытия окна и состоит из двух важных для нас частей:

  • div с классом modal-header в котором h4, который и есть заголовок окна

  • div с классом modal-body¨C11Cвнутри содержит контент окна

Просмотр html кода модального окна Настройки разработчика

Так как окно уже имеет оформление, то просто возьмем его каркас, классы и на основе верстки этого окна составим свое:

<div id="modal-window" class="modal">
    <div class="modal-dialog">
        <div class="modal-content">
           
            <!--заголовок и кнопка закрытия-->
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                <h4 class="modal-title"></h4>
            </div>
             
            <!--контентная часть окна-->
            <div class="modal-body"></div>
             
        </div>
    </div>
</div>

Для показа окна с id modal-window будем использовать:

$('#modal-window').modal('show');

Теперь в нужном нам месте страницы в админке разместим свои вёрстку и js. Для этого используем события в OpenCart. Например повесим обработчик на страницу редактирования заказа:

$this->model_extension_event->addEvent('modal_window', 'admin/view/sale/order_form/after', 'extension/module/modal_window/eventSaleOrderFormAfter');

Теперь обработчик:

public function eventSaleOrderFormAfter(&$route, &$args, &$output)
{
    $idOrder = $args["order_id"];
 
    $this->load->model('sale/order');
    $this->load->model('catalog/product');
 
    //загрузка списка продуктов заказа
    $aOrderProducts = $this->model_sale_order->getOrderProducts($args["order_id"]);
     
    //строка верстки списка товаров
    $sOrderProducts = "";
 
    //формируем список товаров
    for($i=0; $i<count($aOrderProducts); ++$i)
    {
        $aProduct = $this->model_catalog_product->getProduct($aOrderProducts[$i]["product_id"]);
        $sOrderProducts .= "<li>".$aProduct["name"]." - ".$aProduct["model"]." (".$aOrderProducts[$i]["quantity"]." шт.): ".round($aOrderProducts[$i]["total"], 2)."р. </li>";
    }
     
    $sOrderProducts = "<ul>$sOrderProducts</ul>";
 
    //верстка модального окна и скрипт вызова
    $sModal = '
    <div id="modal_window" class="modal">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
                    <h4 class="modal-title">Список товаров</h4>
                </div>
                <div class="modal-body">
                    '.$sOrderProducts.'
                </div>
            </div>
        </div>
    </div>
    <script>$("#modal_window").modal("show");</script>
    ';
 
    //находим закрывающий тег body и перед ним вставляем модальное окно и скрипт его показа
    $iPos = strripos($output, "</body>");
    $output = substr($output, 0, $iPos).$sModal.substr($output, $iPos);
}

Каждый раз при входе на страницу редактирования заказа будет появляться всплывающее окно со списком товаров.

Можно вставлять кнопку в панель кнопок в админке (или в любое другое место), повесить на кнопку обработчик клика и показывать модальное окно (как это сделано на странице Панель состояния). Однако для этого придется использовать регулярные выражения или парсер DOM.

Автор: Виталий Бутурлин