Question

i'm using knockout 2.2.1. I have a set of 3 check boxes to concatenate to get the corresponding values all together:

<fieldset data-role="controlgroup" id="top-colours" data-bind="topColoursLabel: { topColoursRed,topColoursBlue,topColoursGreen }">
    <legend>Top Colours:</legend>
    <input type="checkbox" name="top-colours-red" data-bind="checked: topColoursRed" id="tc-check-1" />
    <label for="tc-check-1">Red stripes</label>
    <input type="checkbox" name="top-colours-blue" data-bind="checked: topColoursBlue" id="tc-check-2" />
    <label for="tc-check-2">Blue stripes</label>
    <input type="checkbox" name="top-colours-green" data-bind="checked: topColoursGreen" id="tc-check-3" />
    <label for="tc-check-3">Green stripes</label>
</fieldset>

The result shall be for example: "Red stripes, Blue stripes". My viewmodel is as follows:

function ColoursViewModel() {
    var self = this;
    self.template = "coloursView";
    self.topColoursRed = ko.observable(false);
    self.topColoursBlue = ko.observable(false);
    self.topColoursGreen = ko.observable(false);
    self.topColoursDescription = ko.observable("");
}

How shall be the custom bindings to achieve this? I try something like that:

ko.bindingHandlers.topColoursLabel = {
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        ko.utils.unwrapObservable(valueAccessor());
        // ...
        var checkText = '...';
        viewModel.topColoursDescription(checkText);
    }
};

I'm not able to find out how to pass the array to my custom bindings to subscribe to the values of the 3 check boxes, because I'm noob to knockout.

It seems to me, that a declaration like:

data-bind="topColoursLabel: { topColoursRed,topColoursBlue,topColoursGreen }"

would be great to achieve this, but i'm searching the right way to do that.

Note: i cannot use a computed observable here, because i need to get some other properties from element - i mean the label-for text - so a custom binding is needed.

Can someone help?

UPDATED jsFiddle: http://jsfiddle.net/Sx87j/

Was it helpful?

Solution

Actually, custom binding handler is not what you really need. You should implement your self.coloursDescription as computed observable which will track checkbox changes and return currently selected stripes:

self.topColoursDescription = ko.computed(function(){
    var colors = [];
    if (self.topColoursRed())   colors.push('Red stripes');
    if (self.topColoursBlue())  colors.push('Blue stripes');
    if (self.topColoursGreen()) colors.push('Green stripes');
    return colors.join(', ');
});

Also remove all tracks of your custom bindings from markup and you will get something like this: http://jsfiddle.net/h7Bmb/8/

Update

I can make your updated fiddle to work with top colours. Making it work with bottom colors too looks a bit complicated with your current approach.

Enumerate all linked color observables in your binding:

<fieldset data-role="controlgroup" id="top-colours" data-bind="topColoursLabel: [ topColoursRed, topColoursBlue, topColoursGreen ]">

Change your custom binding code (the line where ko.utils.unwrapObservable is called):

ko.utils.arrayForEach(valueAccessor(), ko.utils.unwrapObservable);

Example: http://jsfiddle.net/Sx87j/1/

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top