Question

I have two select inputs with same options and changing value in first select should disable all previous options in second (including) selected one, and set the value of second select to first next value. I've setup a working fiddle here.

<select data-bind="options: selectList, value: firstSelect"></select>
<select data-bind="options: selectList, value: secondSelect, minVal: firstSelect"></select>

I have created custom binding handler:

ko.bindingHandlers.minVal = {
    update: function (element, valueAccessor) {
        var firstValue = ko.utils.unwrapObservable(valueAccessor());
        var firstNext=null;
        $(element).children().each(function () {
            var $this = $(this);
            if ($this.val() <= firstValue) {
                $this.attr('disabled', 'disabled');
            } else {
                if (firstNext==undefined){
                    firstNext=$this.val();
                }                
            }
        });
        $(element).val(firstNext).trigger('change');
    }
};

And it works in case that you change first select it will disable all previous options in second, and set the value of second to first next value, but the problem is when user wants to change value in second, it could not do because of update from custom binding is always setting up value according to first. So my question is how to know in custom binding how is updated value, from changing valueAccessor() observable or manually by changing second select?

Was it helpful?

Solution 2

I've find a solution, it was pure logical issue. Just before updating value ask if new value (selected manually form changed select option) is bigger than value that should be selected from custom binding and you will be able to change value to one that you want.

if (firstNext >= $(element).val()) {
    $(element).val(firstNext);
    $(element).change();
}

Here is updated fiddle: http://jsfiddle.net/9gGjq/4/

OTHER TIPS

I think the issue is with the triggering of the change event.

I took a slightly different approach to slice the array as a computed value and bind the second list to that.

Html:

<select data-bind="options: selectList, value: firstSelect"></select>
<select data-bind="options: secondSelectList, value: secondSelect"></select>

Javascript:

ViewModel = function () {
    var self = this;
    self.firstSelect = ko.observable();
    self.secondSelect = ko.observable();
    self.selectList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    self.secondSelectList = ko.computed(function(){
        return self.selectList.slice(self.firstSelect(), self.selectList.length);
    }, self);
};

var vm = new ViewModel();
ko.applyBindings(vm);

Fiddle here:

http://jsfiddle.net/QDpPk/

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