Simple inline editing with knockoutjs - part 2

Part 2 of 2

by Asle Gundersby

HTML

<div data-bind="liveEditor: $root.mymessage">
    <span class="view"><a href="#" data-bind="click: $root.mymessage.edit, text: $root.mymessage() || 'Click to edit mymessage 1'"></a></span>
    <input class="edit" data-bind="value: $root.mymessage,
    event: { blur: $root.mymessage.stopEditing }" />
</div>
<div data-bind="liveEditor: $root.someOtherValue">
    <span class="view"><a href="#" data-bind="click: $root.someOtherValue.edit, text: $root.someOtherValue() || 'Click to edit value 2'"></a></span>
    <input class="edit" data-bind="value: $root.someOtherValue, 
    event: { blur: $root.someOtherValue.stopEditing }" />
</div>

<hr>
<ul data-bind="foreach: myArray">
    <li>
        
<div data-bind="liveEditor: message">
    <span class="view"><a href="#" data-bind="click: message.edit, text: message() || 'Click to edit message 1'"></a></span>
    <input class="edit" data-bind="value: message,
    event: { blur: message.stopEditing }" />
</div>

    </li>
</ul>

CSS

.edit {
    display: none;    
}

.editing .edit {
    display: block;    
}

.editing .view {
    display: none;
}

JavaScript

ko.extenders.liveEditor = function (target) {
    target.editing = ko.observable(false);

    target.edit = function () {
        target.editing(true);
    };

    target.stopEditing = function () {
        target.editing(false);
    };
    return target;
};

ko.bindingHandlers.liveEditor = {
    init: function (element, valueAccessor) {
        var observable = valueAccessor();
        observable.extend({ liveEditor: this });
    },
    update: function (element, valueAccessor) {
        var observable = valueAccessor();
        ko.bindingHandlers.css.update(element, function () { return { editing: observable.editing }; });
    }
};

Message = function(data){
    var self = this;
    self.ID = data.ID;
    self.message = ko.observable(data.message);
};

var viewModel = function(){
    var self = this;
    self.mymessage = ko.observable();
    self.someOtherValue = ko.observable(); 
     
    self.myArray = ko.observableArray();
    var newmsg = new Message({
        ID: 1,
        message: 'first message'
    });
    self.myArray.push(newmsg);
    var newmsg2 = new Message({
        ID: 2,
        message: '2nd message'
    });
    self.myArray.push(newmsg2);

};

ko.applyBindings(new viewModel);