Html
====

This widget is a more complicated version of the [StaticText widget](static-text.md). It allows for inserting not only a text string, but also HTML markup.

Like everything else in the config files, HTML markup is described in the JSON format. It is built on top of the [JSON2HTML](https://json2html.com/) library.

## General information

- **type**: `html`

## Params

- `template` - an object or array of HTML template objects (see below).
- `data` - an object containing data for HTML templates.

## How it works

The idea (derived from the JSON2HTML library) is the following. You describe a structure of an HTML document with special JSON-based syntax. After that, it takes the specified array of data, iterates through this array, and generates an HTML markup.

## Template object

A template object supports the following parameters: 

- `<>` - specifies a DOM element name, e.g. `div` | `span` | `ul` | `li`, etc.
- `text` - node text.
- `html` - an equivalent for the _inner HTML_, i.e. it can be either the same as `text` or a nested template object (or array). 
- `id` - a DOM element ID (optional).
- `class` - a CSS class (optional).
- `style` - an inline style (optional).

Other DOM element attributes are supported as well. See [JSON2HTML](https://json2html.com/docs/) docs for details.

## Examples

### Minimal HTML markup 

This snippet:

``` json
{
    "<>": "span",
    "text": "Hello world" 
}
```

Will be translated to:

``` html
<span>Hello world</span>
```

### Markup with DOM attributes

This snippet:

``` json
{
    "<>": "span",
    "id": "element-01",
    "class": "primary",
    "text": "Hello world"
}
```

Will be translated to:

``` html
<span id="element-01" class="primary">Hello world</span>
```

### Styling

This snippet:

``` json
[
    {
        "<>": "style",
        "text": ".myclass { color: red }"
    },
    {
        "<>": "span",
        "class": "myclass",
        "text": "Lorum ipsum"
    }
]
```

translates to: 

``` html
<style>
  . myclass { color: red }
</style>
<span class="myclass">Lorum ipsum</span>
```

The text will be displayed as red.

### Nested HTML

This snippet:

``` json
{
    "<>": "ul",
    "html": [
        {
            "<>": "li",
            "text": "Foo"
        },
        {
            "<>": "li",
            "text": "Bar"
        }        
    ] 
}
```

translates to: 

``` html
<ul>
    <li>Foo</li>
    <li>Bar</li>
</ul>
```

## JSON2HTML Builder

If you have no experience with this syntax, you may find it a bit challenging to set your mind to write HTML as JSON. In this case, you may use this tool created by the authors of the JSON2HTML library:

[https://json2html.com/builder](https://json2html.com/builder)

## Working with data

In addition to creating static HTML markup, you can create it based on the array of data as specified in the `data` property. It will iterate through each item of `data` and create a copy of an element for them. To refer to a property in a data item, use the `"${propname}"` syntax.

For example, the following definition:

``` json
{
    "name": "option-overview",
    "type": "html",
    "params": {
        "data": [
            {
                "title": "Color",
                "value": "Space Gray"
            },
            {
                "title": "Shape",
                "value": "Rounded Rect"
            }
        ],
        "template": {
            "<>": "div",
            "html": [
                {
                    "<>": "span",
                    "text": "${title}: ",
                    "style": "font-weight: bold"
                },
                {
                    "<>": "span",
                    "text": "${value}"
                }
            ]
        }
    }
}
```

Will be translated to:

``` html
<div>
    <span style="font-weight: bold">Color: </span>
    <span>Space Gray</span>
</div>
<div>
    <span style="font-weight: bold">Shape: </span>
    <span>Rounded Rect</span>
</div>
```

## Alternative way: using dynamic config

After looking at the code above, you may find out that the functionality of JSON2HTML does something similar to our dynamic config system.

Indeed, the previous example may be implemented as:

``` json
{
    "vars": {
        "data": [
            {
                "title": "Color",
                "value": "Space Gray"
            },
            {
                "title": "Shape",
                "value": "Rounded Rect"
            }
        ],
        ...
    }
},
{
    "widgets": [
        {
            "name": "option-overview",
            "type": "html",
            "params": {
                "template": {
                    "{{#each vars.data}}": {
                        "<>": "div",
                        "html": [
                            {
                                "<>": "span",
                                "text": "{{item.title}}",
                                "style": "font-weight: bold"
                            },
                            {
                                "<>": "span",
                                "text": "{{item.value}}"
                            }
                        ]
                    }
                }
            }
        }
    ]
}
```

The generated markup will be identical to the previous sample.

In general, we encourage using the dynamic config approach, however, if for some reasons JSON2HTML syntax is more convenient, feel free to use it.

