> Markdown version of [Binding Model Data in a PolymerTemplate](https://vaadin.com/docs/v10/flow/polymer-templates/tutorial-template-bindings). Section index: [llms.txt](https://vaadin.com/docs/v10/flow/llms.txt)

# Binding Model Data in a PolymerTemplate

At the core of `PolymerTemplate` is the way model values are bound to different parts of the element tree defined by the template. To get started with using templates and learn how to set model values, see [Creating A Simple Component Using the Template API](https://vaadin.com/docs/v10/flow/polymer-templates/tutorial-template-basic.md).

## <a id="binding-text-content"></a>Binding Text Content

The value of a model property can be used as the text content of an element using `[[propertyName]]` inside a tag.

Sample HTML Template

```html
<dom-module id="my-template">
    <template>
        <div>[[hostProperty]]</div>
    </template>
    <script>
         class MyTemplate extends Polymer.Element {
           static get is() {return 'my-template'}
         }
         customElements.define(MyTemplate.is, MyTemplate);
    </script>
</dom-module>
```

For the server-side sample see: [Server-side model sample code](#server-side-sample)

## <a id="binding-property-values"></a>Binding Property Values

You can set an element property value based on a model by using the property name in attribute form (dash-case not camelCase):

```html
<dom-module id="my-template">
<template>
    <my-element my-property="[[hostProperty]]"></my-element>
</template>
...
</dom-module>
```

This example binds to the target property, myProperty on \<my-element>.

> **Note:** `name="[[binding]]"` defines that the element *property* named `name` should get it’s value from the model property named `binding`, whereas `name="binding"` (i.e. without brackets) defines that the element *attribute* named `name` should have the value `binding` regardless of any value in the model.

There are a handful of common native element properties that Polymer can’t data-bind to directly, because the binding causes issues on one or more browsers and you need to use attribute bindings instead. For more information on these properties see: [Native properties that don’t support property binding](https://www.polymer-project.org/2.0/docs/devguide/data-binding#native-binding)

## <a id="binding-attribute-values"></a>Binding Attribute Values

A binding written as `<div something="[[hostProperty]]"></div>` is bound to the *property* `something` because the property can typically be changed on the fly while the attribute is often used only for the initial value.

When you want to explicitly bind to an attribute instead, use the attribute name followed by $:

```html
<dom-module id="my-template">
    <template>
        <div something$="[[hostProperty]]"></div>
    </template>
    ...
</dom-module>
```

or

```html
<dom-module id="my-template">
    <template>
        <a href$="[[hostProperty]]"></a>
    </template>
    ...
</dom-module>
```

> **Note:** Text surrounded by double curly bracket {{ }} or double square bracket \[\[ ]] delimiters identify the host data being bound.
>
> - Double-curly brackets support both upward and downward data flow. see [Two-way data binding](#two-way-binding).
>
> - Double square brackets are one-way, and support only downward data flow.

### <a id="server-side-sample"></a>Server-side model sample code

Here is the server-side sample for tutorial html templates.

PolymerTemplate class

```java
@Tag("my-template")
@HtmlImport("/com/example/PolymerBinding.html")
public class PolymerBindingTemplate extends PolymerTemplate<BindingModel> {

    public PolymerBindingTemplate() {
        getModel().setHostProperty("Bound property");
    }
}
```

TemplateModel sample

```java
public interface BindingModel extends TemplateModel {
    void setHostProperty(String propertyValue);
    String getHostProperty();
}
```

## <a id="two-way-binding"></a>Two-way data binding

For two-way data binding the data flows in both directions client-to-server and server-to-client.

To demonstrate the functionality lets create a TwoWayBindingModel with some a couple of different fields like:

Two-way template model

```java
public interface TwoWayBindingModel extends TemplateModel {
    void setName(String name);
    String getName();

    void setAccepted(Boolean accepted);
    Boolean getAccepted();

    void setSize(String size);
    String getSize();
}
```

For the server-side PolymerTemplate we will set some default values to the model values and wire listeners for events `save` and `reset` as follows:

Two-way binding template

```java
@Tag("two-way-template")
@HtmlImport("/com/example/PolymerTwoWayBinding.html")
public class PolymerTwoWayBindingTemplate
        extends PolymerTemplate<TwoWayBindingModel> {

    public PolymerTwoWayBindingTemplate() {
        reset();
        getElement().addPropertyChangeListener("name", event -> System.out
                .println("Name is set to: " + getModel().getName()));
        getElement().addPropertyChangeListener("accepted",
                event -> System.out.println("isAccepted is set to: "
                        + getModel().getAccepted()));
        getElement().addPropertyChangeListener("size", event -> System.out
                .println("Size is set to: " + getModel().getSize()));
    }

    @EventHandler
    private void reset() {
        getModel().setName("John");
        getModel().setAccepted(false);
        getModel().setSize("medium");
    }
}
```

We use here the `Element::addPropertyChangeListener` method to get immediate update for the property values. Another way would be to define an `@EventHandler` method on the server side which is just called once when a button is pressed similar to the `reset()` method.

On the client we will use different methods to bind binding the model data:

Name string to an input using:

- Native input element

- Polymer element `paper-input`

Boolean accepted to a checkbox using:

- Native checkbox input

- Polymer element `paper-check-box`

Size string to a select element using:

- Native select

- Polymer elements `paper-radio-group` and `paper-radio-button`

> **Note:** Native elements need to specify a custom change event name in the annotation using the syntax: `target-prop="{{hostProp::target-change-event}}"` see. [Two-way binding to a non-Polymer element](https://www.polymer-project.org/2.0/docs/devguide/data-binding#two-way-native)

Polymer html template

```html
<!-- Import Polymer and Polymer components -->
<link rel="import" href="/bower_components/polymer/polymer-element.html">
<link href="/bower_components/paper-input/paper-input.html" rel="import">
<link href="/bower_components/paper-radio-button/paper-radio-button.html" rel="import">
<link href="/bower_components/paper-radio-group/paper-radio-group.html" rel="import">
<link href="/bower_components/paper-checkbox/paper-checkbox.html" rel="import">

<dom-module id="two-way-template">
    <template>
        <table>
            <tr>
                <td>Paper name:</td>
                <td>
                    <paper-input value="{{name}}"></paper-input>
                </td>
            </tr>
            <tr>
                <td>Input name:</td>
                <td>
                    <input value="{{name::input}}">
                </td>
            </tr>
            <tr>
                <td>Change name:</td>
                <td>
                    <input value="{{name::change}}">
                </td>
            </tr>
            <tr>
                <td>Input accepted:</td>
                <td>
                    <input type="checkbox" checked="{{accepted::change}}">
                </td>
            </tr>
            <tr>
                <td>Polymer accepted:</td>
                <td>
                    <paper-checkbox checked="{{accepted}}"></paper-checkbox>
                </td>
            </tr>
            <tr>
                <td>Size:</td>
                <td>
                    <paper-radio-group selected="{{size}}">
                        <paper-radio-button name="small">Small</paper-radio-button>
                        <paper-radio-button name="medium">Medium</paper-radio-button>
                        <paper-radio-button name="large">Large</paper-radio-button>
                    </paper-radio-group>
                </td>
            </tr>
            <tr>
                <td>Size:</td>
                <td>
                    <select value="{{size::change}}">
                        <option value="small">Small</option>
                        <option value="medium">Medium</option>
                        <option value="large">Large</option>
                    </select>
                </td>
            </tr>
        </table>
        <div>
            <button on-click="reset">Reset values</button>
        </div>
        <slot></slot>
    </template>

    <script>
        class TwoWayBinding extends Polymer.Element {
            static get is() {
                return 'two-way-template'
            }
        }
        customElements.define(TwoWayBinding.is, TwoWayBinding);
    </script>
</dom-module>
```

Here’s the template representation in the browser:

[Image: Template representation]

In the template we use two-way bindings for each element and some elements bind to the same property. This will show up in a way that for example the value for name is changed in the paper-input element the value will be reflected to both "Input name:" and "Change name".

> **Note:** The two input bindings "Input name" and "Change name" have a small difference in the way they work.
>
> Input name binds using `{{name::input}}` and Change with `{{name::change}}` the given `target-change-event` lets Polymer know which event to listen to for change notification.
>
> The functional difference is that `::input` will update while typed and `::change` when the value for the field changes (so e.g. onBlur event or for enter)

> **Note:** For information on the element `<slot></slot>` see [Using \<slot> in PolymerTemplates](https://vaadin.com/docs/v10/flow/polymer-templates/tutorial-template-components-in-slot.md)
