Development of an administrative interface for 1C-Bitrix mass operations

Our company is engaged in the development, support and maintenance of Bitrix and Bitrix24 solutions of any complexity. From simple one-page sites to complex online stores, CRM systems with 1C and telephony integration. The experience of developers is confirmed by certificates from the vendor.
Our competencies:
Development stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    815
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Development based on Bitrix, Bitrix24, 1C for the company Development of an Online Appointment Booking Widget for a Medical Center
    565
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Development based on 1C Enterprise for MIRSANBEL
    747
  • image_crm_dolbimby_434_0.webp
    Website development on CRM Bitrix24 for DOLBIMBY
    657
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    980

Developing Admin Interface for Bulk Operations in 1C-Bitrix

A manager selects 200 products in Bitrix's standard list, clicks "Actions" — and sees only five options: activate, deactivate, delete, change section, export. No custom operations. Add them through admin interface extension.

Bitrix Admin Page Architecture

The admin product list is built by the bitrix:iblock.admin.element.list component in /bitrix/modules/iblock/admin/. To add custom actions on selections, no need to edit system files — there's an extension mechanism via admin menu-file and custom handler.

Custom admin page is placed in /bitrix/admin/my_bulk_action.php. It receives ID list via $_REQUEST['ID'][] — Bitrix standard for passing selected elements from lists.

Adding to Actions Menu

Standard iblock list supports adding buttons via module's admin_action.php or JavaScript injection. Cleaner way — register custom action via CAdminContextMenu:

// In /bitrix/admin/my_module_actions.php
// Included via /bitrix/php_interface/init.php

AddEventHandler('main', 'OnAdminListDisplay', function() {
    global $APPLICATION;
    $page = $APPLICATION->GetCurPage();

    // Add button only on element list page for needed iblock
    if (strpos($page, 'iblock_list_admin.php') !== false
        && (int)$_GET['IBLOCK_ID'] === MY_CATALOG_IBLOCK_ID)
    {
        // Registration not done via event — use JS
    }
});

Practically, add button via JavaScript injected at page bottom via $APPLICATION->AddHeadScript() or file in /bitrix/admin/.

JavaScript to add button:

document.addEventListener('DOMContentLoaded', function () {
    var toolbar = document.querySelector('.adm-toolbar-panel');
    if (!toolbar) return;

    var btn = document.createElement('input');
    btn.type = 'button';
    btn.value = 'Update Prices';
    btn.className = 'adm-btn';
    btn.addEventListener('click', function () {
        var form   = document.getElementById('list_form');
        var action = document.createElement('input');
        action.type  = 'hidden';
        action.name  = 'action';
        action.value = 'bulk_price_update';

        var target  = document.createElement('input');
        target.type  = 'hidden';
        target.name  = 'target_url';
        target.value = '/bitrix/admin/my_bulk_price_update.php';

        form.appendChild(action);
        form.appendChild(target);
        form.submit();
    });

    toolbar.appendChild(btn);
});

Bulk Operation Handler

File /bitrix/admin/my_bulk_price_update.php — processing page:

<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_admin_before.php';

$APPLICATION->SetTitle('Bulk Price Update');

// Check permissions
if (!\Bitrix\Main\Engine\CurrentUser::get()->isAdmin()) {
    die('Access denied');
}

$ids = array_map('intval', (array)$_REQUEST['ID']);
$ids = array_filter($ids);

require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_admin_after.php';

if (!empty($ids) && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['confirm'])) {
    // Execute operation
    $markup = (float)$_POST['markup'];

    foreach (array_chunk($ids, 50) as $chunk) {
        foreach ($chunk as $id) {
            $purchase = getPurchasePrice($id);
            if ($purchase > 0) {
                updateRetailPrice($id, $purchase * (1 + $markup / 100));
            }
        }
    }

    LocalRedirect('/bitrix/admin/iblock_list_admin.php?IBLOCK_ID=' . MY_CATALOG_IBLOCK_ID . '&lang=en');
}
?>

<!-- Confirmation form -->
<form method="post" action="">
    <p>Selected items: <b><?= count($ids) ?></b></p>
    <label>Markup (%):
        <input type="number" name="markup" value="40" min="0" max="500">
    </label>
    <?php foreach ($ids as $id): ?>
        <input type="hidden" name="ID[]" value="<?= $id ?>">
    <?php endforeach; ?>
    <input type="hidden" name="confirm" value="Y">
    <?= bitrix_sessid_post() ?>
    <input type="submit" value="Update" class="adm-btn-green">
    <a href="javascript:history.back()" class="adm-btn">Cancel</a>
</form>

<?php require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_admin.php'; ?>

Progress Bar for Long Operations

For 1000+ element updates, need progress indicator. Bitrix implements via CAdminProgress or AJAX polling.

AJAX pattern: operation splits into steps, each step — AJAX request, processes batch, returns {processed: N, total: M}. JavaScript updates progress bar and runs next step. Queue saving between steps — via $_SESSION or b_option by temp key.

Access Control

Each bulk operation handler checks:

  1. CSRF token via check_bitrix_sessid().
  2. User permissions via \Bitrix\Main\Engine\CurrentUser::get()->isAdmin() or \Bitrix\Main\Access.
  3. Passed ID ownership to expected iblock — protects against foreign ID substitution.