knockout icon indicating copy to clipboard operation
knockout copied to clipboard

Suggestion: Add possibility to declaratively disable optionsCaption

Open Elephant-Vessel opened this issue 8 years ago • 6 comments

When adding a optionsCaption to a select, the resulting option is selectable. I'm quite sure that the most frequent use case is for this to be disabled and I think that a optionsCaptionDisabled-binding would bring value as we don't have to muck around with custom logic in a afterRender.

Elephant-Vessel avatar Apr 20 '16 11:04 Elephant-Vessel

It's a good point, thanks for the thought @Elephant-Vessel .

One thing of note, you might be interested in doing the mucking around at the data layer with a computed-casting e.g. (in ES6)

// Add an extender for casting writes through a given function
function castWrite(obs, fn) {
  obs(fn(obs()))  // Cast any existing value
  return ko.computed({ read: obs, write: (v) => obs(fn(v)) })
}
ko.extenders.castWrite = castWrite

So you can then you can do something like this:

selected_option = ko.observable()
  .extend({ castWrite: (v) => v === undefined ? v : "Value When Caption Selected" })

Whenever selected_option is given undefined, i.e. the value when the caption is selected, then its value will be set to the given text.

brianmhunt avatar Apr 20 '16 12:04 brianmhunt

I can give you a use case of where I'd want to select the undefined option:

I have an app where you can select a specific restriction from a list of choicces, but you can go back to 'any' (which results in the undefined selection)... So I set the option text as 'Any XXXX' and if someone switches from a specific choice back to the 'any' i do want the null assigned to the model's optionValue.

-Chris

chrisknoll avatar Apr 20 '16 21:04 chrisknoll

Are there any news on this idea?

AnReZa avatar Jul 01 '19 11:07 AnReZa

Maybe this will help. The optionsCaption value can be an observable, which means it can be a computed observable.

this.selectedOption = ko.observable();
this.optionCaption = ko.pureComputed(function () {
    return this.selectedOption() === undefined ? "Select an option" : undefined;
}. this);

Alternatively, you can have this logic in the binding itself:

<select data-bind="
    options: optionsList, 
    value: selectedOption, 
    optionsCaption: !selectedOption() ? 'Select an option' : undefined"></select>

mbest avatar Jul 02 '19 05:07 mbest

@mbest Do I see that right, that your idea would remove the "please select" entry from the list, as soon as the user selects another option? That isn't quite what I normally do, but it's an alternative.

AnReZa avatar Jul 02 '19 11:07 AnReZa

Do I see that right, that your idea would remove the "please select" entry from the list

Yes. If the goal is to disallow selecting an undefined value after another has been selected, this will do the trick. Alternatively, the valueAllowUnset option could be used to allow an initial undefined value without the need for a "caption" value.

mbest avatar Jul 02 '19 16:07 mbest