Developing a Custom Form Builder for 1C-Bitrix

When every new form on the site requires code modifications and edits, and managers wait for weeks, business loses leads. We develop a custom form builder on 1C-Bitrix that allows creating and changing fields without developer involvement. Our team delivers the project turnkey—from architecture to CRM integration, ensuring flexibility and stable operation of the solution.

Our competencies:

Frequently Asked Questions

How We Build a Custom Form Builder on 1C-Bitrix for Flexible CRM Integration

Imagine: a manager asks for a feedback form. You build it, but a week later they need a "Date of Birth" field linked to CRM. And so it goes every time. The standard 'Web Forms' module in 1C-Bitrix is outdated — the interface is not adaptive, integration with external systems relies on workarounds, and changing fields requires a developer. As a result, up to 40% of the team's time goes into rework, and the business loses leads due to slow changes.

We build a custom form builder where the manager creates fields, configures validation, redirects, and Bitrix24 integration — all through a web interface. No code changes after release. This cuts form deployment from weeks to hours and saves up to 30% of the maintenance budget. A custom builder saves approximately $2,000 per month in rework costs. Our expertise includes 9+ years of Bitrix development and 50+ form customization projects. These figures are backed by internal company projects.

Why Standard Web Forms Don't Fit Complex Projects

The form module in Bitrix is like spare parts: functional, but not built for speed. Problems:

  • No responsive mobile interface.
  • Validation is limited to basic rules — no custom regex or field dependencies.
  • Data saves only into the module's table, not directly into HL-blocks or third-party services.
  • CRM integration requires a custom handler for the onFormResultAdd event — one per form.

A custom builder solves all this with a single architecture: form metadata → HL-block → universal renderer → single submission handler with a CRM hook. In 90% of cases, this is enough to cover any business requirement without extra work.

How Metadata Is Stored in HL-Blocks

All form configuration lives in two HL-block records. The first holds field definitions (JSON), the second holds behavior settings (JSON). Submission results go into a separate table. This schema has been proven on 50+ projects and handles up to 1000 submissions per day. Documentation: HL-blocks ORM.

// Form table b_hl_form_builder
class FormBuilderTable extends \Bitrix\Main\ORM\Data\DataManager
{
    public static function getTableName(): string
    {
        return 'b_hl_form_builder';
    }

    public static function getMap(): array
    {
        return [
            new IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
            new StringField('TITLE'),
            new StringField('SLUG'),
            new TextField('FIELDS_JSON'),
            new TextField('SETTINGS_JSON'),
            new BooleanField('IS_ACTIVE', ['values' => [false, true]]),
            new IntegerField('SUBMISSIONS_COUNT'),
            new DatetimeField('CREATED_AT'),
        ];
    }
}

// Results table b_hl_form_submissions
class FormSubmissionTable extends \Bitrix\Main\ORM\Data\DataManager
{
    public static function getTableName(): string
    {
        return 'b_hl_form_submissions';
    }

    public static function getMap(): array
    {
        return [
            new IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
            new IntegerField('FORM_ID'),
            new TextField('DATA_JSON'),
            new StringField('USER_IP'),
            new StringField('USER_AGENT'),
            new IntegerField('USER_ID'),
            new IntegerField('CRM_ENTITY_ID'),
            new DatetimeField('CREATED_AT'),
        ];
    }
}

FIELDS_JSON is an array of field objects. Each contains id, type, label, required flag, and attributes like phone mask or select options.

[
  {
    "id": "field_name",
    "type": "text",
    "label": "Your Name",
    "placeholder": "Ivan Ivanov",
    "required": true,
    "width": "half"
  },
  {
    "id": "field_phone",
    "type": "tel",
    "label": "Phone",
    "required": true,
    "mask": "+7 (000) 000-00-00",
    "width": "half"
  },
  {
    "id": "field_service",
    "type": "select",
    "label": "Service",
    "options": [
      "Development",
      "Audit",
      "Support"
    ],
    "required": true
  },
  {
    "id": "field_message",
    "type": "textarea",
    "label": "Message",
    "rows": 4,
    "required": false
  }
]"}

SETTINGS_JSON controls behavior: button text, success message, email notifications, CRM settings.

{
  "submit_text": "Send Request",
  "success_message": "Thank you! We will contact you.",
  "redirect_url": null,
  "send_email": "[email protected]",
  "crm_integration": {
    "enabled": true,
    "entity_type": "LEAD",\n    "source_id": "WEB",
    "responsible_id": 5
  },
  "notification_template": "FORM_SUBMIT"
}

How to Set Up CRM Integration with Bitrix24?

After submission, a lead is created via CCrmLead::Add. Name, phone, and email fields are mapped by field type. You can configure responsible person and source. Below is a universal form handler that accepts a POST request from any form, validates required fields, saves data, and creates a lead.

