# Gallery

This widget displays a list of images and allows you to select an image. The gallery is similar to options but it contains images obtained from your back end or an external image source, not from an e-commerce driver.

## General information

- **type**: `gallery`

## Params

You can specify elements of your gallery either manually or through the REST API. The following parameters correspond to the first way:

- `prompt` - the prompt (for example, _Pick a background_).
- `description` - the tooltip (appears when a user points to the `i` icon).
- `showTitle` - enables element titles in a response. The default value is `true`.
- `forceSelection` - if `true`, the first element will be automatically selected at the loading time.
- `items` - an array of images to display in the gallery. Each item is described with [properties explained below](#gallery-item-properties).
- `itemWidth` - defines an item width. This value is applied as a CSS variable **--item-width**.
- `onChange` - a function (`"{{#function <expression>}}"`) or an array of functions that work after changing an item.

### Gallery item properties 

Gallery elements are described by the following properties: 

- `title` - a display name of an item. Required only when `showTitle` of a widget is `true`.
- `name` - a _machine-readable_ name of an item. This name can be used to refer to an item on the back end.
- `previewUrl` - a URL to the image to display in the editor. This is the only mandatory parameter.
- `data` - a JSON object containing arbitrary data associated with this image. 

See the [examples below](#examples) for details. 

### Dynamic config properties

- `_` (alias of `selected`) - currently selected item.


## Examples

### Hardcoding a gallery

``` json
{
    "type": "gallery",
    "name": "backgrounds",
    "title": "Background",
    "params": {
        "prompt": "Choose a background image",
        "showTitle": true,
        "items": [
            {
                "title": "Football",
                "name": "something",
                "previewUrl": "/assets/img/something.jpg"
            }
        ]
    }
}
```

### Dynamically define a gallery from vars

_**NOTE!** To understand this example, read the [Dynamic Configs article](../dynamic-configs.md) first._

It is not always convenient to hardcode all items in the config. You may rather prefer to specify a list of items in the `vars` section of the config and create a gallery based on it. For example, assume that you have a list of Customer's Canvas state files. You can display them like this:

``` json
{
    "vars": {
        "stateFiles": [
            "1eec1a5e-f2c9-4e9b-9817-7a08d7327853", 
            "f1d26448-5e5d-429a-8c32-d96655ca897f",
            "3f5077f8-af8e-4c96-b8e8-badff16d4915"
        ]
    },
    "widgets": [{
        "name": "state-gallery",
        "type": "gallery",
        "params": {
            "prompt": "Select a design",
            "forceSelection": false,
            "showTitle": false,
            "items": {
                "{{#each vars.stateFiles as state}}": {
                    "name": "{{state}}",
                    "previewUrl": "{{ settings.customersCanvasBaseUrl + 'api/rendering/GetProofImage/' + user.id + '/' + stateFile + '/0_0.png'}}"
                }
            }
        }
    }],
    ...
}
```

### Grab items from a remote source

Using `vars` is not always a good idea. Sometimes you may want to get a list of images from your backend using REST API. In this case, you can use the Gallery widget along with the [Ajax widget](ajax.md) together. 

Imagine that you have an endpoint like `GET http://example.com/api/backgrounds/christmas`. It returns a JSON in the same format as the Gallery expects, for example: 

``` json
[
    {
        "title": "HO-HO-HO!",
        "name": "9424",
        "previewUrl": "http://example.com/api/backgrounds/christmas/9424?w=400&h=400",
        "data": {
            "author": "John Smith"
        }
    },
    {
        "title": "Christmas Tree and Gifts",
        "name": "bg-xmas-2",
        "previewUrl": "http://example.com/api/backgrounds/christmas/8842?w=400&h=400",
        "data": {
            "author": "Jane Johnson"
        }
    }
]
```

Your config may look like this: 

``` json
{
    "widgets": [
        {
            "name": "bg-request",
            "type": "ajax",
            "params": {
                "url": "http://example.com/api/backgrounds/christmas",
                "method": "GET"
            }
        },
        {
            "name": "bg-gallery",
            "type": "gallery",
            "params": {
                "prompt": "Choose a background",
                "items": "{{$['bg-request'].response}}"
            }
        }
    ]
}
```

What if the back end sends your data in some other structure? It may be the case that the back-end part was created by developers from another team or it is already widely used. 

For example, assume that the list of files is a part of a larger structure and the object describing a file has a different structure, e.g.

``` json
{
    "categoryId": 1234,
    "rootId": 42,
    "files": [
        {
            "id": 9424,
            "displayName": "HO-HO-HO!",
            "author": "John Smith"
        },
        {
            "id": 8842,
            "displayName": "Christmas Tree and Gifts",
            "author": "John Smith"
        }
    ]
}
```

For this scenario, you can use the Dynamic Config approach, like in the example with `vars`:

``` json
{
    "widgets": [
        {
            "name": "bg-request",
            "type": "ajax",
            "params": {
                "url": "http://example.com/api/backgrounds/christmas",
                "method": "GET"
            }
        },
        {
            "name": "bg-gallery",
            "type": "gallery",
            "params": {
                "prompt": "Choose a background",
                "items": {
                    "{{#each $['bg-request'].response.files as item}}": {
                        "title": "{{item.displayName}}",
                        "name": "{{item.id}}",
                        "previewUrl": "{{'http://example.com/api/backgrounds/christmas/'+item.id+'?w=400&h=400'}}",
                        "data": {
                            "author": "{{item.author}}"
                        }
                    }
                }
            }
        }
    ]
}
```