[1С-Битрикс, JavaScript, PHP] Меняем страницу просмотра элемента универсальных списков в коробочном Битрикс24
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Всем привет.
Если вы когда-либо работали с универсальными списками в Битрикс24, то, наверное, в курсе, что страница детального просмотра элемента полностью идентична странице редактирования. Единственное отличие — если у пользователя права только на чтение, то на странице не будет кнопок «Сохранить» и «Применить». Согласитесь, не самый приятный интерфейс.
И поэтому когда на работе возникла необходимость использования универсальных списков, я решил поменять страницу детального просмотра, благо мы используем коробку, и возможности для кастомизации просто неограниченные.
ВАЖНОЕ ПРЕДУПРЕЖДЕНИЕ
Создатели Битрикс24 крайне не рекомендуют менять интерфейс корпоративного портала, поскольку в коробке публичная часть приравнивается к ядру, и при обновлении системы есть риск, что все ваши модификации будут стёрты.
Если же вы решите скопировать нужные шаблоны в папку local и издеваться над ними как хотите, то при обновлении они затронуты не будут. Но и новые фичи к ним тоже не будут применены.
Поэтому единственно верный способ в данном случае — это модификация DOM-дерева через Javascript
По сути нам нужно всего-то подменить ссылку на детальную страницу в таблице списка:
Однако на деле это не так просто реализовать, т.к. нужно лезть в компонент, отвечающий за вывод универсальных списков и править ссылку там.
Поэтому мы пойдём иным путём — через Javascript будем открывать страницу в слайдере, используя битриксовую библиотеку SidePanel.
Сделать это можно двумя способами — в init.php и своём модуле. Также необходимо зарегистрировать свою JS-библиотеку.
И хотя второй способ более удобен, я покажу вам именно первый, а в конце статьи дам ссылку на свой модуль.
Итак, поехали. Все действия нужно выполнять в папке local.
Для начала нужно создать отдельную папку, где будет храниться наша библиотека. Назовём её, к примеру, viewer, и будет она иметь следующую структуру:
/viewer
-/js
--viewer.js // наша js-библиотека
-include.php // файл, который мы будем подключать в init.php
Здесь немного остановимся. Для php-кода я создал отдельный файл, который потом подключу в init.php, чтобы не засорять последний.
Давайте теперь зарегистрируем нашу библиотеку с помощью метода старого ядра CJSCore::RegisterExt:
// include.php
// т.к. в битриксе есть js-библиотека viewer, то нужно использовать другое название
CJSCore::RegisterExt('elementviewer', [
'js' => '/local/viewer/js/viewer.js', // путь к библиотеке
'rel' => ['SidePanel'] // слайдер
]);
Осталось только подключить данную библиотеку на странице универсальных списков методом CJSCore::Init, и, казалось бы, дело в шляпе — можно приступать к написанию самой библиотеки.
Однако не всё так просто, т.к. перед подключением необходимо проверить, что мы находимся на нужной странице. Делать это лучше с помощью регулярных выражений, т.к. id списка в адресе может меняться
// include.php
$pattern = '/\/lists\/(\d+)\/view\//'; // часть адреса страницы универсального списка, где (\d+) = id списка
$server = Bitrix\Main\Context::getCurrent()->getServer(); // объект Server, потребуется для получения адреса страницы
if(preg_match($pattern, $server->getRequestUri())) {
CJSCore::Init(['elementviewer']); // подключаем библиотеку
}
Итак, библиотеку подключили, осталось её написать. Для этого создаём файл viewer.js (если ранее не создали) и первым делом объявляем неймспейс с помощью функции BX.namespace:
const ElementViewer = BX.namespace('Viewer');
Теперь все переменные и функции можно объявлять следующим способом:
ElementViewer.init = function() {
}
Чтобы не писать весь код в одной функции, разобьём её для удобства на более мелкие.
Первым делом нам необходимо найти на странице узел, содержащий ссылку на детальную страницу. Для этого воспользуемся функцией BX.findChildren, которая должна вернуть нам список всех объектов, содержащих ссылки на детальную страницу:
ElementViewer.findCell = function () {
return BX.findChildren(document, {
class: 'main-grid-cell-content' // css-класс узла с искомой ссылкой
}, true);
}
Заодно напишем функцию, которая будет извлекать id списка и элемента из ссылки для дальнейшей работы:
ElementViewer.pattern = '/lists/(\\d+)/element/0/(\\d+)'; // часть адреса страницы детального просмотра элемента универсального списка, где первый шаблон = id списка, а второй = id элемента.
ElementViewer.extractListData = function (url) {
let match = url.match(this.pattern); // проверяем ссылку регуляркой
if(match) {
return {
list_id: Number(match[1]),
element_id: Number(match[2])
};
}
}
Вернёмся к BX.findChildren. Особенность данной функции в том, что она возвращает список всех объектов с указанным css-классом, и не факт, что это будет ссылка. Поэтому нам нужно выполнить проверку, и уже только после этого отменять событие открытия ссылки и открывать слайдер:
ElementViewer.init = function (sliderUrl) {
const cell = this.findCell();
cell.forEach(item => {
let itemChild = item.children;
let child = itemChild[0];
if(child && child.tagName === 'A') {
const listData = this.extractListData(child.toString()); // получаем id списка и элемента из ссылки
if(listData !== undefined) {
child.addEventListener('click', (e) => {
e.preventDefault(); // отменяем переход по ссылке
this.openSlider(sliderUrl, listData.list_id, listData.element_id); // открываем слайдер
})
}
}
});
}
Нам осталось написать последнюю функцию, которая будет открывать слайдер. Для этого задействуем библиотеку SidePanel:
ElementViewer.openSlider = function (sliderUri, listId, elementId) {
// в слайдер можно передавать данные методом POST, поэтому воспользуемся этой возможностью для передачи id списка и элемента
let sliderParams = {
list_id: listId,
element_id: elementId
}
return BX.SidePanel.Instance.open(sliderUri, {
allowChangeHistory: false,
cacheable: false,
requestMethod: 'POST',
requestParams: sliderParams
});
}
Ну что же, библиотека написана, осталось вызвать функцию init после подключения. Для этого вернёмся в include.php, где проверяется адрес страницы:
if(preg_match($pattern, $server->getRequestUri())) {
CJSCore::Init(['elementviewer']); // подключаем библиотеку
$asset = Bitrix\Main\Page\Asset::getInstance();
$script = '<script>BX.ready(function() {
ElementViewer.init();
})</script>';
$asset->addString($script);
}
Остался последний штрих — подключить наш код в init.php:
// init.php
$file = $_SERVER['DOCUMENT_ROOT'] . '/local/path/to/viewer/include.php';
if(file_exists($file)) {
require $file;
}
Если всё сделано правильно, то при нажатии на элемент универсального списка откроется слайдер:
В заключении, как и обещал, ссылка на модуль, реализующий то же самое.
Спасибо за внимание.
===========
Источник:
habr.com
===========
Похожие новости:
- [Nginx, JavaScript, DevOps] Я сделал свой PyPI-репозитарий с авторизацией и S3. На Nginx
- [Разработка веб-сайтов, JavaScript, Математика] Математика верстальщику не нужна, или Временные функции и траектории для покадровых 2D анимаций на сайтах
- [JavaScript, Программирование, Разработка веб-сайтов] JavaScript: делегирование событий простыми словами (перевод)
- [Разработка веб-сайтов, JavaScript, Программирование, Отладка] Обработка ошибок в JavaScript
- [JavaScript, TypeScript] SEO npm-пакета: почему важно правильно настраивать конфиг и писать тесты
- [1С-Битрикс, MySQL, Информационная безопасность, Разработка веб-сайтов, Управление проектами] Интернет-магазин как черная дыра в бюджете
- [JavaScript, Браузеры, Разработка веб-сайтов] Про Shadow DOM
- [Google Cloud Platform, Google Chrome, Google Web Toolkit, Google API, JavaScript] Экстренная психологическая помощь | Prototyping Weekend
- [JavaScript, Node.JS, Программирование, Разработка веб-сайтов] Руководство по Express.js. Часть 2 (перевод)
- [JavaScript, Программирование] Как я искал работу в Берлине
Теги для поиска: #_1sbitriks (1С-Битрикс), #_javascript, #_php, #_bitriks24 (битрикс24), #_php, #_javascript, #_1sbitriks (
1С-Битрикс
), #_javascript, #_php
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:26
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Всем привет. Если вы когда-либо работали с универсальными списками в Битрикс24, то, наверное, в курсе, что страница детального просмотра элемента полностью идентична странице редактирования. Единственное отличие — если у пользователя права только на чтение, то на странице не будет кнопок «Сохранить» и «Применить». Согласитесь, не самый приятный интерфейс. И поэтому когда на работе возникла необходимость использования универсальных списков, я решил поменять страницу детального просмотра, благо мы используем коробку, и возможности для кастомизации просто неограниченные. ВАЖНОЕ ПРЕДУПРЕЖДЕНИЕ
Создатели Битрикс24 крайне не рекомендуют менять интерфейс корпоративного портала, поскольку в коробке публичная часть приравнивается к ядру, и при обновлении системы есть риск, что все ваши модификации будут стёрты. Если же вы решите скопировать нужные шаблоны в папку local и издеваться над ними как хотите, то при обновлении они затронуты не будут. Но и новые фичи к ним тоже не будут применены. Поэтому единственно верный способ в данном случае — это модификация DOM-дерева через Javascript По сути нам нужно всего-то подменить ссылку на детальную страницу в таблице списка: Однако на деле это не так просто реализовать, т.к. нужно лезть в компонент, отвечающий за вывод универсальных списков и править ссылку там. Поэтому мы пойдём иным путём — через Javascript будем открывать страницу в слайдере, используя битриксовую библиотеку SidePanel. Сделать это можно двумя способами — в init.php и своём модуле. Также необходимо зарегистрировать свою JS-библиотеку. И хотя второй способ более удобен, я покажу вам именно первый, а в конце статьи дам ссылку на свой модуль. Итак, поехали. Все действия нужно выполнять в папке local. Для начала нужно создать отдельную папку, где будет храниться наша библиотека. Назовём её, к примеру, viewer, и будет она иметь следующую структуру: /viewer -/js --viewer.js // наша js-библиотека -include.php // файл, который мы будем подключать в init.php Здесь немного остановимся. Для php-кода я создал отдельный файл, который потом подключу в init.php, чтобы не засорять последний. Давайте теперь зарегистрируем нашу библиотеку с помощью метода старого ядра CJSCore::RegisterExt: // include.php
// т.к. в битриксе есть js-библиотека viewer, то нужно использовать другое название CJSCore::RegisterExt('elementviewer', [ 'js' => '/local/viewer/js/viewer.js', // путь к библиотеке 'rel' => ['SidePanel'] // слайдер ]); Осталось только подключить данную библиотеку на странице универсальных списков методом CJSCore::Init, и, казалось бы, дело в шляпе — можно приступать к написанию самой библиотеки. Однако не всё так просто, т.к. перед подключением необходимо проверить, что мы находимся на нужной странице. Делать это лучше с помощью регулярных выражений, т.к. id списка в адресе может меняться // include.php
$pattern = '/\/lists\/(\d+)\/view\//'; // часть адреса страницы универсального списка, где (\d+) = id списка $server = Bitrix\Main\Context::getCurrent()->getServer(); // объект Server, потребуется для получения адреса страницы if(preg_match($pattern, $server->getRequestUri())) { CJSCore::Init(['elementviewer']); // подключаем библиотеку } Итак, библиотеку подключили, осталось её написать. Для этого создаём файл viewer.js (если ранее не создали) и первым делом объявляем неймспейс с помощью функции BX.namespace: const ElementViewer = BX.namespace('Viewer');
Теперь все переменные и функции можно объявлять следующим способом: ElementViewer.init = function() {
} Чтобы не писать весь код в одной функции, разобьём её для удобства на более мелкие. Первым делом нам необходимо найти на странице узел, содержащий ссылку на детальную страницу. Для этого воспользуемся функцией BX.findChildren, которая должна вернуть нам список всех объектов, содержащих ссылки на детальную страницу: ElementViewer.findCell = function () {
return BX.findChildren(document, { class: 'main-grid-cell-content' // css-класс узла с искомой ссылкой }, true); } Заодно напишем функцию, которая будет извлекать id списка и элемента из ссылки для дальнейшей работы: ElementViewer.pattern = '/lists/(\\d+)/element/0/(\\d+)'; // часть адреса страницы детального просмотра элемента универсального списка, где первый шаблон = id списка, а второй = id элемента.
ElementViewer.extractListData = function (url) { let match = url.match(this.pattern); // проверяем ссылку регуляркой if(match) { return { list_id: Number(match[1]), element_id: Number(match[2]) }; } } Вернёмся к BX.findChildren. Особенность данной функции в том, что она возвращает список всех объектов с указанным css-классом, и не факт, что это будет ссылка. Поэтому нам нужно выполнить проверку, и уже только после этого отменять событие открытия ссылки и открывать слайдер: ElementViewer.init = function (sliderUrl) {
const cell = this.findCell(); cell.forEach(item => { let itemChild = item.children; let child = itemChild[0]; if(child && child.tagName === 'A') { const listData = this.extractListData(child.toString()); // получаем id списка и элемента из ссылки if(listData !== undefined) { child.addEventListener('click', (e) => { e.preventDefault(); // отменяем переход по ссылке this.openSlider(sliderUrl, listData.list_id, listData.element_id); // открываем слайдер }) } } }); } Нам осталось написать последнюю функцию, которая будет открывать слайдер. Для этого задействуем библиотеку SidePanel: ElementViewer.openSlider = function (sliderUri, listId, elementId) {
// в слайдер можно передавать данные методом POST, поэтому воспользуемся этой возможностью для передачи id списка и элемента let sliderParams = { list_id: listId, element_id: elementId } return BX.SidePanel.Instance.open(sliderUri, { allowChangeHistory: false, cacheable: false, requestMethod: 'POST', requestParams: sliderParams }); } Ну что же, библиотека написана, осталось вызвать функцию init после подключения. Для этого вернёмся в include.php, где проверяется адрес страницы: if(preg_match($pattern, $server->getRequestUri())) {
CJSCore::Init(['elementviewer']); // подключаем библиотеку $asset = Bitrix\Main\Page\Asset::getInstance(); $script = '<script>BX.ready(function() { ElementViewer.init(); })</script>'; $asset->addString($script); } Остался последний штрих — подключить наш код в init.php: // init.php
$file = $_SERVER['DOCUMENT_ROOT'] . '/local/path/to/viewer/include.php'; if(file_exists($file)) { require $file; } Если всё сделано правильно, то при нажатии на элемент универсального списка откроется слайдер: В заключении, как и обещал, ссылка на модуль, реализующий то же самое. Спасибо за внимание. =========== Источник: habr.com =========== Похожие новости:
1С-Битрикс ), #_javascript, #_php |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:26
Часовой пояс: UTC + 5