KO editable helper binding test

by whelkaholism

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
Allow (1 or 2): <input type="text" data-bind="value: AllowWhat" />
<br/>
<button data-bind="visible: !IsEditMode(), click: setEditMode">Edit</button>
<button data-bind="visible: IsEditMode, click: cancelEditMode">Cancel</button>
<hr/>
1:<br/>
<!-- ko with: Item -->
    <!-- ko conditionalEditable: $parent.IsEditMode() && $root.PERMS.check('CanEdit1') -->
    [<span data-bind="text: IsEditable"></span>]
    <span data-bind="visible: !IsEditable, text: Value1"></span>
        <!-- ko if: IsEditable -->
            <input type="text"  data-bind="value: Value1" />
        <!-- /ko -->
    <!-- /ko -->
<hr/>
2:<br/>
    <!-- ko conditionalEditable: $parent.IsEditMode() && $root.PERMS.check('CanEdit2')-->
        [<span data-bind="text: IsEditable"></span>]
        <span data-bind="visible: !IsEditable, text: Value2"></span>
        <!-- ko if: IsEditable -->
            <input type="text"  data-bind="value: Value2" />
        <!-- /ko -->
    <!-- /ko -->
<!-- /ko -->

JavaScript

ko.virtualElements.allowedBindings.conditionalEditable = true;

ko.bindingHandlers.conditionalEditable = {
	init:
		function(el, f_valueaccessor, allbindings, viewmodel, bindingcontext) 
		{		
            var newcontext = bindingcontext.extend(
                function() 
                { 
                    return { IsEditable: ko.unwrap(f_valueaccessor()) };
                }
            );
            
            ko.applyBindingsToDescendants(newcontext, el);
            
			return { controlsDescendantBindings: true }            
		}
};

function ItemModel()
{
    this.Value1 = ko.observable('Value 1');
    this.Value2 = ko.observable('Value 2');
}

function Model()
{
    var _this = this;
    
    this.AllowWhat = ko.observable('1');
    this.Item = ko.observable(new ItemModel());
    this.IsEditMode = ko.observable();
    
    this.PERMS = {
        check: 
            function(perm)
            {
                return perm == ('CanEdit' + _this.AllowWhat());
            }
    };       
    
    this.setEditMode = function()
    {
        _this.IsEditMode(true);
    };
    
    this.cancelEditMode = function()
    {
        _this.IsEditMode(false);
    };
}
    
var model = new Model();
ko.applyBindings(model);