Setting up 1C-Bitrix form field validation

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

Form Field Validation Setup in 1C-Bitrix

Form accepts phone number in any format: "80291234567", "+375-29-123-45-67", "029 123 45 67" — all saved as-is. Three months later manager looks at 2000 records with numbers in ten different formats and can't export them to CRM.

Built-in Form Module Validation

Module form supports basic validation at field level via parameters in b_form_field: REQUIRED field (Y/N), CHECK_FILTER — regex for value check, FILTER_MEMO — error message.

API editing:

\CFormField::Update($fieldId, $formId, [
    'REQUIRED'     => 'Y',
    'CHECK_FILTER' => '^\\+375[0-9]{9}$',
    'FILTER_MEMO'  => 'Enter phone in format +375XXXXXXXXX',
]);

CHECK_FILTER checked on server when saving result. Client-side validation not supported by standard module — server-only.

Client-side Validation via JavaScript

For immediate feedback, client validation added to bitrix:form.result.new template. Handler subscribes to form submit event:

document.getElementById('form_<?= $arResult['FORM']['SID'] ?>').addEventListener('submit', function (e) {
    var errors = [];

    // Phone
    var phone = document.getElementById('field_PHONE').value.replace(/\D/g, '');
    if (!/^375\d{9}$/.test(phone)) {
        errors.push('Phone: enter number in format +375XXXXXXXXX');
        document.getElementById('field_PHONE').classList.add('error');
    }

    // Email
    var email = document.getElementById('field_EMAIL').value;
    if (email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
        errors.push('Email: invalid address format');
        document.getElementById('field_EMAIL').classList.add('error');
    }

    if (errors.length > 0) {
        e.preventDefault();
        document.getElementById('form_errors').innerHTML = errors.join('<br>');
    }
});

Normalization Before Saving

Validation without normalization is half a solution. Phone must not only be checked but standardized. Event handler OnBeforeResultAdd:

AddEventHandler('form', 'OnBeforeResultAdd', function($formId, &$arFields) {
    if (isset($arFields['form_field_PHONE'])) {
        $phone = preg_replace('/\D/', '', $arFields['form_field_PHONE']);

        // Normalize: 80291234567 → 375291234567
        if (strlen($phone) === 11 && $phone[0] === '8') {
            $phone = '375' . substr($phone, 2);
        }
        if (strlen($phone) === 9) {
            $phone = '375' . $phone;
        }

        if (strlen($phone) === 12 && str_starts_with($phone, '375')) {
            $arFields['form_field_PHONE'] = '+' . $phone;
        } else {
            // Return error
            global $APPLICATION;
            $APPLICATION->ThrowException('Invalid phone format');
            return false;
        }
    }
});

Validation with Input Mask

Input mask prevents incorrect format during entry. IMask.js library integrated in component template:

IMask(document.getElementById('field_PHONE'), {
    mask: '+{375} (00) 000-00-00',
});

After mask, user physically can't enter letter in phone field. Reduces server validation load but doesn't replace it — data can come via direct POST request bypassing form.

Spam Protection

Standard Bitrix CAPTCHA connected via component parameter USE_CAPTCHA. For Web Forms — captcha field type in b_form_field. Alternative — Google reCAPTCHA v3 via OnBeforeResultAdd handler: on low reCAPTCHA score form rejected without showing error to user (honeypot approach for bots).

Server-side reCAPTCHA v3 check:

$token = $_POST['g-recaptcha-response'];
$response = file_get_contents(
    'https://www.google.com/recaptcha/api/siteverify?secret=SECRET&response=' . $token
);
$data = json_decode($response, true);
if ($data['score'] < 0.5) {
    return false; // Silently reject
}