← Назад к справке

Модули

JS, CSS и контроллеры

Рабочая справка по подключению JS/CSS из локального модуля Bitrix и созданию своих AJAX-контроллеров.

Для фронта модуль обычно делает две вещи: подключает JS/CSS на нужных страницах и даёт контроллеры для AJAX-запросов.

JS и CSS

Публичные ресурсы модуля обычно копируются в /local/js и /local/css.

Куда класть файлы

/local/modules/test.example/install/
├── js/
│   └── app.js
└── css/
    └── app.css

При установке эти файлы можно скопировать в:

/local/js/test.example/app.js
/local/css/test.example/app.css

Подключить Asset

<?php

use Bitrix\Main\Page\Asset;

/**
 * Подключает JS и CSS модуля.
 */
function addModuleAssets(): void
{
    Asset::getInstance()->addCss('/local/css/test.example/app.css');
    Asset::getInstance()->addJs('/local/js/test.example/app.js');
}

addModuleAssets();

Пути передаются относительно корня сайта. Если файл лежит в модуле, но не скопирован в публичную папку, браузер его не загрузит.

Подключить из события

Частый вариант — зарегистрировать обработчик OnProlog или OnEpilog и подключать JS/CSS только на нужных страницах.

<?php

namespace test\Example\EventHandler;

use Bitrix\Main\Context;
use Bitrix\Main\Page\Asset;

class AssetHandler
{
    /**
     * Подключает ресурсы модуля на нужной странице.
     */
    public static function onProlog(): void
    {
        $request = Context::getCurrent()->getRequest();
        $request_uri = (string) $request->getRequestUri();

        if (strpos($request_uri, '/crm/deal/details/') === false) {
            return;
        }

        Asset::getInstance()->addCss('/local/css/test.example/app.css');
        Asset::getInstance()->addJs('/local/js/test.example/app.js');
    }
}

Контроллеры

Контроллер модуля — удобная точка для AJAX-запросов из JS без отдельных файлов ajax.php.

Структура контроллера

Контроллер наследуется от Bitrix\Main\Engine\Controller. Действие — это публичный метод с суффиксом Action.

<?php

namespace test\Example\Controller;

use Bitrix\Main\Engine\Controller;
use Bitrix\Main\Loader;

class Deal extends Controller
{
    /**
     * Возвращает тестовые данные сделки.
     */
    public function getAction(int $deal_id): array
    {
        Loader::includeModule('crm');

        return [
            'deal_id' => $deal_id,
            'message' => 'Контроллер работает',
        ];
    }
}

Если namespace зарегистрирован в автозагрузке, контроллер можно вызывать через BX.ajax.runAction().

configureActions

Через configureActions() можно настроить фильтры действия: авторизацию, CSRF, HTTP-метод и другие проверки.

<?php

namespace test\Example\Controller;

use Bitrix\Main\Engine\ActionFilter;
use Bitrix\Main\Engine\Controller;

class Deal extends Controller
{
    /**
     * Настраивает фильтры действий.
     */
    public function configureActions(): array
    {
        return [
            'get' => [
                'prefilters' => [
                    new ActionFilter\Authentication(),
                    new ActionFilter\HttpMethod([
                        ActionFilter\HttpMethod::METHOD_POST,
                    ]),
                    new ActionFilter\Csrf(),
                ],
            ],
        ];
    }

    /**
     * Возвращает данные сделки.
     */
    public function getAction(int $deal_id): array
    {
        return [
            'deal_id' => $deal_id,
        ];
    }
}

Не отключай CSRF и авторизацию без необходимости. Для публичных действий лучше явно понимать, кто и откуда может вызвать контроллер.

Вызов из JS

Имя действия модуля строится по схеме vendor:module.Controller.action. Для модуля test.example и контроллера test\Example\Controller\Deal это может быть: test:example.Deal.get.

BX.ajax.runAction('test:example.Deal.get', {
    data: {
        deal_id: 123
    }
}).then(function (response) {
    console.log(response.data);
}).catch(function (response) {
    console.error(response.errors);
});

Если видишь ошибку про отсутствие конфигурации контроллеров, проверь namespace, автозагрузку, версию главного модуля и правильность имени действия.

Источники