# Ajax

This non-visual widget is used to send requests to the server and receive responses that can be used in other widgets. For example, it can be used to populate dropdown lists or image galleries, dynamically generate images on the server based on the other widget values, etc.

## General information

- **type**: `ajax`

## Params

- **url** - a URL that is used to accept requests. 
- **method** - an HTTP method like `POST`, `GET`, etc. The default value is `POST`.
- **headers** - a dictionary of HTTP headers sent along with the request (an object with the keys used as a header name and a value used as a header value).
- **enabled** - if `False`, the request will not be executed. The default value is `true`.
- **request** - a request body. Typically, you put a JSON here that consists of references to other widgets (see examples below).
- **responseType** - how to interpret the response received from the server:
   - `text` - the server returns a raw text string. The Ajax widget does not try to interpret it.
   - `json` - the server returns a JSON object. When you refer the `response` in your config, you can access its properties. This is the default value.
   - `blob` - the server returns binary data. It makes sense to use it along with some widgets that can work with binary data directly.
   - `blob_url` - the server returns binary data, but it is converted to the Blob URL, which can be used with HTML markup.
   - `status_code` - the `response` contains only the HTTP code.
- **lock** - the widget name that should be locked while waiting for the response. The editor will show a preloader on this widget (e.g. a `static-image`).
- **autoCompile** - if `true`, the request is sent every time it detects changes in the request (or other params). If `false`, the request is sent only when you explicitly call the `compile()` method. The default value is `true`.
- **onSuccess** - `Function | Array<Function>` - a function (`"{{#function <expression>}}"`) or an array of functions that work after the successful request.
- **onError** - `Function | Array<Function>` - a function or an array of functions that should work when the request fails.

## Properties

You can use the following properties in the Dynamic Configs: 

- `response` - a server response, interpreted based on the `responseType` param. If `autoCompile` is `true`, it is automatically updated every time the widget gets a server response.

## Methods

You can use the following methods in the Dynamic Configs: 

- `compile()` - forces the widgets to "recompile" its params and therefore send a request to the server. It is a way to initiate a request when `autoCompile` is `false`.

## Code examples

### Auto update image

Let's assume you have an endpoint at  *http://localhost:4242/api/preview*, where our PsdWebService is installed (i.e. an API which allows personalization of PSD file using Web API). You send a JSON where you specify what layers should be replaced by what values, and it returns a URL to an image that you want to set to the [StaticImage widget](static-image.md).

For example, you may want to re-generate it every time a user changes the option called **name**. 

The config may look like this: 

``` json
{
   "widgets": [{
       "name": "name",
       "type": "option",
       "params": {
            "type": "list",
            "title": "Name",
            "prompt": "Choose a name",
            "values": [
                { "title": "Jack" },
                { "title": "James" },
                { "title": "John" }
            ]
       }  
    },
    {
       "name": "image-request",
       "type": "ajax",
       "params": {
            "url": "http://localhost:4242/api/preview",
            "method": "POST",
            "lock": "preview",
            "responseType": "json",
            "request": {
                  "greeting": {
                       "type": "text",
                       "text": "Hello {{$['name']._.title}}"
                  }
            }
       }  
   },
   {
       "name": "preview",
       "type": "static-image",
       "params": {
            "imageUrl": "{{$['image-request'].response}}"
       }
   }]
}
```

For example, a user chooses _"Jack"_. The widget detects the `$['name']` widget change and sends the following POST request to _http://localhost:4242/api/preview_:

``` json
{
    "greeting": {
        "type": "text",
        "text": "Hello Jack"
    }
}
```

The server returns a URL to the image. The `$['preview']` widget detects that the response from the server arrives and displays this URL (through the `response` property).


### Generate an image when opening a step

Now, let's assume that you don't want to generate the image every time a user chooses a name. For example, the user selects options in Step 1, but the image is used in Step 2. You don't want to overburden the server by generating intermediate results that are never used.

In this scenario, you turn off the auto compilation (`autoCompile: false`) and manually call the `compile()` method of the Ajax widget when the user opens Step 2.

You can do it as follows: 

``` json
{
   "widgets": [{
       "name": "name",
       "type": "option",
       "params": {
            "type": "list",
            "title": "Name",
            "prompt": "Choose a name",
            "values": [
                { "title": "Jack" },
                { "title": "James" },
                { "title": "John" }
            ]
       }  
    },
    {
       "name": "image-request",
       "type": "ajax",
       "params": {
            "url": "http://localhost:4242/api/preview",
            "method": "POST",
            "lock": "preview",
            "responseType": "json",
            "request": {
                  "greeting": {
                       "type": "text",
                       "text": "Hello {{$['name']._.title}}"
                  }
            }
       }  
   },
   {
       "name": "preview",
       "type": "static-image",
       "params": {
            "imageUrl": "{{$['image-request'].response}}"
       }
   }],
   "steps": [
       {
           "title": "Step 1",
           "toolPanel": { "name": "name" },
           ...
       },
       {
           "title": "Step 2",
           "mainPanel": { "name": "preview" },
           "onActivate": ["{{#function $['pdf-request'].compile()}}"] 
       }
   ]
}
```


