JSFiddle - React, Tailwind, and code Playground

by stevegreatrex

HTML

<span data-bind="visible: !property1.isEditing(), text: property1"></span>

<input data-bind="visible: property1.isEditing, value: property1" />
<span data-bind="visible: !child.childProperty.isEditing(), text: child.childProperty"></span>

<input data-bind="visible: child.childProperty.isEditing, value: child.childProperty" />
<ul data-bind="foreach: children"> <span data-bind="visible: !isEditing(), text: childProperty"></span>

    <input data-bind="visible: isEditing, value: childProperty" />
</ul>
<a href="#" data-bind="click: beginEdit, visible: !isEditing()">Edit</a>

<a href="#" data-bind="click: endEdit, visible: isEditing">Save</a>

<a href="#" data-bind="click: cancelEdit, visible: isEditing">Cancel</a>

<script type="text/html" id="editable-field">
    < span data - bind = "visible: !$data.isEditing(), text: $data" > < /span>
    <input data-bind="visible: $data.isEditing, text: $data" / >
</script>

CSS

* {
    font-family: Segoe UI
}
span, input, a {
    display: block;
}

JavaScript

/*
  ko.editable implementation
*/

(function (window, ko, undefined) {
    "use strict";

    ko.editable = function (initial) {
        var _rollbackValue,
        _observable = ko.observable(initial);

        //a flag to indicate if the field is being edited
        _observable.isEditing = ko.observable(false);

        //start an edit
        _observable.beginEdit = function () {
            _rollbackValue = _observable();
            _observable.isEditing(true);
        };

        //end (commit) an edit
        _observable.endEdit = function () {
            if (!_observable.isEditing()) {
                return;
            }

            _observable.isEditing(false);
        };

        //cancel and roll-back an edit
        _observable.cancelEdit = function () {
            if (!_observable.isEditing()) {
                return;
            }

            _observable(_rollbackValue);

            _observable.isEditing(false);
        };

        //public members
        return _observable;
    };

    var forEachEditableProperty = function (target, action) {
        for (var prop in target) {
            if (target.hasOwnProperty(prop)) {
                var value = target[prop],
                    unwrappedValue = ko.utils.unwrapObservable(value);

                //direct editables
                if (value && value.isEditing) {
                    action(value);
                }

                //editables in arrays
                if (unwrappedValue && unwrappedValue.length) {
                    for (var i = 0; i < unwrappedValue.length; i++) {
                        if (unwrappedValue[i] && unwrappedValue[i].isEditing) {
                            action(unwrappedValue[i]);
                        }
                    }
                }
            }
        }
    };

    ko.editable.makeEditable = function (target) {
        if (!target) {
            throw "Target must be specified";
        }

        target.isEditing =...