Control a paper-checkbox's state

Frexuz picture Frexuz · Feb 8, 2015 · Viewed 9.8k times · Source

I'm trying to setup an element with a paper-checkbox inside of it. I want the checkbox's checked state to be controlled by the response of an ajax call.

HTML:

<epic-list-episode checked="<%= episode.seen? %>">
  <p><strong><%= episode.show.name %></strong></p>
</epic-list-episode>

Custom element:

<polymer-element name="epic-list-episode" attributes="checked">

  <template>
    <link rel="stylesheet" href="epic-list-episode.css.scss" />
    <div horizontal layout center>
      <div flex>
        <content></content>
      </div>
      <div vertical layout>
        <paper-checkbox checked?="{{checked === 'true'}}" on-change="{{changeHandler}}"></paper-checkbox>
      </div>
    </div>
  </template>

  <script>
    Polymer({
      changeHandler: function(event) {
        //Send ajax, wait for error/success callback
        //checkbox.checked = response from ajax
      }
    });
  </script>

</polymer-element>

How can this be achieved? I've tried return false but the checkbox still does its toggle animation.

To clarify, here is the flow i want:

  1. Checkbox is unchecked
  2. I click the checkbox (I don't want it to toggle yet)
  3. Ajax request is sent off
  4. Wait for the callback
  5. If it's successful, toggle the state of the checkbox

Answer

Justin XL picture Justin XL · Feb 9, 2015

I don't think you need that checked attribute at all.

What you can do is, when the on-change is called, set the checked property of the paper-checkbox back to its previous value. And then after the ajax callback, set it back to what it should be.

changeHandler: function (event, detail, sender) {
    this.$.checkbox.checked = !this.$.checkbox.checked;

    // give the checkbox a little loading animation
    var loading = new CoreAnimation();
    loading.duration = 750;
    loading.easing = 'ease-in';
    loading.keyframes = [{ opacity: 1, transform: "scale(1)" }, { opacity: 0.4, transform: "scale(0.9)" }];
    loading.direction = 'alternate';
    loading.iterations = '1000';
    loading.target = this.$.checkbox;
    loading.play();

    // give it a little delay to act like a callback
    this.job('delay', function () {
        // stop the animation
        loading.finish();

        this.$.checkbox.checked = !this.$.checkbox.checked;
    }, 3000);
}

Note that I have also included some animation code to make the user feel like the paper-checkbox is doing something, for a better user experience. Please see this jsbin for a working example.