Backbone Checkbox Defer

Defer the checking or unchecking of a checkbox until the user has confirmed their choice in a dialog.

by david_i_smith

HTML

<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>
<input type="checkbox" />
<label>Unchecked</label>
<div id="dialog">
    <button class="confirm">Confirm</button>
    <button class="cancel">Cancel</button>
</div>

JavaScript

var Checkbox = Backbone.View.extend({
    events: {
        'click': 'onClick'
    },
    onClick: function (e) {
        this.deferClick();
    },
    deferClick: function () {
        this.isChecked = (this.$el.is(':checked')) ? true : false;
        this.trigger('clicking', ['Checking', 'Unchecking']);
    },
    resolveClick: function (isConfirmed) {
        this.isChecked = isConfirmed;
        this.$el.prop('checked', isConfirmed);
        this.trigger('clicked', ['Checked', 'Unchecked']);
    }
});

var Dialog = Backbone.View.extend({
    events: {
        'click .confirm': 'onConfirm',
        'click .cancel': 'onCancel'
    },
    initialize: function (options) {
        this.checkbox = options.checkbox;
        this.hide();
    },
    show: function () {
        this.$el.show();
    },
    hide: function () {
        this.$el.hide();
    },
    onConfirm: function (e) {
        this.dismiss(this.checkbox.isChecked);
    },
    onCancel: function (e) {
        this.dismiss(!this.checkbox.isChecked);
    },
    dismiss: function (isConfirmed) {
        this.trigger('dismissed', isConfirmed);
    }
});

var Label = Backbone.View.extend({
    initialize: function (options) {
        this.checkbox = options.checkbox;
    },
    update: function (messages) {
        this.$el.html(this.getMessage(messages));
    },
    getMessage: function (messages) {
        return (this.checkbox.isChecked) ? messages[0] : messages[1];
    }
});

var checkbox = new Checkbox({
    el: $('[type=checkbox]'),
    isChecked: false,
});
var label = new Label({
    el: $('label'),
    checkbox: checkbox
});
var dialog = new Dialog({
    el: $('#dialog'),
    checkbox: checkbox
});

dialog.listenTo(checkbox, 'clicking', dialog.show);
label.listenTo(checkbox, 'clicking', label.update);
checkbox.listenTo(dialog, 'dismissed', checkbox.resolveClick);
dialog.listenTo(checkbox, 'clicked', dialog.hide);
label.listenTo(checkbox, 'clicked', label.update);