clickToEdit

by Sourabh Tewari

HTML

<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<div data-bind="clickToEdit: message"></div>

JavaScript

ko.bindingHandlers.hidden = {
    update: function(element, valueAccessor) {
        ko.bindingHandlers.visible.update(element, function() { return !ko.utils.unwrapObservable(valueAccessor()); });
    }        
};

ko.bindingHandlers.clickToEdit = {
    init: function(element, valueAccessor) {
        var observable = valueAccessor(),
            link = document.createElement("a"),
            input = document.createElement("input");

        element.appendChild(link);
        element.appendChild(input);

        observable.editing = ko.observable(false);

        ko.applyBindingsToNode(link, {
            text: observable,
            hidden: observable.editing,
            click: observable.editing.bind(null, true)
        });

        ko.applyBindingsToNode(input, {
            value: observable,
            visible: observable.editing,
            hasfocus: observable.editing,
            event: {
                keyup: function(data, event) {
                    //if user hits enter, set editing to false, which makes field lose focus
                    if (event.keyCode === 13) {
                       observable.editing(false);
                       return false;
                    }
                    //if user hits escape, push the current observable value back to the field, then set editing to false
                    else if (event.keyCode === 27) {
                       observable.valueHasMutated();
                       observable.editing(false);
                       return false;
                    }
                    
                }
            }
        });
    }
};

ko.applyBindings({ message: ko.observable("Welcome to camp!") });