Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

JSON responses and AJAX forms

In OpenCart 4 forms are sent in the background: the page does not reload, the controller answers with a short JSON message, and a built-in script shows it. JSON is a text format for data, and AJAX is the name for a request sent by a script instead of the browser itself.

A method that returns JSON

Add a method to the controller of the page:

// catalog/controller/information/hello.php
public function send(): void
{
    $json = ['success' => 'Thank you!'];
 
    $this->response->addHeader('Content-Type: application/json');
    $this->response->setOutput(json_encode($json));
}

Open index.php?route=information/hello.send — the browser shows the text {"success":"Thank you!"}. The header tells the browser that this is JSON and not HTML.

The form

In the template of the page add a form, and in the controller — its address:

$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>

The attribute data-oc-toggle="ajax" hands the form to the built-in script of the theme. Press the button — a green message «Thank you!» appears at the top of the page, and the page does not reload.

Checking the field

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));
}

Send the form empty — the text of the error appears under the field. The script finds the element by the key: the error name goes into the element with id="error-name".

Keys the script understands

KeyWhat the script does
successShows a green message
error as a stringShows a red message
error as an arrayShows each text under its field: key name → #error-name
redirectGoes to the given address

An underscore in a key becomes a dash in the id: the error first_name is shown in #error-first-name.

The texts used here are added to the language file of the page: entry_name, button_submit, error_name, text_hello.

Common mistake

The method builds the answer and forgets the Content-Type header or prints something besides JSON — a warning, a stray echo. The script cannot parse the answer and the form silently does nothing. Open the browser developer tools, the Network tab, and look at the response of the request: it must contain only JSON.

Thanks for reading!

Donate to the site — we work hard for you.