Ответы JSON и формы AJAX
В OpenCart 4 формы отправляются в фоне: страница не перезагружается, контроллер отвечает коротким сообщением в формате JSON, а встроенный скрипт его показывает. JSON — текстовый формат данных, а AJAX — название запроса, который отправляет скрипт, а не сам браузер.
Метод, возвращающий JSON
Добавьте метод в контроллер страницы:
// catalog/controller/information/hello.php
public function send(): void
{
$json = ['success' => 'Спасибо!'];
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}Откройте index.php?route=information/hello.send — браузер покажет ответ в формате JSON с ключом success. Заголовок сообщает браузеру, что это JSON, а не HTML.
Форма
В шаблон страницы добавьте форму, а в контроллер — её адрес:
$data['send'] = $this->url->link('information/hello.send', 'language=' . $this->config->get('config_language'));{# catalog/view/template/information/hello.twig #}
<form id="form-hello" action="{{ send }}" method="post" data-oc-toggle="ajax">
<div class="mb-3">
<label for="input-name" class="form-label">{{ entry_name }}</label>
<input type="text" name="name" id="input-name" class="form-control">
<div id="error-name" class="invalid-feedback"></div>
</div>
<button type="submit" class="btn btn-primary">{{ button_submit }}</button>
</form>Атрибут data-oc-toggle="ajax" передаёт форму встроенному скрипту темы. Нажмите кнопку — вверху страницы появится зелёное сообщение «Спасибо!», а страница не перезагрузится.
Проверка поля
public function send(): void
{
$this->load->language('information/hello');
$json = [];
$name = trim($this->request->post['name'] ?? '');
if (mb_strlen($name) < 2) {
$json['error']['name'] = $this->language->get('error_name');
}
if (!$json) {
$json['success'] = sprintf($this->language->get('text_hello'), $name);
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}Отправьте форму пустой — под полем появится текст ошибки. Скрипт находит элемент по ключу: ошибка name попадает в элемент с id="error-name".
Ключи, которые понимает скрипт
| Ключ | Что делает скрипт |
|---|---|
success | Показывает зелёное сообщение |
error строкой | Показывает красное сообщение |
error массивом | Показывает каждый текст под своим полем: ключ name → #error-name |
redirect | Переходит по указанному адресу |
Подчёркивание в ключе превращается в дефис в идентификаторе: ошибка first_name выводится в #error-first-name.
Тексты из примера добавляют в файл перевода страницы: entry_name, button_submit, error_name, text_hello.
Частая ошибка
Метод собирает ответ, но забывает заголовок Content-Type или выводит что-то кроме JSON — предупреждение, случайный echo. Скрипт не может разобрать ответ, и форма молча ничего не делает. Откройте инструменты разработчика в браузере, вкладку Network, и посмотрите ответ запроса: в нём должен быть только JSON.