Оптимизация производительности и безопасности — залог успешного проекта на 1С-Битрикс. Данный материал посвящен практическому применению «Дополнительные возможности встройки CRM_XXX_DETAIL_ACTIVITY, CRM_DYNAMIC_XXX_…». Мы подготовили подробный разбор принципов работы и развернутые примеры интеграции.
Дополнительные возможности встройки CRM_XXX_DETAIL_ACTIVITY, CRM_DYNAMIC_XXX_DETAIL_ACTIVITY
> Scope: crm
>
> Кто может работать со встройкой: пользователь с доступом на изменение элемента
При помощи дополнительных параметров можно для своего пункта в меню таймлайна установить интерфейс Битрикс24.
Для добавления встройки используйте метод placement.bind. Базовые возможности встройки описаны в статье Кнопка над таймлайном карточки элемента.
Скачать пример приложения с использованием встройки.
Параметр OPTIONS
Названиетип | Описание |
|---|---|
useBuiltInInterfaceboolean | Использовать стандартный интерфейс Битрикс24. По умолчанию N. Если Y, то интерфейс строится по описанной структуре LayoutDto. Процесс работы с интерфейсом описан ниже |
newUserNotificationTitlestring | Заголовок уведомления для нового пользователя |
newUserNotificationTextstring | Текст уведомления для нового пользователя. При клике на «Подробнее» откроется слайдер с контекстом newUserNotification=Y и шириной 800px |
Пример регистрации
BX24.callMethod(
'placement.bind',
{
'PLACEMENT': 'CRM_DEAL_DETAIL_ACTIVITY',
'HANDLER': 'https://your-handler-uri.ru',
'TITLE': 'Моя встройка',
'OPTIONS': {
'useBuiltInInterface': 'Y',
'newUserNotificationTitle': 'Встречайте новое приложение',
'newUserNotificationText': 'E-invoice поможет работать со счетами'
}
}
);!img_15.png 11569
Работа с интерфейсом встройки {#Interface}
Взаимодействие происходит через метод BX24.placement.call. Цикл работы приложения при использовании штатного интерфейса Битрикс24 useBuiltInInterface = Y:
1. Загрузка iframe.
Приложение загружается в скрытом iframe. В placementOptions передаются:
entityTypeIdentityIduseBuiltInInterface: Y
2. Отрисовка интерфейса.
Когда приложение загружено, оно должно вызвать setLayout, чтобы отрисовать первичное состояние места встройки.
BX24.placement.call('setLayout', LayoutDto, callback);3. Реакция на действия.
Если приложение отобразило в интерфейсе интерактивные элементы, например ссылки, оно может зарегистрировать обработчик bindLayoutEventCallback, чтобы обрабатывать реакцию на взаимодействие с элементами.
BX24.placement.call('bindLayoutEventCallback', null, callback);4. Управление состоянием элементов.
Можно изменить внешний вид конкретного элемента интерфейса и его видимость через setLayoutItemState.
BX24.placement.call('setLayoutItemState', { id: '...', visible: true/false, properties: {...} }, callback);5. Управление кнопками.
Можно изменить внешний вид кнопок нижней части интерфейса через setPrimaryButtonState и setSecondaryButtonState.
BX24.placement.call('setPrimaryButtonState', {...}, callback);
BX24.placement.call('setSecondaryButtonState', {...}, callback);6. Завершение работы.
Когда процесс работы пользователя со встройкой завершен или если пользователь нажал «отмена», необходимо вызвать finish. Таймлайн будет переключен на таб по умолчанию.
BX24.placement.call('finish');7. Блокировка интерфейса.
На время длительных операций, например сохранения, интерфейс можно заблокировать вызвав lock. Для разблокировки вызвать unlock.
BX24.placement.call('lock'); // блокировка
BX24.placement.call('unlock'); // разблокировка8. Отслеживание изменений элемента.
Для отслеживания изменений полей элемента, например чтобы перерисовать интерфейс в зависимости от значения поля, можно зарегистрировать обработчик bindEntityUpdateCallback. Коллбек будет вызван сразу после сохранения полей в редакторе.
BX24.placement.call('bindEntityUpdateCallback', null, callback);Внешний вид интерфейса LayoutDto {#LayoutDto}
Названиетип | Описание |
|---|---|
blocksContentBlockDto[] | Ассоциативный массив объектов, описывающих контентные блоки. Ключи массива — идентификаторы блоков. Минимум 1 элемент |
primaryButtonButtonDto | Основная кнопка. Обычно завершает обработку данных, сохраняет их |
secondaryButtonButtonDto | Дополнительная кнопка. Обычно отменяет процесс обработки данных |
Нажатие на активные кнопки вызывает коллбеки:
primaryButton— коллебBX24.placement.call('bindPrimaryButtonClickCallback', null, callback),secondaryButton— коллбекBX24.placement.call('bindSecondaryButtonClickCallback', null, callback).
ContentBlockDto {#contentblockdto}
Контентные блоки основной области, их можно сочетать и гибко собирать различные интерфейсы.
Общая структура блока:
{
"type": "string",
"visible": true,
"properties": {}
}type— тип блока, строка,visible— управление видимостью блока, булевое поле. Изменение видимости позволяет организовывать динамические интерфейсы. По умолчанию =true.properties— набор свойств конкретного блока.
Типы контентных блоков
| Тип | Название |
|---|---|
text | Текст |
link | Ссылка |
withTitle | Блок с заголовком |
lineOfBlocks | Несколько контент-блоков в одну строку |
dropdownMenu | Выпадающий список |
input | Поле с вводом текста |
textarea | Поле ввода многострочного текста |
select | Поле ввода с выбором из списка |
list | Ненумерованный список |
section | Раздел |
##### Текст {#text}
Блок с выводом отформатированного текста.
Названиетип | Описание |
|---|---|
valuestring | Текст |
multilineboolen | Обработка переносов строк. Если true, символы \n будут заменены на <br>. По умолчанию false |
boldboolen | Жирный текст. По умолчанию false |
sizestring | Размер текста. Доступные значения: — xs, — sm, — md — по умолчанию, — lg, — xl |
colorstring | Цвет текста. Доступные значения: — base_50, — base_60, — base_70, — base_90, — primary, — warning, — danger, — success |
{
"type": "text",
"properties": {
"value": "Здравствуйте!\nМы начинаем.",
"multiline": true,
"bold": true,
"size": "lg",
"color": "base_90"
}
}!text
##### Ссылка {#link}
Названиетип | Описание |
|---|---|
textstring | Текст ссылки, HTML теги не поддерживаются |
actionActionDto | Действие по нажатию на ссылку |
sizestring | Размер текста. Доступные значения: — xs, — sm, — md — по умолчанию, — lg, — xl |
boldboolen | Жирный текст. По умолчанию false |
{
"type": "link",
"properties": {
"text": "Открыть сделку",
"action": { "type": "redirect", "uri": "/crm/deal/details/123/" },
"bold": true
}
}!link
##### Блок с заголовком {#withTitle}
Блок выводит название и значение. В качестве значения можно использовать другой контент-блок.
Названиетип | Описание |
|---|---|
titlestring | Текст заголовка |
inlineboolean | Показывать название и значение в одну строку. По умолчанию false |
titleWidthstring | Ширина заголовка, применяется если inline=true. Доступные значения:— sm,— md — по умолчанию,— lg |
blockContentBlockDto | Контент-блок, являющийся значением. Поддерживаются блоки с типами text, link, lineOfBlocks |
Пример с контент-блоком типа текст:
{
"type": "withTitle",
"properties": {
"title": "Заголовок",
"block": {
"type": "text",
"properties": {
"value": "Какое-то значение"
}
}
}
}!withTitle1
Пример с контент-блоком типа ссылка:
{
"type": "withTitle",
"properties": {
"title": "Заголовок 2",
"block": {
"type": "link",
"properties": {
"text": "Открыть сделку",
"action": {
"type": "redirect",
"uri": "/crm/deal/details/123/"
}
}
},
"inline": true
}
}!withTitle2
##### Несколько контент-блоков в одну строку {#lineOfBlocks}
Блок выводит в одну строку несколько контент-блоков типа текст или ссылка. Это позволяет выводить одной строкой текст с разным форматированием и со ссылками.
Названиетип | Описание |
|---|---|
blocksContentBlockDto[] | Ассоциативный массив контент-блоков. Поддерживаются блоки с типами text, link |
{
"type": "lineOfBlocks",
"properties": {
"blocks": {
"text": {
"type": "text",
"properties": {
"value": "Какой-то текст"
}
},
"link": {
"type": "link",
"properties": {
"text": "ссылка",
"action": {
"type": "redirect",
"uri": "/crm/deal/details/123/"
}
}
},
"boldText": {
"type": "text",
"properties": {
"value": "жирный текст",
"bold": true
}
}
}
}
}!lineOfBlocks
##### Выпадающий список {#dropdownMenu}
Названиетип | Описание |
|---|---|
selectedValuestring | Текущее выбранное значение. Если не заполнено, будет использовано первое значение из списка |
valuesobject | Объект, в котором названия свойств это код варианта значения supplier, а значения свойств — значение, которое увидит пользователь поставщик |
{
"type": "dropdownMenu",
"properties": {
"selectedValue": "client",
"values": {
"": "- не выбрано -",
"supplier": "поставщик",
"client": "клиент"
}
}
}!dropdownMenu
Чтобы отслеживать изменения значений, зарегистрируйте коллбек:
BX24.placement.call('bindValueChangeCallback', null, Callback)для получения изменений в любом из блоковBX24.placement.call('bindValueChangeCallback', 'id блока', Callback)для получения изменений значения только этого блока.
При изменении значения в коллбек придет id блока выпадающего списка и его текущее значение: {id: "clientMenu", value: "client"}.
##### Поле с вводом текста {#input}
Названиетип | Описание |
|---|---|
titlestring | Заголовок поля |
valuestring | Текст поля |
placeholderstring | Плейсхолдер. Будет показан, если поле не заполнено |
disabledboolean | Если передано true, поле будет заблокировано для редактирования. По умолчанию false |
errorTextstring | Сообщение об ошибке. Если передан не пустой errorText, текущее значение поля не прошло валидацию. Пользователю будет показана ошибка |
{
"type": "input",
"properties": {
"value": "aaa@mail.domain",
"placeholder": "Введите email",
"title": "Email",
"errorText": "Некорректное значение"
}
}!input
Чтобы отслеживать изменения значений, зарегистрируйте коллбек:
BX24.placement.call('bindValueChangeCallback', null, Callback)для получения изменений в любом из блоковBX24.placement.call('bindValueChangeCallback', 'id блока', Callback)для получения изменений значения только этого блока.
При изменении значения в коллбек придет id поля ввода текста и его текущее значение: {id: "email", value: "aaa@mail.domain"}.
##### Поле ввода многострочного текста {#textarea}
Названиетип | Описание |
|---|---|
titlestring | Заголовок поля |
valuestring | Текст поля |
placeholderstring | Плейсхолдер. Будет показан, если поле не заполнено |
disabledboolean | Если передано true, поле будет заблокировано для редактирования. По умолчанию false |
errorTextstring | Сообщение об ошибке. Если передан не пустой errorText, текущее значение поля не прошло валидацию. Пользователю будет показана ошибка |
{
"type": "textarea",
"properties": {
"value": "Пройти через калитку\nСвернуть налево",
"title": "Дополнительная информация"
}
}!textarea
Чтобы отслеживать изменения значений, зарегистрируйте коллбек:
BX24.placement.call('bindValueChangeCallback', null, Callback)для получения изменений в любом из блоковBX24.placement.call('bindValueChangeCallback', 'id блока', Callback)для получения изменений значения только этого блока.
При изменении значения в коллбек придет id поля ввода текста и его текущее значение: {id: "description", value: "Пройти через калитку\nСвернуть налево"}.
##### Поле ввода с выбором из списка {#select}
Названиетип | Описание |
|---|---|
titlestring | Заголовок поля |
selectedValuestring | Текущее выбранное значение. Если не заполнено, будет использовано первое значение из списка |
valuesobject | Объект, в котором названия свойств это код варианта значения msk, а значения свойств — значение, которое увидит пользователь Москва |
disabledboolean | Если передано true, поле будет заблокировано для редактирования. По умолчанию false |
errorTextstring | Сообщение об ошибке. Если передан не пустой errorText, текущее значение поля не прошло валидацию. Пользователю будет показана ошибка |
{
"type": "select",
"properties": {
"selectedValue": "spb",
"values": {
"msk": "Москва",
"spb": "Санкт-Петербург",
"kld": "Калининград"
},
"title": "Город"
}
}!select
Чтобы отслеживать изменения значений, зарегистрируйте коллбек:
BX24.placement.call('bindValueChangeCallback', null, Callback)для получения изменений в любом из блоковBX24.placement.call('bindValueChangeCallback', 'id блока', Callback)для получения изменений значения только этого блока.
При изменении значения в коллбек придет id поля и его текущее значение: {id: "city", value: "msk"}.
##### Ненумерованный список {#list}
Названиетип | Описание |
|---|---|
blocksContentBlockDto[] | Ассоциативный массив контент-блоков. Поддерживаются блоки с типами text, link, lineOfBlocks. Минимум 1 элемент |
{
"type": "list",
"properties": {
"blocks": {
"li1": {
"type": "text",
"properties": {
"value": "Импорт элементов CRM без реквизитов",
"color": "base_70"
}
},
"li2": {
"type": "link",
"properties": {
"text": "Начало работы с CRM",
"action": {
"type": "layoutEvent",
"value": "link2ItemClicked!"
}
}
},
"li3": {
"type": "text",
"properties": {
"value": "Как сконвертировать лид",
"bold": true,
"color": "base_90"
}
}
}
}
}!list
##### Раздел {#section}
Блок выводит сгруппированный набор блоков. Возможен вариант с картинкой.
Названиетип | Описание |
|---|---|
blocksContentBlockDto[] | Ассоциативный массив контент-блоков. Поддерживаются любые виды блоков. Минимум 1 элемент, максимум 20 |
imageSrcstring | Полный путь до картинки |
imageSizestring | Размер картинки. Доступные значения: — lg — по умолчанию,— md,— sm |
typestring | Внешний вид. Доступные значения: — default — по умолчанию,— primary,— warning,— danger,— success,— withBorder |
Пример с несколькими блоками и изображением:
{
"type": "section",
"properties": {
"type": "withBorder",
"imageSrc": "https://www.1c-bitrix.ru/images/content_ru/products/box/bus.png",
"blocks": {
"header": {
"type": "text",
"properties": {
"value": " Отправьте клиенту ссылку на встречу",
"size": "xl",
"color": "base_90"
}
},
"notes": {
"type": "list",
"properties": {
"blocks": {
"li1": {
"type": "text",
"properties": {
"value": "Клиент сам выберет удобный слот",
"color": "base_70"
}
},
"li2": {
"type": "text",
"properties": {
"value": "Встреча появится у вас в делах",
"color": "base_70"
}
}
}
}
},
"howto": {
"type": "link",
"properties": {
"text": "Как это работает?",
"action": {
"type": "openRestApp",
"value": "howto"
}
}
}
}
}
}!section
Пример с одним блоком без изображения:
{
"type": "section",
"properties": {
"type": "danger",
"blocks": {
"erroMessage": {
"type": "text",
"properties": {
"value": "Произошла ошибка. Попробуйте еще раз.",
"color": "danger"
}
}
}
}
}!section2
ButtonDto {#buttondto}
Кнопка в нижней части интерфейса.
Названиетип | Описание |
|---|---|
titlestring | Текст кнопки |
statestring | Состояние. Доступные значения: — normal — по умолчанию,— disabled |
Действия с кнопкой ActionDto {#actiondto}
Действие определяет реакцию на клик по определенному элементу. Доступные виды действий:
- переход по ссылке,
- JS событие,
- открытие слайдера приложения.
##### Переход по ссылке {#click}
Переход по ссылке возможен в двух вариантах:
- слайдер, если это относительная ссылка на стандартные объекты Битрикс24, поддерживающие работу в слайдере,
- обычный переход по ссылке в остальных случаях.
Названиетип | Описание |
|---|---|
typeconst | Тип действия. Должно иметь значение redirect |
valuestring | URI ссылки. Например: https://ya.ru или /crm/deal/details/1/ для объектов Битрикс24 |
{
"type": "redirect",
"value": "/crm/deal/details/1/"
}##### JS событие {#js}
Названиетип | Описание |
|---|---|
typeconst | Тип действия. Должно иметь значение layoutEvent |
valuestring | Идентификатор события. Например: doSomething или start_processing |
{
"type": "layoutEvent",
"value": "clicked"
}Вызов действия вызывает обработчик, который зарегистрирован через BX24.placement.call('bindLayoutEventCallback', null, Callback) или BX24.placement.call('bindLayoutEventCallback', 'id блока', Callback).
В обработчик будет передано value действия и id блока, который вызвал действие: {id: "myLink", value: "clicked"}.
##### Открытие слайдера приложения {#slider}
Вызов действия откроет слайдер приложения, зарегистрировавшего встройку. В слайдер будет передан контекст:
entityTypeIdидентификатор типа объекта, к которому привязано дело,entityIdидентификатор элемента.
Названиетип | Описание |
|---|---|
typeconst | Тип действия. Должно иметь значение openRestApp |
valuearray | Массив произвольного формата, данные из которого будут переданы в слайдер приложения |
sliderParamsActionSliderParamsDto | Параметры открытия слайдера |
###### ActionSliderParamsDto {#actionsliderparamsdto}
Названиетип | Описание |
|---|---|
widthint | Ширина слайдера, px. Не может быть использовано одновременно с leftBoundary |
leftBoundaryint | Слайдер во всю ширину окна браузера с отступом слева, px. Не может быть использовано одновременно с width |
titlestring | Текст заголовка окна браузера при открытии слайдера |
{
"type": "openRestApp",
"value": {
"myId": 123,
"someImportant": "qwerty"
},
"sliderParams": {
"title": "Это заголовок слайдера приложения",
"width": 700
}
}Примеры LayoutDto
{
"blocks": {
"section1": {
"type": "section",
"properties": {
"type": "withBorder",
"imageSrc": "https://www.1c-bitrix.ru/images/content_ru/products/box/bus.png",
"blocks": {
"header": {
"type": "text",
"properties": {
"value": " Отправьте клиенту ссылку на встречу",
"size": "xl",
"color": "base_90"
}
},
"notes": {
"type": "list",
"properties": {
"blocks": {
"li1": {"type": "text", "properties": {"value": "Клиент сам выберет удобный слот", "color": "base_70"}},
"li2": {"type": "text", "properties": {"value": "Встреча появится у вас в делах", "color": "base_70"}}
}
}
},
"howto": {
"type": "link",
"properties": {"text": "Как это работает?", "action": {"type": "openRestApp", "value": "howto"}}
}
}
}
},
"section2": {
"type": "section",
"properties": {
"type": "primary",
"blocks": {
"sectionText": {
"type": "lineOfBlocks",
"properties": {"blocks": {"block1": {"type": "text", "properties": {"value": "Если вы еще не пробовали генератор продаж, самое время испытать этот инструмент в действии", "color": "base_70"}}, "block2": {"type": "link", "properties": {"text": "Подробнее", "action": {"type": "redirect", "value": "/crm/"}}}}}
}
}
}
}
},
"primaryButton": {"title": "Включить"},
"secondaryButton": {"title": "Отмена"}
}!example1
{
"blocks": {
"errorMessage": {
"type": "text",
"properties": {"value": "Используйте все возможности мобильного СМС маркетинга\nОтправку СМС легко настроить и использовать в CRM Битрикс24\nОтправляйте сообщения прямо из карточки сделки, лида, клиента, счета или предложения.", "size": "sm", "color": "base_70", "multiline": true}
},
"section1": {
"type": "section",
"properties": {"type": "danger", "blocks": {"errorMessage": {"type": "text", "properties": {"value": "Произошла ошибка. Попробуйте еще раз", "color": "danger"}}}}
}
},
"primaryButton": {"title": "Включить", "state": "disabled"},
"secondaryButton": {"title": "Отмена", "state": "disabled"}
}!example2
{
"blocks": {
"name": {"type": "input", "properties": {"value": "Иван", "placeholder": "Введите имя", "title": "Имя"}},
"lastname": {"type": "input", "properties": {"value": "Иванов", "placeholder": "", "title": "Фамилия"}},
"secondname": {"type": "input", "properties": {"value": "", "placeholder": "Введите отчество", "title": "Отчество"}}
},
"primaryButton": {"title": "Сохранить"},
"secondaryButton": {"title": "Отмена"}
}!example3
- [](../placement-bind)
- [](../ui-interaction/index)
- [](../ui-interaction/crm-card)
- [](../../../settings/interactivity/index)
- [](./detail-activity)
💡 Экспертное мнение и рекомендации
Практические рекомендации:
- При написании кастомных компонентов для «Дополнительные возможности встройки CRM_XXX_DETAIL_ACTIVITY, CRM_DYNAMIC_XXX_…» всегда разделяйте бизнес-логику и представление (шаблон).
- Используйте отладку SQL-запросов через конструкцию
$wpdb->last_queryили стандартный трекер Битрикса, чтобы контролировать нагрузку.
Похожая задача в бизнесе?
Помогу автоматизировать процессы и внедрить ИИ
Меня зовут Андрей Горошко. Я Full-stack разработчик и эксперт по 1С-Битрикс. Настраиваю CRM Битрикс24, разрабатываю защищенные API и создаю умных ИИ-агентов для автоматизации рутины.
или на почту: gorandvas@yandex.ru