JSFiddle - React, Tailwind, and code Playground

by gurkavcu

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/2.2.1/knockout-min.js"></script>
<input type="checkbox" data-bind="checked: protectedBool" />
<span data-bind="text: protectedBool"></span>
<button data-bind="click: commit">Commit</button>
<button data-bind="click: rollback">Rollback</button>

JavaScript

ko.protectedObservable = function(initialValue) {
    //private variables
    var _actualValue = ko.observable(initialValue),
        _tempValue = initialValue;

    //computed observable that we will return
    var result = ko.computed({
        //always return the actual value
        read: function() {
           return _actualValue();
        },
        //stored in a temporary spot until commit
        write: function(newValue) {
             _tempValue = newValue;
        }
    });

    //if different, commit temp value
    result.commit = function() {
        if (_tempValue !== _actualValue()) {
             _actualValue(_tempValue);
        }
    };

    //force subscribers to take original
    result.reset = function() {
        _actualValue.valueHasMutated();
        _tempValue = _actualValue();   //reset temp value
    };

    return result;
};

ko.commitProtectedObservables = function (obj) {
    for (var prop in obj) {
        if (obj[prop].commit !== undefined) {
            obj[prop].commit();
        }
    }
};

ko.rollbackProtectedObservables = function (obj) {
    for (var prop in obj) {
        if (obj[prop].reset !== undefined) {
            obj[prop].reset();
        }
    }
};

var ViewModel = function() {
    var self = this;
    
    self.protectedBool = ko.protectedObservable(true);
    self.commit = function(){
        ko.commitProtectedObservables(self);
    };
    self.rollback = function() {
        ko.rollbackProtectedObservables(self);
    };
};

$(function() {
    ko.applyBindings(new ViewModel());
});