Добавление пользовательской кнопки в грид Bitrix24
В этой статье мы рассмотрим, как добавить пользовательскую кнопку в выпадающий список действий в гриде Bitrix24, на примере страницы деталей сделки.
1. Подключение обработчика событий
Для начала подключим обработчик событий в init.php:
use Bitrix\Main\EventManager;
use Bitrix\Main\Page\Asset;
CModule::IncludeModule('main');
$eventManager = EventManager::getInstance();
$eventManager->addEventHandler(
'main',
'OnEpilog',
['CustomHandlerClass', 'MyOnEpilogHandler'],
100
);
2. Реализация обработчика
Создадим метод MyOnEpilogHandler, который подключает необходимые JS-скрипты на странице деталей сделки:
class CustomHandlerClass {
public static function MyOnEpilogHandler() {
global $APPLICATION;
$asset = Asset::getInstance();
if (str_contains($APPLICATION->GetCurPage(), "crm/deal/details/")) {
$iblockId = IBlockHelper::getIBlockByCode('DEAL_ATTACHMENTS');
\CJSCore::RegisterExt(
'dealSendFiles',
[
'js' => '/local/js/deal/details/sendFiles.js',
'rel' => ['popup', 'ajax', 'ui.notification', 'jquery']
]
);
\CJSCore::Init(['dealSendFiles']);
echo '<script>
BX.ready(function() {
BX.dealAttachmentsIBlockId = ' . intval($iblockId['ID']) . ';
});
</script>';
}
}
}
Этот код проверяет текущий URL, и если он соответствует странице деталей сделки, подключает кастомный JavaScript-файл, а также передает идентификатор инфоблока в глобальную переменную BX.
3. Реализация JS-скрипта
Теперь создадим файл /local/js/deal/details/sendFiles.js со следующим содержимым:
BX.addCustomEvent("Grid::ready", BX.delegate(function (gridInstance) {
updateGridActions(gridInstance, BX.dealAttachmentsIBlockId);
}));
BX.addCustomEvent("Grid::updated", BX.delegate(function (gridInstance) {
updateGridActions(gridInstance, BX.dealAttachmentsIBlockId);
}));
/**
* Функция обновления списка операций в строках грида
* @param {Object} gridInstance - объект текущего грида
* @param {number} iblockId - идентификатор инфоблока
*/
function updateGridActions(gridInstance, iblockId) {
console.log('Grid обновлен:', gridInstance.containerId);
const expectedContainerId = `lists_attached_crm_${iblockId}`;
if (gridInstance.containerId === expectedContainerId) {
gridInstance.rows.rows.forEach(row => {
if (row.actionsButton) {
const actions = parseGridActions(row.actionsButton.dataset['actions']);
actions.unshift({
title: "Отправить файлы",
text: "Отправить файлы",
onclick: `sendFiles('${row.node.dataset.id}')`,
default: true
});
row.actionsButton.dataset['actions'] = stringifyGridActions(actions);
}
});
}
}
/**
* Парсит строку действий грида
* @param {string} actionsString - строка с действиями
* @returns {Array} массив объектов действий
*/
function parseGridActions(actionsString) {
try {
const json = actionsString.slice(1, -1).replace(/'/g, '"');
return JSON.parse(json);
} catch (error) {
console.error("Ошибка парсинга действий:", error);
return [];
}
}
/**
* Преобразует массив действий в строку для dataset
* @param {Array} actionsArray - массив объектов действий
* @returns {string} строка для записи в dataset
*/
function stringifyGridActions(actionsArray) {
return `(${JSON.stringify(actionsArray)})`;
}
/**
* Отправляет файлы
* @param {string} rowId - идентификатор строки
*/
function sendFiles(rowId) {
BX.ajax.runAction('customNamespace:deal.sendFiles', {
data: { rowId }
}).then(response => {
BX.UI.Notification.Center.notify({
content: 'Файлы успешно отправлены!',
autoHideDelay: 3000
});
}).catch(error => {
BX.UI.Notification.Center.notify({
content: 'Ошибка при отправке файлов.',
autoHideDelay: 3000
});
console.error("Ошибка отправки файлов:", error);
});
}
4. Что делает код
- Подключает кастомный JavaScript на странице деталей сделки.
- Отслеживает события загрузки грида (Grid::ready) и его обновления (Grid::updated).
- Добавляет пользовательскую кнопку в список действий каждой строки грида, если ID контейнера грида совпадает с ожидаемым.
- При нажатии на кнопку выполняет AJAX-запрос к кастомному методу на сервере, отправляя данные строки.
- Показывает уведомление о результате выполнения операции.
5. Настройка метода на сервере
Не забудьте настроить серверный метод customNamespace:deal.sendFiles, который будет обрабатывать запросы. Например:
class DealController extends \Bitrix\Main\Engine\Controller {
public function sendFilesAction($rowId) {
// Логика отправки файлов
return [
'success' => true
];
}
}
Теперь вы можете использовать данный код, чтобы добавить пользовательскую кнопку в грид Bitrix24.