Calculator development on the 1C-Bitrix website

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
    1175
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Website development for FIXPER company
    811
  • 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
    564
  • 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
    655
  • image_crm_technotorgcomplex_453_0.webp
    Development based on Bitrix24 for the company TECHNOTORGKOMPLEKS
    976

Development of Calculators on a 1C-Bitrix Website

A calculator on a website is one of the few interactive elements that directly affects conversion. The user enters parameters, sees the total price or result, and makes a decision right there without leaving for email or a messenger. The typical problem: standard 1C-Bitrix forms cannot calculate in real time, and off-the-shelf plugins do not cover business-specific logic.

Approaches to implementing calculators on Bitrix

On 1C-Bitrix, calculators are implemented in three ways, each with its own area of application:

1. Component with AJAX calls to PHP logic

The classic approach for complex calculations where the logic must stay on the server (current prices from the database, discounts, integration with 1C). The component lives in bitrix/components/vendor/calculator/, and the template sends AJAX to $APPLICATION->IncludeComponent or to a dedicated ajax.php.

2. JavaScript calculator with server-side validation

Calculation directly in the browser for instant response, with final validation on the server when the form is submitted. Suitable for most price calculators where the data is static (rates, coefficients).

3. Bitrix Form Builder + custom JS

A quick option for simple cases: a standard Bitrix form with an added JavaScript handler. Does not scale, but can be launched in 1 day.

Calculator component architecture

Structure of a custom component:

/bitrix/components/custom/calculator/
  component.php      # Main component logic
  .parameters.php    # Parameters for admin panel configuration
  templates/
    .default/
      template.php   # HTML template
      script.js      # JS calculation logic
      style.css

The component.php file is the heart of the component. This is where the calculator data is loaded:

<?php
if (!defined('B_PROLOG_INCLUDED') || B_PROLOG_INCLUDED !== true) die();

class CustomCalculatorComponent extends CBitrixComponent
{
    public function executeComponent()
    {
        // Load rates from an info block
        $arFilter = [
            'IBLOCK_ID' => $this->arParams['RATES_IBLOCK_ID'],
            'ACTIVE' => 'Y',
        ];

        $rsRates = CIBlockElement::GetList(
            ['SORT' => 'ASC'],
            $arFilter,
            false,
            false,
            ['ID', 'NAME', 'PROPERTY_*']
        );

        $this->arResult['RATES'] = [];
        while ($arRate = $rsRates->GetNext()) {
            $this->arResult['RATES'][] = $arRate;
        }

        // Pass data to the template via JSON for JS
        $this->arResult['RATES_JSON'] = json_encode(
            $this->arResult['RATES'],
            JSON_UNESCAPED_UNICODE
        );

        $this->includeComponentTemplate();
    }
}

In the template, data is passed to JavaScript:

// template.php
<script>
const CALCULATOR_DATA = <?= $arResult['RATES_JSON'] ?>;
</script>

AJAX handling for server-side calculations

If the calculation cannot be done on the client (dynamic prices, stock availability check), use AJAX:

// ajax.php in the component folder
define('STOP_STATISTICS', true);
define('NO_KEEP_STATISTIC', 'Y');
define('DisableEventsCheck', true);

require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php');

if (!check_bitrix_sessid()) {
    echo json_encode(['error' => 'Invalid session']);
    die();
}

$action = $_POST['action'] ?? '';

if ($action === 'calculate') {
    $params = json_decode(file_get_contents('php://input'), true);

    // Calculation logic
    $result = calculatePrice($params);

    header('Content-Type: application/json');
    echo json_encode(['success' => true, 'data' => $result]);
}

require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/epilog_after.php');

Call from JavaScript:

async function calculate(params) {
    const response = await fetch('/bitrix/components/custom/calculator/ajax.php', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            action: 'calculate',
            sessid: BX.bitrix_sessid(), // Bitrix CSRF token
            ...params
        })
    });
    return response.json();
}

Saving a request from the calculator

The calculation result usually needs to be attached to a request. Options:

  1. Standard feedback form (bitrix:form.result.new) — calculator results are passed via hidden fields
  2. Creating a lead/deal in CRM — via CCrmLead::Add() or the REST API if it needs to go directly into the funnel
  3. Writing to an info block — for storing calculation history
// Creating a lead with calculator data
use Bitrix\Crm;

$leadData = [
    'TITLE' => 'Calculator request: ' . $calcTitle,
    'NAME' => $arFields['name'],
    'PHONE' => [['VALUE' => $arFields['phone'], 'VALUE_TYPE' => 'WORK']],
    'COMMENTS' => 'Calculation parameters: ' . json_encode($calcParams),
    'UF_CRM_CALC_RESULT' => $calcResult,
];

$leadId = CCrmLead::Add($leadData, true, ['REGISTER_SONET_EVENT' => false]);

Caching calculator data

If the calculator fetches data from info blocks or external sources, caching is important:

$cacheTime = 3600; // 1 hour
$cache = Bitrix\Main\Data\Cache::createInstance();

if ($cache->initCache($cacheTime, 'calculator_rates_' . $iblockId, '/calculator/')) {
    $arRates = $cache->getVars();
} elseif ($cache->startDataCache()) {
    $arRates = loadRatesFromIblock($iblockId);
    $cache->endDataCache($arRates);
}

Development timelines

Calculator type Complexity Timeline
Simple (2–5 fields, JS) S 2–4 days
Medium (6–15 fields, conditional logic) M 1–2 weeks
Complex (dynamic data, 1C integration) L 3–5 weeks
Multi-step with CRM save XL 4–8 weeks

The most time-consuming part is not the calculation logic itself, but formalizing the business rules: clients often lack a ready specification, and working it out takes as long as the actual development.