Диалог выбора товаров — это стандартный всплывающий компонент админки 1С-Битрикс, через который редактор ищет и привязывает элементы инфоблока к скидкам, наборам, подпискам и любым кастомным сущностям. Понимание его механики экономит десятки часов на самописных формах: почти всегда достаточно вызвать готовый диалог платформы, а не рисовать свой.
Что такое диалог выбора и где он живёт
Когда в карточке скидки, набора товаров или SKU вы нажимаете «Добавить товар» и получаете всплывающее окно с поиском и деревом каталога — это и есть диалог выбора товаров. Технически он строится на классе CAdminDialog из главного модуля и на публичном компоненте выбора элементов инфоблока, который открывается в iframe поверх текущей страницы.
Ключевые файлы платформы, к которым сводится вся механика:
/bitrix/js/main/core/core_admin_dialog.js— клиентская часть попапа;/bitrix/components/bitrix/catalog.product.search/— компонент поиска товаров;/bitrix/admin/cat_product_search.php— страница-эндпоинт, которую диалог грузит в iframe;iblock.section.searchиCIBlockFindTools— навигация по разделам каталога.
Из коробки этот механизм задействован в модулях catalog (скидки, наборы, товарные подборки) и sale. Ваша задача как разработчика — переиспользовать его, а не дублировать.
CAdminDialog: как открыть попап
Базовый способ показать всплывающее окно из админской страницы — объект BX.CAdminDialog. Он умеет грузить контент из URL (iframe) или из готовой HTML-строки, задавать заголовок, размеры и набор кнопок.
Минимальный вызов через iframe выглядит так:
var oDialog = new BX.CAdminDialog({ title: 'Выбор товара', content_url: '/bitrix/admin/cat_product_search.php?lang=ru&n=FORM_NAME&k=', width: 750, height: 550 }); oDialog.Show();
Параметры, которые встречаются чаще всего:
n— имя формы или префикс полей, куда диалог вернёт результат;k— идентификатор строки/ключ, если товары добавляются в табличный список;IBLOCK_ID— ограничение выбора конкретным инфоблоком;caller— метка вызывающей стороны, чтобы серверная часть знала, какой формат ответа отдать.
CJSCore::Init(array('admin_dialog')) — без этого объект BX.CAdminDialog в браузере будет недоступен.Поиск и фильтр внутри диалога
Компонент catalog.product.search отдаёт не просто список, а полноценный интерфейс поиска: строка по названию и артикулу, дерево разделов каталога, постраничная навигация и предпросмотр цены с остатком. Поиск идёт по полю NAME, символьному коду и внешнему коду XML_ID, а также по значениям торговых предложений.
Поведение фильтра управляется параметрами компонента:
| Параметр | Назначение |
|---|---|
IBLOCK_ID | Инфоблок, в котором ищем товары |
SEARCH | Предзаполненная поисковая строка |
SHOW_SKU | Показывать ли торговые предложения (SKU) |
SEF_MODE | ЧПУ-режим для ссылок внутри диалога |
Если каталог большой, полезно заранее ограничить выбор нужным разделом через параметр SECTION_ID — это снижает нагрузку и убирает лишний «шум» для контент-менеджера.
Как вернуть выбранный товар в форму
Диалог грузится в iframe, поэтому результат передаётся в родительское окно через JavaScript. Стандартный компонент вызывает функцию-колбэк из window.top или напрямую пишет значения в поля формы по имени, переданному в параметре n.
Типовой сценарий: определяете в родительском окне функцию, которая примет ID и название товара, а в вызове диалога указываете её имя. При клике по товару компонент выполнит примерно такой код:
window.opener.SelProduct(productId, productName, '');
или, в терминах iframe, — window.parent.myCallback(id, name);. Внутри своего колбэка вы:
- подставляете
IDв скрытое поле формы; - выводите название рядом для наглядности;
- вызываете
oDialog.Close()(илиBX.WindowManager.Get().Close()), чтобы закрыть попап.
window.parent либо window.opener. Перепутанный контекст — самая частая причина «молчаливого» диалога, который ничего не возвращает.Привязка товаров к скидкам, наборам и подпискам
На практике диалог почти всегда обслуживает связь «многие ко многим»: одной скидке или набору соответствует список товаров. Стандартные механизмы Битрикса хранят эти связи по-разному, и это важно учитывать в кастомной логике:
- Скидки на товары — условия каталожной скидки описываются деревом правил (класс
CCatalogDiscount), где список ID товаров попадает в условие типа «товар входит в набор ID». - Наборы и комплекты — таблица
b_catalog_product_sets, работа черезCCatalogProductSet. - Собственные сущности (подписки, подборки) — как правило, отдельная таблица через ORM
Bitrix\Main\Entity, где вы сами храните парыENTITY_ID + PRODUCT_ID.
Диалог здесь отвечает только за пользовательский выбор ID. Сохранение связи — уже ваш серверный обработчик формы: он принимает массив выбранных PRODUCT_ID из POST, валидирует их через CIBlockElement::GetList и пишет в нужную таблицу.
Использование в кастомных формах
Когда вы делаете собственную админскую страницу (например, «Товары подписки»), диалог подключается в несколько шагов. Ниже — рабочая последовательность, которую мы применяем на проектах:
- В шапке страницы вызвать
CJSCore::Init(array('admin_dialog'))и подключитьcore_admin_dialog.js. - В форме разместить скрытое поле-список выбранных ID и видимую таблицу через
CAdminListили простой<table>. - По кнопке «Добавить товар» открыть
new BX.CAdminDialog(...)сcontent_urlнаcat_product_search.phpи уникальным именем формы в параметреn. - Определить JS-колбэк, который добавит строку в таблицу и допишет ID в скрытое поле.
- В обработчике
$_SERVER['REQUEST_METHOD'] == 'POST'сохранить массив ID в вашу сущность.
Если своя таблица избыточна, для простых случаев подойдёт готовый input с кнопкой из хелпера CAdminDialogChain либо стандартный контрол «привязка к элементу инфоблока» из свойств инфоблока (тип свойства E — «Привязка к элементам»), у которого попап выбора работает из коробки без единой строки JS.
Итог
Диалог выбора товаров в админке — это не магия, а связка CAdminDialog, компонента catalog.product.search и вашего JS-колбэка, возвращающего ID в форму. Переиспользование штатного попапа надёжнее и дешевле любого самописного, а для типовых задач часто хватает свойства инфоблока типа «Привязка к элементам».
Если нужно встроить выбор товаров в нестандартную форму, связать его со скидками, наборами или подписками и при этом не сломать обмен с 1С — мы в B2Bsite проектируем такие интерфейсы под конкретную бизнес-логику магазина, аккуратно вписываясь в стандарты платформы.
Частые вопросы
Какой класс отвечает за всплывающий диалог в админке Битрикса?
Клиентский объект BX.CAdminDialog из главного модуля. Он открывает попап с контентом из URL (iframe) или из готовой HTML-строки и управляет кнопками и размерами окна.
Как подключить ядро диалога на своей странице?
Вызовите CJSCore::Init(array('admin_dialog')) в шапке страницы. Без инициализации расширения admin_dialog объект BX.CAdminDialog в браузере будет недоступен.
Какой компонент ищет товары внутри диалога?
Штатный catalog.product.search, который открывается через страницу /bitrix/admin/cat_product_search.php. Он даёт поиск по названию и артикулу, дерево разделов и предпросмотр цены с остатком.
Как выбранный товар попадает обратно в форму?
Через JavaScript-колбэк в родительском окне: компонент вызывает вашу функцию и передаёт ID и название товара. Обращаться к родителю нужно через window.parent для iframe или window.opener для отдельного окна.
Можно ли ограничить выбор одним инфоблоком или разделом?
Да. Передайте параметр IBLOCK_ID, чтобы искать только в нужном каталоге, и SECTION_ID, чтобы сузить выбор до конкретного раздела. Это ускоряет диалог на больших каталогах.
Нужно ли писать свой попап для привязки товаров к скидке?
Обычно нет. Диалог отвечает только за выбор ID, а сохранение связи делает ваш серверный обработчик. Для простых форм подойдёт свойство инфоблока типа «Привязка к элементам», где попап работает без кода.
Где хранятся связи товаров с наборами и скидками?
Наборы — в таблице b_catalog_product_sets через CCatalogProductSet, условия скидок — в правилах CCatalogDiscount. Для собственных сущностей вроде подписок связь обычно хранят в отдельной ORM-таблице.
Почему диалог открывается, но ничего не возвращает?
Чаще всего перепутан контекст окна: для iframe нужен window.parent, а не window.opener. Также проверьте, что имя колбэка совпадает с параметром n и что функция объявлена в родительском окне.
Поможем с настройкой и поддержкой 1С-Битрикс: Управление сайтом
Поможем с настройкой, доработкой и поддержкой 1С-Битрикс: Управление сайтом.