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

# Binding Model Data in Polymer Templates

> **Note: Use Lit templates instead**
>
> Lit templates are recommended. Polymer templates are available in the next long term supported Vaadin version (LTS), but they are deprecated.

The way model values are bound to different parts of the element tree that is defined by the template is at the core of the `PolymerTemplate` API. See [Creating A Simple Component Using the PolymerTemplate API](https://vaadin.com/docs/v14/flow/templates/polymer-templates/tutorial-template-basic.md) for a simple example of how to set model values.

The first three sections below demonstrate how to bind [text content](#binding-text-content), [property values](#binding-property-values), and [attribute values](#binding-attribute-values). The JavaScript template examples in these sections all use the following example Java template and model class

**Example**: `PolymerBindingTemplate` template class.

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

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

**Example**: `BindingModel` model interface.

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

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

To bind text content in a JavaScript Polymer template, use the `\[[propertyName]]` syntax inside a tag. Double square brackets (\[\[ ]]) indicate a one-way binding.

**Example**: Binding text content in a JavaScript Polymer template.

```js
class MyTemplate extends PolymerElement {
    static get template() {
        return html`<div>[[hostProperty]]</div>`;
    }

    static get is() {return 'my-template'}
}
customElements.define(MyTemplate.is, MyTemplate);
```

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

To set an element property value based on a model, use the property name in the attribute format, by using the dash-case format, sometimes referred to as kebab-case, e.g. `my-property-name` (not camelCase `myPropertyName`).

**Example**: Setting an element property based on a model in a JavaScript Polymer template.

```js
return html`<my-element my-property="[[hostProperty]]"></my-element>`;
```

- This 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`.

- `name="binding"` (without brackets) defines that the element *attribute* named `name` should have the value `binding`, regardless of any value in the model.

Polymer cannot bind certain common native element properties directly, because the binding causes issues on one or more browsers. In these cases, you can use attribute bindings instead. See [Native properties that don’t support property binding](https://www.polymer-project.org/3.0/docs/devguide/data-binding#native-binding) for more.

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

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

To explicitly bind to an attribute, use the attribute name followed by a dollar sign (`$`).

**Example**: Binding to an attribute in an JavaScript Polymer template.

```js
return html`<div something$="[[hostProperty]]"></div>`;
```

or

```js
return html`<a href$="[[hostProperty]]"></a>`;
```

## <a id="server-side-sample"></a>Two-way Versus One-way Bindings

Text surrounded by double curly bracket {{ }} or double square bracket \[\[ ]] delimiters identifies the host data that is bound:

- Double curly brackets ({{ }}) indicate two-way bindings: both server-to-client and client-to-server data flow.

- Double square brackets (\[\[ ]]) indicate one-way bindings: only server-to-client data flow.

## <a id="two-way-binding"></a>Creating Two-way Data Bindings

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

To demonstrate we create:

- A two-way binding model class with a number of fields.

- A Java template class that sets default values for the model, and adds listeners for `save` and `reset` events.

- An associated JavaScript Polymer template.

**Example**: `TwoWayBindingModel` with `name`, `accepted` and `size` fields.

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

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

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

**Example**: `PolymerTwoWayBindingTemplate` Java template class that defines `save` and `reset` event property change listeners, and sets default values for the `name`, `accepted` and `size` fields.

```java
@Tag("two-way-template")
@JsModule("./com/example/two-way-template.js")
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");
    }
}
```

- The `Element::addPropertyChangeListener` method gets immediate updates when the property values change. As an alternative, you could define an `@EventHandler` method on the server side and add appropriate event handers in the template.

- On the client, we use the following methods to bind the model data (see JavaScript template below):

  - `name` string to an input using:

    - Native input element.

    - Polymer element `paper-input`.

  - `accepted` boolean 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 `target-prop="{{hostProp::_target-change-event_}}"` syntax. See [Two-way binding to a non-Polymer element](https://www.polymer-project.org/3.0/docs/devguide/data-binding#two-way-native) in the Polymer 3 documentation for more.

**Example**: Polymer JavaScript template.

```js
import {PolymerElement,html} from '@polymer/polymer/polymer-element.js';
import '@polymer/paper-input/paper-input.js';
import '@polymer/paper-radio-button/paper-radio-button.js';
import '@polymer/paper-radio-group/paper-radio-group.js';
import '@polymer/paper-checkbox/paper-checkbox.js';

class TwoWayBinding extends PolymerElement {

    static get template() {
        return html`
            <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>`;
    }

    static get is() {
        return 'two-way-template';
    }
}
customElements.define(TwoWayBinding.is, TwoWayBinding);
```

- We use two-way bindings for each element.

- Some elements bind to the same property. For example, when the value for `name` is changed in the `paper-input` element, the new value reflects in both `Input name` and `Change name`.

- The two input bindings, `Input name` and `Change name`, work in slightly different ways:

  - `Input name` binds using `{{name::input}}` and `Change name` binds using `{{name::change}}`. The given `target-change-event` lets Polymer know which event to listen to for change notifications.

  - The functional difference is that `::input` updates during typing, and `::change` updates when the value of the field changes, for example an `onBlur` event or Enter key press.

Here’s the template representation in the browser:

[Image: Template representation]

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

`92A1CE11-112F-4215-88D8-177FBF0221CA`
