Dante
Dante

Reputation: 3316

Checkbox's checked property binding - Polymer

I am trying to bind a Polymer property to the CheckBox's checked property. However, the property's observer never gets fired, besides, the label also never shows any text.

However, I am able to execute a function every time the CheckBox gets clicked.

This is my code:

<link rel="import" href="../../components/polymer/polymer.html">

<dom-module id="check-box-example">
  <template>
    <div>
      <label>
        <template if="{{checked}}">Uncheck</template>
        <template if="{{!checked}}">Check</template>
      </label><br>
      <input type="checkbox" checked="{{checked}}" on-click="_checkBoxClicked">Check Box
    </div>
  </template>
  <script>
    Polymer({
      is: 'check-box-example',
      properties:{
        checked: {
          type: Boolean,
          observer: '_checkedChanged'
        }
      },
      _checkBoxClicked: function() {
        console.log("The Check Box was clicked.");
      },
      _checkedChanged: function(newValue, oldValue) {
        console.log("New Checkbox value: " + newValue);
      },
    });
  </script>
</dom-module>

What am I doing wrong? Thanks in advance.

Upvotes: 3

Views: 4532

Answers (1)

tony19
tony19

Reputation: 138526

A few problems:

  1. Your templates are missing is="dom=if", so it effectively does nothing in your code.

  2. Even with dom-if applied, the if attribute is set to checked, which has no initial value. The binding is only evaluated when the bound property has a non-undefined value, and since checked is never set, your templates don't stamp any contents (i.e., you wouldn't see "Check" or "Uncheck").

    properties: {
      checked: {
        type: Boolean,
        value: false  // initial value required for binding
      }
    }
    
  3. Your template text look backwards. The text content for if="{{checked}}" is "Uncheck", while if="{{!checked}}" is "Check". Perhaps those are user instructions rather than checkbox status.

  4. The native input does not emit a change-event for its checked attribute, so the binding wouldn't update your checked property. Instead, you could update your click-handler to explicitly set your checked property to match the value of the input's checked.

    _checkBoxClicked: function(e) { this.checked = this.$.input.checked; }
    
  5. Your label has no association to the input, so clicking it doesn't change the state of the checkbox. You could fix that by using label's for:

    <label for="foo">...</label>
    <input id="foo">
    

    or by making input a child of label:

    <label>
      <input>
    </label>
    

codepen

Upvotes: 4

Related Questions