An AJAX Contact Form in 1C-Bitrix: Submit Without Reloading
A contact form on a 1C-Bitrix website can be submitted through AJAX without reloading the page, saving each enquiry in an information block and notifying the website administrator at the same time.
This approach suits callback requests, service enquiries, quotation requests and similar forms.
The resulting workflow is:
For example, name it:
Note the information block ID after creating it. You will need it in the PHP handler.
In the following examples, assume our information block ID is:
In the Bitrix admin panel, open the email events section and create a new type.
For example:
For example, the email body might look like this:
It can be placed directly on a page, in the website template or inside a modal window.
Example form:
The form also includes:
The JavaScript intercepts form submission and sends the data to the PHP handler:
Example handler:
The codes:
For example, the value:
Required checks must therefore also run on the server.
Back to blog
This approach suits callback requests, service enquiries, quotation requests and similar forms.
The resulting workflow is:
- The user fills in the form.
- JavaScript sends the data through AJAX.
- A PHP handler validates the data.
- The enquiry is saved in an information block.
- Bitrix creates an email event and sends a notification.
- The user sees a success message without the page reloading.
1. Create an Information Block for Enquiries
First, create a separate information block to store user enquiries.For example, name it:
Website Enquiries
Add the following properties to the information block:- NAME — the user's name;
- PHONE — phone number;
- EMAIL — email address;
- PAGE — the page from which the enquiry was sent.
Note the information block ID after creating it. You will need it in the PHP handler.
In the following examples, assume our information block ID is:
12
Replace it with your own information block ID in a real project.
2. Create an Email Event Type
Create an email event through which the administrator will receive new enquiry notifications.In the Bitrix admin panel, open the email events section and create a new type.
For example:
NEW_FEEDBACK
Define the following event fields:
#NAME# - Name
#PHONE# - Phone
#EMAIL# - Email
#MESSAGE# - Message
#PAGE# - Submission page
Then create an email template and link it to the event NEW_FEEDBACK.For example, the email body might look like this:
A new enquiry has been submitted on the website.
Name: #NAME#
Phone: #PHONE#
Email: #EMAIL#
Message:
#MESSAGE#
Page:
#PAGE#
In the recipient field, enter the address that should receive enquiries.
3. Add the HTML Form
Now create the form itself.It can be placed directly on a page, in the website template or inside a modal window.
Example form:
<form id="feedback-form">
<?=bitrix_sessid_post()?>
<div class="form-group">
<label for="feedback-name">Ваше имя</label>
<input
type="text"
name="name"
id="feedback-name"
class="form-control"
required
>
</div>
<div class="form-group">
<label for="feedback-phone">Телефон</label>
<input
type="text"
name="phone"
id="feedback-phone"
class="form-control"
required
>
</div>
<div class="form-group">
<label for="feedback-email">E-mail</label>
<input
type="email"
name="email"
id="feedback-email"
class="form-control"
>
</div>
<div class="form-group">
<label for="feedback-message">Сообщение</label>
<textarea
name="message"
id="feedback-message"
class="form-control"
rows="5"
></textarea>
</div>
<input
type="hidden"
name="page"
id="feedback-page"
value=""
>
<div class="form-group">
<label>
<input
type="checkbox"
name="agree"
value="Y"
required
>
Я согласен на обработку персональных данных
</label>
</div>
<div class="feedback-result"></div>
<button
type="submit"
class="feedback-submit"
>
Отправить
</button>
</form>
This uses the standard HTML attributes required and type="email", allowing the browser to perform basic form validation.The form also includes:
<?=bitrix_sessid_post()?>
This adds the Bitrix session identifier, which we will check on the server.
4. Submit the Form Through AJAX
This example uses jQuery, which is often already included in 1C-Bitrix projects.The JavaScript intercepts form submission and sends the data to the PHP handler:
$(document).on('submit', '#feedback-form', function(e) {
e.preventDefault();
var $form = $(this);
var $button = $form.find('.feedback-submit');
var $result = $form.find('.feedback-result');
$('#feedback-page').val(window.location.href);
$result
.removeClass('success error')
.html('');
$button.prop('disabled', true);
$.ajax({
url: '/local/ajax/feedback.php',
type: 'POST',
data: $form.serialize(),
dataType: 'json'
})
.done(function(response) {
if (response.status) {
$result
.addClass('success')
.html(response.message);
$form[0].reset();
} else {
$result
.addClass('error')
.html(response.message);
}
})
.fail(function() {
$result
.addClass('error')
.html('При отправке формы произошла ошибка. Попробуйте ещё раз.');
})
.always(function() {
$button.prop('disabled', false);
});
});
When the form is submitted:- Default form submission is prevented using preventDefault().
- The current page URL is written to a hidden field.
- The submit button is temporarily disabled.
- The form data is sent to the PHP file in a POST request.
- A JSON response is expected from the server.
- The form is cleared after successful submission.
- The result is displayed to the user.
5. Create the PHP Form Handler
Create the file:
/local/ajax/feedback.php
Load the Bitrix core and information block module, validate the data and create a new information block element.Example handler:
<?php
define('NO_KEEP_STATISTIC', true);
define('NO_AGENT_STATISTIC', true);
define('NOT_CHECK_PERMISSIONS', true);
require_once(
$_SERVER['DOCUMENT_ROOT']
. '/bitrix/modules/main/include/prolog_before.php'
);
use Bitrix\Main\Application;
use Bitrix\Main\Loader;
use Bitrix\Main\Mail\Event;
use Bitrix\Main\Web\Json;
header('Content-Type: application/json; charset=UTF-8');
$result = [
'status' => false,
'message' => ''
];
try {
if (!check_bitrix_sessid()) {
throw new RuntimeException(
'Сессия устарела. Обновите страницу и попробуйте ещё раз.'
);
}
if (!Loader::includeModule('iblock')) {
throw new RuntimeException(
'Не удалось подключить модуль информационных блоков.'
);
}
$request = Application::getInstance()
->getContext()
->getRequest();
$name = trim((string)$request->getPost('name'));
$phone = trim((string)$request->getPost('phone'));
$email = trim((string)$request->getPost('email'));
$message = trim((string)$request->getPost('message'));
$page = trim((string)$request->getPost('page'));
$agree = $request->getPost('agree');
if ($name === '') {
throw new RuntimeException(
'Укажите ваше имя.'
);
}
if ($phone === '') {
throw new RuntimeException(
'Укажите номер телефона.'
);
}
if (
$email !== ''
&& !filter_var($email, FILTER_VALIDATE_EMAIL)
) {
throw new RuntimeException(
'Укажите корректный e-mail.'
);
}
if ($agree !== 'Y') {
throw new RuntimeException(
'Необходимо подтвердить согласие на обработку персональных данных.'
);
}
$nameSafe = htmlspecialcharsbx($name);
$phoneSafe = htmlspecialcharsbx($phone);
$emailSafe = htmlspecialcharsbx($email);
$messageSafe = htmlspecialcharsbx($message);
$pageSafe = htmlspecialcharsbx($page);
$properties = [
'NAME' => $nameSafe,
'PHONE' => $phoneSafe,
'EMAIL' => $emailSafe,
'PAGE' => $pageSafe
];
$element = new CIBlockElement();
$elementId = $element->Add([
'IBLOCK_ID' => 12,
'ACTIVE' => 'Y',
'NAME' => 'Заявка от '
. $nameSafe
. ' '
. date('d.m.Y H:i:s'),
'PREVIEW_TEXT' => $messageSafe,
'PROPERTY_VALUES' => $properties
]);
if (!$elementId) {
throw new RuntimeException(
'Не удалось сохранить заявку: '
. $element->LAST_ERROR
);
}
Event::send([
'EVENT_NAME' => 'NEW_FEEDBACK',
'LID' => defined('SITE_ID') ? SITE_ID : 's1',
'C_FIELDS' => [
'NAME' => $nameSafe,
'PHONE' => $phoneSafe,
'EMAIL' => $emailSafe,
'MESSAGE' => $messageSafe,
'PAGE' => $pageSafe
]
]);
$result = [
'status' => true,
'message' => 'Спасибо! Ваша заявка отправлена.'
];
} catch (Throwable $e) {
$result = [
'status' => false,
'message' => $e->getMessage()
];
}
echo Json::encode($result);
die();
Pay attention to this line:
'IBLOCK_ID' => 12,
Specify the ID of the information block created to store enquiries.The codes:
NAME
PHONE
EMAIL
PAGE
must match the symbolic codes of your information block properties.
6. What Does the PHP Handler Do?
The handler performs the following steps:- Loads the 1C-Bitrix core.
- Checks the session identifier.
- Loads the module iblock.
- Retrieves POST request data.
- Validates required fields.
- Checks the email format.
- Checks the user's consent.
- Creates a new information block element.
- Triggers an email event.
- Returns the result to JavaScript as JSON.
status
If the enquiry is saved successfully, its value is:
true
On error, the response contains:
false
JavaScript uses this value to show the appropriate message.
7. Send an Email Notification
The following method sends the notification:
Bitrix\Main\Mail\Event::send()
It receives the code of the email event created earlier:
'EVENT_NAME' => 'NEW_FEEDBACK'
And the data array:
'C_FIELDS' => [
'NAME' => $nameSafe,
'PHONE' => $phoneSafe,
'EMAIL' => $emailSafe,
'MESSAGE' => $messageSafe,
'PAGE' => $pageSafe
]
The array keys must match the variables added to the email event type.For example, the value:
'PHONE' => $phoneSafe
is available in the email template as:
#PHONE#
8. Style the Submission Result
Add simple styles for success and error messages:
.feedback-result {
margin: 15px 0;
}
.feedback-result.success {
color: #198754;
}
.feedback-result.error {
color: #dc3545;
}
.feedback-submit:disabled {
opacity: 0.6;
cursor: default;
}
The appearance of the form can, of course, be adapted to the project's design.
9. Test the Form
After configuration, check each step:- Whether the AJAX request is sent.
- Whether the PHP handler returns valid JSON.
- Whether a new information block element is created.
- Whether its properties are saved.
- Whether the email event is created.
- Whether the email arrives at the specified address.
10. What Else Should a Production Project Include?
For a production contact form, also consider:- Spam and automated submission protection;
- Request rate limiting;
- A phone number mask or additional phone validation;
- Error logging;
- Input length validation;
- A separate personal data processing policy;
- CAPTCHA, if needed.
Required checks must therefore also run on the server.
Summary
An AJAX contact form in 1C-Bitrix has three main parts:- An HTML form filled in by the user;
- JavaScript that sends the data without reloading the page;
- A PHP handler that validates the data, saves the enquiry and creates an email event.