Reputation: 10193
On my webpage I have the following 2 inputs, the first one is textbox populated by autocomplete, and the second one is an ordinary textbox;
<td style="width: 380px">
<input type="text"
data-bind="enable: enableContract, jqAuto: {
source: getOptions,
value: SelectedContract,
labelProp: 'Label',
inputProp: JobDescription
}"
style="width: 99%;" />
</td>
<td style="width: 160px">
<input type="text"
data-bind="value: Description, enable: enableContract, event: {change: disableContractIfConditionsMet}"
style="width: 99%;" />
</td>
Just to complete the picture, when the autocomplete textbox is populated, the following 2 fields are populated;
self.ContractId = ko.pureComputed(function () {
if (self.SelectedContract() != null) {
return self.SelectedContract().Id;
}
return 0;
});
self.JobName = ko.pureComputed(function () {
if (self.SelectedContract() != null) {
return self.SelectedContract().JobName;
}
return "";
});
the value of the autocomplete textbox itself is set as follows;
self.SelectedContract = ko.observable(self.JobDescription());
What is not working is the change event on the second textbox. The intention is that when you enter the text "Sick" for example, it disables and clears the previous textbox (and set the ContractId to zero and JobName to empty - not coded yet). But this event is not executed when I leave the Description textbox. How do I get this to work?
Upvotes: 1
Views: 366
Reputation: 43881
It's hard to say why your code isn't working, but here's a snippet that uses the change
event to do what you describe, at least as far as disabling. I don't understand the jqAuto
binding, so I don't know how to clear the value.
self = {
SelectedContract: ko.observable(),
JobDescription: ko.observable(),
enableContract: ko.observable(true),
Description: ko.observable('descrip'),
disableContractIfConditionsMet: () => {
if (self.Description() === 'Sick') {
self.enableContract(false)
}
}
};
self.ContractId = ko.pureComputed(function() {
if (self.SelectedContract() != null) {
return self.SelectedContract().Id;
}
return 0;
});
self.JobName = ko.pureComputed(function() {
if (self.SelectedContract() != null) {
return self.SelectedContract().JobName;
}
return "";
});
ko.applyBindings(self);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div>
<input type="text" data-bind="enable: enableContract, jqAuto: {
source: getOptions,
value: SelectedContract,
labelProp: 'Label',
inputProp: JobDescription
}" style="width: 99%;" />
</div>
<div>
<input type="text" data-bind="value: Description, enable: enableContract, event: {change: disableContractIfConditionsMet}" style="width: 99%;" />
</div>
Upvotes: 1
Reputation: 23372
I'd suggest not using the change
event, but subscribing to the value
bound observable instead.
var disableContractIfConditionsMet = function(currentDescription) {
// Perform condition logic and set enable/disable states here
};
this.Description = ko.observable();
this.Description.subscribe(disableContractIfConditionsMet);
You can probably even create an enabled
/disabled
computed method that automatically updates based on the value of Description
. I don't really understand the exact UI requirements though, so it's hard for me to write those...
An example of how you'd use a computed:
ko.applyBindings(new function() {
var REQUIRED_VALUE = "test";
this.secondInputValue = ko.observable("");
this.firstInputEnabled = ko.computed(function() {
return this.secondInputValue()
.toLowerCase()
.includes(REQUIRED_VALUE);
}, this);
});
input {
display: block;
margin-bottom: 1rem;
}
input:disabled {
background: rgba(0,0,0,0.2);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input data-bind="enable: firstInputEnabled">
<label>
This input enables the first one if you type something containing "test"
<input data-bind="textInput: secondInputValue">
</label>
Upvotes: 3