JSFiddle - React, Tailwind, and code Playground

by NinjaFish

HTML

<script src="https://github.com/jquery/jquery-tmpl/raw/master/jquery.tmpl.js"></script>
<script src="https://github.com/SteveSanderson/knockout/raw/master/build/output/knockout-latest.debug.js"></script>
<form>
    <div>
        <div>
            <label><input type="checkbox" data-bind="checked: genders" value="1" />Male</label>
            <label><input type="checkbox" data-bind="checked: genders" value="2" />Female</label>
        </div>
    </div>
    <a href="#" data-bind="click: genders.reset">Cancel</a>
    <a href="#" data-bind="click: genders.commit">Update</a>
</form>

<hr/>

<div data-bind="text: ko.toJSON(viewModel)"></div>

JavaScript

//wrapper to an observableArray of primitive types that has commit/reset
ko.observableArrayWithUndo = function(initialArray) {
    var undoState = null,
        currentState = initialArray,
        result = ko.observableArray(initialArray.slice(0));
    
    var onChange = function(newValues) {
        if (!undoState) {
            undoState = currentState.slice(0);
        }
        currentState = newValues.slice(0);
    };
    
    var subscription = result.subscribe(onChange);
    
    result.commit = function() {
        undoState = null;
    };
    
    result.reset = function() {
        if (undoState) {
            subscription.dispose();
            result(undoState.slice(0));
            currentState = undoState.slice(0);
            undoState = null;
            subscription = result.subscribe(onChange);
        }
    };
    
    return result;
};


var viewModel = {
    genders: ko.observableArrayWithUndo([])
};

ko.applyBindings(viewModel);