0
votes

I'm making a readonly binding for knockout.

I've got it working nicely if I apply a binding to each element, as demonstrated in this fiddle: http://jsfiddle.net/paulinfrancis/wDJ9n/

However, I'd like to be able to set the binding to the view's root element, instead of on every form element:

<div data-bind="readonly: isReadonly">
    <!-- My form elements here -->
</div>

ko.bindingHandlers.readonlyView = {
init: function(element, valueAccessor){
    var isReadOnly = ko.unwrap(ko.unwrap(valueAccessor()));
        if (isReadOnly) {
            var $elements = $(':text, :radio, :checkbox, :input', $(element));
            $elements.each(function(){
                var domElement = this;

                ko.cleanNode(domElement);

                var $domElement = $(domElement);

                if ($domElement.is(':text')) {
                    //I need the observable bound to the textbox text
                } else if ($domElement.is(':radio')) {
                    //I need to determine if the radio btn is checked
                } else if ($domElement.is(':checkbox')) {
                    //I need to determine if the checkbox is checked
                } else if($domElement.is(':input')) {
                    $domElement.prop('disabled', true);
                }
            })
        }
    }
}

I'm not sure how to get the viewmodel property names that the elements are bound to, so that I can replace the existing elements with their readonly counterparts of my choice.

I can access the values I need using dataFor or contextFor, but I need to know the bound property names first:

ko.dataFor(domElement)['observableOne']()
ko.contextFor(domElement).$data['observableOne']()

I could of course parse the data-bind attribute on each element, but that seems dirty. Are there other better ways?

2

2 Answers

0
votes

Are you sure the Knockout "enable" or "disable" bindings would not work for you? These could all share the same "readOnly" observable flag.

http://knockoutjs.com/documentation/enable-binding.html

<p>
  Your cellphone number:
  <input type='text' data-bind="value: cellphoneNumber, enable: hasCellphone" />
</p>

...

var viewModel = {
    hasCellphone : ko.observable(false),
    cellphoneNumber: ""
};
0
votes

I think, based on your comment to 7zark7, that what you really want are the if and ifnot bindings:

<label>Had caffeine fix
  <img src="checkmark.png" data-bind="if: isReadOnly() && coffeeConsumed()">
  <input type="checkbox" data-bind="ifnot: isReadonly, checked: coffeeConsumed">
</label>