I have a drop down box including 'dog', 'cat', 'bear'. I want to show an input box in front of the select box when the user select 'cat' or 'dog'. So I am using the visible binding to do this:
<select data-bind="options:animals, value: animal"</select>
<input data-bind="value: description, visible: showDescription"/>
self.showDescription=ko.observable(false);
self.showOtherDescription = function() {
if(animal == 'cat' || animal == 'dog'){
self.showDescription=ko.observable(true);
}
}
It is working when the page is loaded. But when I change the option to 'bear' from the drop down it does not hide the input box. Does anybody have any idea?
The showDescription
observable really should be the computed function to drive the visibility of the <input>
element on the view:
self.showDescription = ko.computed(function(){
return (animal() === 'cat' || animal() === 'dog');
});
This is the way to go IMO:
var ViewModel = function() {
var self = this;
self.animals = ['', 'cat', 'dog', 'mouse', 'bird'];
self.animal = ko.observable('');
self.description = ko.observable('');
self.showOtherDescription = ko.computed(function() {
return self.animal() === 'cat' || self.animal() === 'dog';
});
};
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select data-bind="options: animals, value: animal"></select>
<input data-bind="value: description, visible: showOtherDescription"/>
It changes / adds a few things to your code:
- The
showDescription
is not needed, at least not in the context of the things you've posted;
- The
showOtherDescription
needs to be a computed
so it's updated when dependencies are updated;
showOtherDescription
should not have a "setter" function or side-effects that change other observables. If you do need such a setter, check out writeable computed observables;
- If you use
animal
as a two-way bound property, it needs to be an observable
and thus needs to be invoked as a function to get its value.
- I'm not sure how the code you posted would work, as refer to
animal
like animal == 'cat'
as well as use it in the View. I think it should probably be exposed publicly on the ViewModel, and as such you should refer to it as self.animal
.
I think you are assigning to the observable instead of using observable function invocation in the "showOtherDescription" function , try this
//self.showDescription=ko.observable(true);
self.showDescription(true);