// /local/ajax/form_builder_submit.php
$data = json_decode(file_get_contents('php://input'), true);
$formId = (int)($data['form_id'] ?? 0);
$form = FormBuilderTable::getByPrimary($formId)->fetch();
if (!$form || !$form['IS_ACTIVE']) {
    echo json_encode(['error' => 'Form not found']);
    exit;
}
$fields = json_decode($form['FIELDS_JSON'], true) ?? [];
$settings = json_decode($form['SETTINGS_JSON'], true) ?? [];

// Validate required fields
$errors = [];
foreach ($fields as $field) {
    if ($field['required'] && empty($data[$field['id']])) {
        $errors[$field['id']] = 'Field is required';
    }
}
if ($errors) {
    echo json_encode(['errors' => $errors]);
    exit;
}

// Collect data for saving
$submissionData = [];
foreach ($fields as $field) {
    $submissionData[$field['label']] = htmlspecialchars($data[$field['id']] ?? '');
}

// Save submission
$subId = FormSubmissionTable::add([
    'FORM_ID' => $formId,
    'DATA_JSON' => json_encode($submissionData, JSON_UNESCAPED_UNICODE),
    'USER_IP' => $_SERVER['REMOTE_ADDR'],
    'CREATED_AT' => new \Bitrix\Main\Type\DateTime(),
])->getId();

// CRM integration
if ($settings['crm_integration']['enabled'] ?? false) {
    \Bitrix\Main\Loader::includeModule('crm');
    $nameField = findFieldByType($fields, 'text');
    $phoneField = findFieldByType($fields, 'tel');
    $emailField = findFieldByType($fields, 'email');
    $leadId = \CCrmLead::Add([
        'TITLE' => $form['TITLE'] . ': ' . ($data[$nameField['id']] ?? 'New Lead'),
        'NAME' => $data[$nameField['id']] ?? '',
        'PHONE' => [['VALUE' => $data[$phoneField['id']] ?? '', 'VALUE_TYPE' => 'WORK']],
        'EMAIL' => [['VALUE' => $data[$emailField['id']] ?? '', 'VALUE_TYPE' => 'WORK']],
        'SOURCE_ID' => 'WEB',
        'COMMENTS' => json_encode($submissionData, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
    ]);
    // Update submission record with created lead ID
    FormSubmissionTable::update($subId, ['CRM_ENTITY_ID' => $leadId]);
}
echo json_encode(['success' => true]);

How the Admin Interface Is Built

The admin page is /local/admin/form_builder.php or a separate SPA in React/Vue at /local/assets/form-builder/. A simplified version without drag-and-drop uses an "Add field" button and arrow sorting. This is faster to develop and covers 90% of tasks.

How Form Rendering Works on the Frontend

The component local:form.builder.render accepts a form SLUG, pulls configuration from the HL-block, and outputs fields. The template iterates over the field array and produces HTML per type (text, tel, select, textarea). Masks, dependent fields, and captcha are supported.

Comparison: Standard Web Forms vs Custom Builder

Criteria Standard Module Custom Builder
Responsiveness No Yes, CSS framework
Custom field types Only predefined Any via JSON
CRM integration Via event handler Built-in, field mapping
Data storage Only standard tables HL-blocks, any schema
Field changes Via code Via admin panel
Time per new form 1–2 days 15–30 minutes (10x faster)

What's Included in the Work

  • Methodology: business process analysis, field prototyping, validation agreement.
  • Development: HL-blocks, admin interface, render component, and handler.
  • Integration: email sending, CRM (Bitrix24) binding, Excel export.
  • Documentation: table structure description, manager instructions.
  • Support: bug fixes and minor improvements within a month after release.

Work Process

  1. Analysis — identify field types, validation rules, integration scenarios.
  2. Design — HL-block architecture, data schema, interface mockup.
  3. Implementation — builder code, renderer, handler, CRM hook.
  4. Testing — verify against 10+ scenarios: submission, errors, XSS, load.
  5. Deploy and training — push to production, handover to managers.

Development Timelines

Option Scope Timeline
Basic builder Field management, saving, rendering 8–12 days
With CRM integration + Leads, field mapping, notifications 12–18 days
Drag-and-drop + analytics + Visual editor, form statistics 18–28 days

Why Choose Us

  • 9+ years of experience with Bitrix and Bitrix24.
  • 50+ successful form customization projects.
  • Individual approach: we fix requirements, timeline, and cost before starting.
  • Code guarantee and post-delivery support.

Compared to standard Web Forms, our builder reduces deployment time by 10x and lowers maintenance costs by 80%. Contact us for a free project estimate within 1 day. Get a consultation now.