Reputation: 2911
I'm using knockout validation and the error class is being added to the EndDate field but not the StartDate field when it't empty. the class caused the field to have a red background. I can't see any difference in the two fields. Something similar is happening on my other pages also.
Upon further investigation i realize it's always the first date field on the page that doesn't work. If I comment out the first one then the second stops working.
**Edit: as a hack I added this above the first date field
<input id="StartDate2" style="width: 140px;" type="hidden" data-bind="date: startDate">
and it works......but just feels really wrong.**
I have this at the beginning of my view model
ko.validation.init({
insertMessages: false,
decorateElement: true,
errorElementClass: "input-validation-error"
});
from my model
startDate: KnockoutObservable<Date> = ko.observable(null).extend({ required: { message: "Please enter a start date." }, simpleDate: { message: "Please enter a valid start date." } });
endDate: KnockoutObservable<Date> = ko.observable(null).extend({ required: { message: "Please enter an end date." }, simpleDate: { message: "Please enter a valid end date." } });
from the view
<li>
<label for="StartDate" class="required_label">Start Date</label>
<input id="StartDate" style="width: 140px;" type="text" data-bind="date: startDate, valueUpdate: 'afterkeydown', class:{'input-validation-error':(!startDate.isValid() && showErrors())}" ">
</li>
<li>
<label for="EndDate" class="required_label">End Date</label>
<input id="EndDate" style="width: 140px;" type="text" data-bind="date: endDate">
</li>
And here's our custome date binding handler
// mm/dd/yyyy format
ko.bindingHandlers.date = {
init: (element, valueAccessor) => {
$(element).mask("99/99/9999", { placeholder: "mm/dd/yyyy" });
ko.utils.registerEventHandler(element, "change", () => {
var value = valueAccessor();
if (moment(element.value).isValid()) {
value(element.value);
} else {
value(null);
}
});
ko.validation.makeBindingHandlerValidatable("date");
},
update: (element, valueAccessor, allBindingsAccessor) => {
var value = valueAccessor();
var allBindings = allBindingsAccessor();
var valueUnwrapped: any = ko.utils.unwrapObservable(value);
var pattern = allBindings.format || "MM/DD/YYYY";
var output = null;
if (valueUnwrapped !== null && valueUnwrapped !== undefined && valueUnwrapped.length > 0) {
output = moment(valueUnwrapped).format(pattern);
}
if ($(element).is("input") === true) {
$(element).val(output);
} else {
$(element).text(output);
}
}
};
Upvotes: 0
Views: 358
Reputation: 139758
You are making your date
custom binding "validation compatible" only in its init
function which will be only called when the binding is first used in the HTML. That is why the validation was only worked for the second input.
In order to fix this you have to move the ko.validation.makeBindingHandlerValidatable("date");
outside of your init
function and have it after the whole binding handler declaration
ko.bindingHandlers.date = {
//...
};
ko.validation.makeBindingHandlerValidatable("date");
Upvotes: 1