JSFiddle - React, Tailwind, and code Playground

by rniemeyer

HTML

<select data-bind="optionsPlus: choices, defaultCaption: 'choose one...', value: myValue"></select>

<button data-bind="click: setToOne">one</button>
<button data-bind="click: setToMany">many</button>

JavaScript

ko.bindingHandlers.optionsPlus = {
    preprocess: function(value, name, addBindingCallback) {
        addBindingCallback("optionsCaption", value + ".caption"); 

        return value;
    },
    init: function(element, valueAccessor) {
        var options = valueAccessor();

        //create an observable to track the caption
        if (options && !ko.isObservable(options.caption)) {
            options.caption = ko.observable();
        }
        
        return ko.bindingHandlers.options.init.apply(this, arguments);
    },
    update: function(element, valueAccessor, allBindings) {
        var options = valueAccessor(),
            value = ko.unwrap(options);

        options.caption(value.length === 1 ? null : allBindings.get("defaultCaption"));
        
        ko.bindingHandlers.options.update.apply(this, arguments);        
    }
    
};

var viewModel = {
    choices: ko.observableArray(["one", "two", "three"]),
    myValue: ko.observable(),
    setToOne: function() {
       this.choices(["one"]);   
    },
    setToMany: function() {
       this.choices(["one", "two", "three"]);
    }
};

ko.applyBindings(viewModel);