Dante Dante - 3 months ago 53
HTML Question

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.

Answer

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