Модальные окна OpenCart

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

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

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

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

Для того чтобы использовать модальное окно OpenCart, надо определить какая библиотека предоставляет для этого функционал, используемый в этом движке.

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

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

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

•••
js
$('#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 окне. А для показа этого окна используется:

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

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

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

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

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

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

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

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

  • div с классом modal-header в котором h4, который и есть заголовок окна
  • div с классом modal-body внутри содержит контент окна
Просмотр html кода модального окна Настройки разработчика
Просмотр html кода модального окна Настройки разработчика

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

•••
xml
<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 будем использовать:

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

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

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

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

•••
php
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.