https://stackoverflow.com/questions/44265973/element-not-updating-error-state-when-value-changed-via-javascript
by jlspake
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<div class="col-md-6 form-group has-feedback" data-bind="css: { 'has-error': Term.hasError }">
<label for="ddlTerm" class="col-form-label" style="padding: 0;">Term</label>
<div class="input-group input-group-sm">
<input type="text" data-bind="textInput: Term" class="form-control input-sm" id="tbTerm" />
<div class="input-group-btn">
<button type="button" class="btn btn-warning dropdown-toggle" data-toggle="dropdown">Select <span class="caret"></span></button>
<ul class="dropdown-menu pull-right">
<li><a data-bind="click: function(){set_Term(12)}">12 Months</a></li>
<li><a data-bind="click: function(){set_Term(24)}">24 Months</a></li>
<li><a data-bind="click: function(){set_Term(36)}">36 Months</a></li>
<li><a data-bind="click: function(){set_Term(48)}">48 Months</a></li>
<li><a data-bind="click: function(){set_Term(60)}">60 Months</a></li>
<li><a data-bind="click: function(){set_Term(72)}">72 Months</a></li>
<li><a data-bind="click: function(){set_Term(84)}">84 Months</a></li>
</ul>
</div>
</div>
<span data-bind='visible: Term.hasError, text: Term.validationMessage' class="help-block"></span>
</div>
JavaScript
var viewModel = function(){
var self = this;
self.Term = ko.observable('').extend({ required: 'Term is required' });
self.set_Term = function(months) {
self.Term(months);
};
}
ko.extenders.required = function(target, overrideMessage) {
//add some sub-observables to our observable
target.hasError = ko.observable();
target.validationMessage = ko.observable();
//define a function to do validation
function validate(newValue) {
target.hasError(newValue ? false : true);
target.validationMessage(newValue ? "" : overrideMessage || "This field is required");
}
//initial validation
validate(target());
//validate whenever the value changes
target.subscribe(validate);
//return the original observable
return target;
};
ko.applyBindings(new viewModel());