Skip to content

How to: Working with AJAX

beatnbite edited this page Oct 2, 2012 · 4 revisions

This article explains how to:

  • request the server to perform an action without reloading the page
  • process the request on the server
  • trigger some actions on the client after processing the request

Sending an AJAX request to the server

To send an AJAX request you should execute the following JavaScript code on your page:

core.post(

  URLHandler.buildURL({target: 'example', action: 'save'}),

  function(XMLHttpRequest, textStatus, data, valid) {
  },

  {
    x: 1,
    y: 2
  }

);

The code will trigger "save" action in "example" controller. Depending on the current area (the storefront or the backend) it will run either \XLite\Controller\Customer\Example::doActionSave() or \XLite\Controller\Admin\Example::doActionSave() method.

The specified variables ("x" and "y") will be submitted to the server via a POST reqest, so you can retrieve them in your doActionSave() method as follows:

protected function doActionSave()
{
    $x = \XLite\Core\Request::getInstance()->x;
    // ...or use this notation:
    $y = \XLite\Core\Request::getInstance()->get('y');

    // Process the request
    // ...
}

core.post() has three parameters:

  1. The URL where to send the request
  2. The JavaScript callback function to handle the server response (optional)
  3. Data to be submitted to the server (optional)

Since the two last parameters are optional, it is possible to call the function as follows:

core.post(URLHandler.buildURL({target: 'example', action: 'save'}));

Processing the AJAX reqest

Notyfing of a success or a failure

The action method confirms whether the requested actions has been performed successfully by setting the "valid" variable to true.

protected function doActionSave()
{
    // Do something and set $success to TRUE if all is OK
    // (and FALSE if something goes wrong)
    // ...

    // Pass the status back to JavaScript
    $this->valid = $success;
}

The variable will be passed to the JavaScript callback function as the 4th parameter. So, on the client side we can handle this as follows:

core.post(

  URLHandler.buildURL({target: 'example', action: 'save'}),

  function(XMLHttpRequest, textStatus, data, valid) {
    if (valid) {
      ..."success" scenario...
    } else {
      ..."fail" scenario...
    }
  }

);

Responsing with data

You can pass data from your action method back to the JavaScript callback function as follows:

protected function doActionSave()
{
    // Process the request and prepare the $data array
    // ..

    // Pass the data back to the JavaScript callback function
    print (json_encode($data));
}

You can process the data from the callback function as follows:

core.post(

  URLHandler.buildURL({target: 'example', action: 'save'}),

  function(XMLHttpRequest, textStatus, data, valid) {
    if (valid && data) {
      data = jQuery.psrseJSON(data);
      ... process the response ...
    }
  }

);

Redirecting the user after processing the request

After processing the request you can redirect the user to other page as follows:

protected function doActionSave()
{
    // Process the request
    // ...

    // Redirect the user
    $this->setReturnURL([your-url]);
    $this->setHardRedirect(true);
}

Reloading the page after processing the request

After processing the request you can reload the page as follows:

protected function doActionSave()
{
    // Process the request
    // ...

    // Reload the page
    $this->setHardRedirect(true);
}

Triggering and processing JavaScript events

From your action method you can trigger one or more events to be processed on the client side:

protected function doActionSave()
{
    // ...

    // Trigger two custom events: "cartUpdated" and "userDeleted".
    \XLite\Core\Event::cartUpdated('some-value', 'another-value', ...);
    \XLite\Core\Event::userDeleted('some-value');

    // ...
}

To handle the events on the client side you are to bind JavaScript functions to these events as follows:

core.bind(
  'cartUpdated',
  function (event, param1, param2, ...) {
    ...
  }
);

You can bind more than one JavaScript function to an event.

Displaying a "top" message

You can trigger a message to be displayed on the client side as follows:

protected function doActionSave()
{
    // ...

    // Add a regular message
    \XLite\Core\TopMessage::addInfo(‘Done.’);

    // Add a warning message
    \XLite\Core\TopMessage::addWarning(‘Used the default value for the field.’);

    // Add an error message
    \XLite\Core\TopMessage::addError(‘There is no such a product!’);

    // ...
}

On the client side the messages will be shown by the "skins/default/en/top_message/controller.js" file.

Clone this wiki locally