Что бы на сайте под управлением CMS Bitrix добавить свою вкладку в редактор элемента инфоблока достаточно сделать несколько не сложных действий. Ниже будет показан пример с добавлением вкладки с историей изменения цены товара.
Результат всех проделанных действий — будет скриншот из этой записи.
Итак, что нужно:
- Повесить свой обработчик на событие Bitrix(который отрисует нашу вкладку)
- Сделать обработчик + шаблон html с выводимой вкладкой и информацией в этой вкладке
Для работы с административной частью Bitrix, так же и для создания административных страниц Bitrix, есть специальное (достаточно запутанное) API. Собственно если понять это API можно создавать «годные» страницы для административных нужд, если вы уже делаете страницы администратора для Bitrix — то понять код ниже вам не составит труда.
Вешаем наш обработчик на событие Bitrix в файл init.php (/bitrix/php_interface/init.php)
1 2 3 4 5 |
require($_SERVER['DOCUMENT_ROOT'] . '/coderun/TabProductElement.php'); \Bitrix\Main\EventManager::getInstance()->addEventHandler("main", "OnAdminIBlockElementEdit", [Coderun\TabProductElement::getInstance(),'onInit']); |
Что здесь происходит:
- Подключаем файл обработчика (расположение выбираете на свой вкус, здесь указан лишь пример)
- Регистрируете обработчик который будет выполняться при возникновении события OnAdminIBlockElementEdit
Само событие OnAdminIBlockElementEdit возникает в недрах Bitrix в файле /bitrix/modules/iblock/admin/iblock_element_edit.php строка 521
Описываем наш обработчик в виде PHP Класса
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
<?php namespace Coderun; /** * Вкладка для каталога товаров * В элемент инфоблока * Для отслеживания изменений цены * */ class TabProductElement { protected static $_instance = null; /** * Название цен */ const PRICE_LABEL = [ 'opt' => 'Оптовая цена', 'base' => 'Базовая цена', 'zakup' => 'Закупочная цена', 'maker' => 'Цена завода', ]; /** * * @return TabProductElement */ public static function getInstance() { if (is_null(self::$_instance)) { self::$_instance = new self(); } return self::$_instance; } /** * Инициализация и запуск * Если не вернёт специальный массив, то прочие методы не запустятся * @param array $params Данные по админке * @return boolean */ public function onInit($params) { if (($params['IBLOCK']['ID'] ?? null) != '4') {//Только для инфоблока 4-е return false; } return array( "TABSET" => "PRICE_HISTORY", "GetTabs" => array($this, "tabs"), "ShowTab" => array($this, "showtab"), "Action" => array($this, "action"), "Check" => array($this, "check"), ); } public function action($params) { return true; } public function check($params) { return true; } /** * Возвращает параметры будущей вкладки * @param type $arArgs * @return type */ public function tabs($arArgs) { return array( array( "DIV" => "price_history_edit1", "TAB" => "История изменения цен", "ICON" => "sale", "TITLE" => "Таблица изменения цен", "SORT" => 100 ) ); } /** * Вывод нужной вкладки * @param type $divName * @param type $params * @param type $bVarsFromForm */ public function showtab($divName, $params, $bVarsFromForm) { //return; if ($divName == "price_history_edit1") {//Одна из наших вкладок созданых в tabs ?> <tr> <!--Обязательно, что бы не разнесло форму--> <td> <!--Обязательно, что бы не разнесло форму--> <table class="internal" width="100%" cellspacing="0" cellpadding="0" border="0"> <tbody> <tr class="heading"> <td>#</td> <td>Тип цены</td> <td>Значение</td> <td>Обновлено</td> </tr> <?php $i = 0; ?> <?php foreach ($this->getProductPriceHistory($params['ID']) as $items) { ?> <tr> <td valign="top" align="left"> <?php echo ++$i; ?> </td> <td valign="top" align="center"> <?php echo self::PRICE_LABEL[$items['PRICE_TYPE']]; ?> </td> <td valign="top" align="center"> <?php echo CurrencyFormat($items['PRICE'], 'RUB'); ?> </td> <td valign="top" align="center"> <?php echo (string) $items['DATE_CREATE']; ?> </td> </tr> <?php } ?> </tbody> </table> </td> </tr> <? } } /** * Получение данных из таблицы с историей * @param type $id * @return type */ protected function getProductPriceHistory($id) { \Bitrix\Main\Loader::includeModule('coderun.pricehistory'); $result = []; $dbQuery = \Coderun\PriceHistory\ProductPriceHistoryTable::getlist([ 'filter' => ['ELEMENT_ID' => $id], 'order' => ['ID' => 'DESC'], 'select' => ['*'], 'limit' => 50, 'cache' => ['ttl' => 3600], ]); while ($tmp = $dbQuery->fetch()) { $result[] = $tmp; } return $result; } } |
Что здесь происходит:
- Ну вопервых это метод «onInit». Он отвечает за овтвет на событие на которое мы «подписались» выше. Главное что бы этот метод вернул специальный массив в с ключами и функциями обратного вызова, которые отвечают за действия.
- Метод «tabs» описывает вкладку(вкладки) которые нужно добавить. Массив многомерный.
- Метод «showtab» — шаблон вывода вкладок. В данном случае это одна вкладка которая выводит табличные данные от стороннего модуля. Главное что бы html не сломался, ваш шабло нужно обернуть в <tr><td>ТУТ_ВАШ_ШАБЛОН</tr></td>
- Метод getProductPriceHistory — это обычный запрос к БД по D7 который вернёт необходимы нам данные. Данные мы получаем отдельным способом.
В целом простой и понятный способ как можно отобразить дополнительную информацию в административной панели на сайте под управлением CMS Bitrix.
Вот только вставить на такую вкладку таблицу, используя CAdminList множно, но при попытке сортировать или производить любые другие интерактивные действия вроде постраничной навигации — ломается верстка. То же самое и с bitrix:main.ui.grid
Увы, пока не нашел решения как вставить полноценную коробочную таблицу именно во вкладку.
Вёрстка не ломается и можно спокойно фильтровать, сортировать и использовать постраничную навигацию.
Пример с пагинацией
https://youtu.be/FWgZWIcfQNY