Question

I have a set of check boxes, each bound to a custom "checked" handler:

    <input type="checkbox" name="colours-red" data-bind="jqmCheckbox: colourRed" id="check-1" />
    <input type="checkbox" name="colours-green" data-bind="jqmCheckbox: colourGreen" id="check-2" />
    <input type="checkbox" name="colours-blue" data-bind="jqmCheckbox: colourBlue" id="check-3" />

My view model is very easy:

this.colourRed = ko.observable(false);
this.colourGreen = ko.observable(false);
this.colourBlue = ko.observable(false);

Now, i try to extend the colours as follows, to get it automatically updated. I need other subscribers to get notified, if this is changing:

ko.extenders.elementId = function (target, option) {
    target.elId = ko.observable();

    function setElementId(target, option) {
        target.elId(option);
    }
    target.subscribe(setElementId);
    return target;
};

Inside the custom binding i could get the element id:

ko.bindingHandlers.jqmCheckbox = {
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        ko.bindingHandlers.checked.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
        // ...set this valueAccessor extender ?
    }
};

But I'm not able to get this to work, and also i dont know if this is possible, anyway. How can i set my extender in the custom binding handler, where the element is available as parameter?

This is the jsFiddle: http://jsfiddle.net/Tk2FZ/1/

Thanks in advance

Was it helpful?

Solution 2

SOLVED: after some time spent again to get this to work, i found the problem. Here is the final working fiddle: http://jsfiddle.net/z9qZc/

I put this answer to my self, just in case this two cents can help other people to spare time. I find this extender is a generic solution, and maybe not so bad. Let me know what you think about.

The answer is (now) clear: initialize the extender (as in most of cases it would be enough to read the documentation with care...).

self.colourRed = ko.observable(true).extend({elementId:""});
self.colourGreen = ko.observable(false).extend({elementId:""});
self.colourBlue = ko.observable(false).extend({elementId:""});

Thanks to Cyanfish that pointed out that my first try was bloated with unnecessary code, and helped my a lot. Thanks to all knockout people who made this brilliant artwork to help us all.

OTHER TIPS

I wouldn't bother with an extender; just set the elId property inside the binding handler.

ko.bindingHandlers.jqmCheckbox = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        if (!valueAccessor().elId) {
            valueAccessor().elId = ko.observable();
        }
        valueAccessor().elId(element.id);
        return ko.bindingHandlers.checked.init.apply(this, arguments);
    },
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        return ko.bindingHandlers.checked.update.apply(this, arguments);
    }
};

The code is inside of init because that's called when the binding is initialized on a particular element.

EDIT

If you need the observable to be available immediately, you can use an extender for that (in addition to the code above). The observable will then be updated when the binding is initialized.

ko.extenders.elementId = function (target, option) {
    target.elId = ko.observable();
    return target;
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top