Search code examples
.net-corebootstrap-4knockout.jsasp.net-mvc-5

KnockoutJS Required (ifonly) not being honored when observable changes


I have 2 fields that I need to required based on another field in my model. The first field is functioning as desired, however the second field (similar logic) doesn't honor the required attribute. I have verified that the onlyif code is firing when the observable is changed. However the form allows submission if the required fields are not filled in.

JS Code

//Works As Expected
           self.model.RecentLocations.LastDayOnSite.extend({
                required: {
                    onlyIf: function () {
                        return ((!self.model.RecentLocations.IsLastDayOnSiteNA()) && (self.model.CaseType() != 'Quarantine'));
                    }
                }
            });

//Not Requiring Field as expected.
            self.model.ContactTracingStartDate.extend = ko.observable().extend({
                required: {
                    onlyIf: function () {
                        return (self.model.IsContactTracingRequired() == "Y");
                    }
                }
            });

HTML Code

//Works As Expected
                    <div class="col-md-2 form-group">
                        <i id="lastDayOnSite-asterisk" class="fas fa-asterisk fa-fw" style="font-size: 7px; color:red; vertical-align:super" data-bind="hidden: (model.RecentLocations.IsLastDayOnSiteNA() || model.CaseType() === 'Quarantine')"></i>
                        <label for="lastDayOnSite-datepicker_nfd">Last Day on Site</label>
                        <input type="text" class="form-control datepicker_nfd" id="lastDayOnSite-datepicker_nfd" data-bind="value: model.RecentLocations.LastDayOnSite, preventFutureDate: model.RecentLocations.LastDayOnSite, disable: model.RecentLocations.IsLastDayOnSiteNA()" data-emessage="Last Day on Site" placeholder="Date">
                    </div>

//Not Requiring Field as expected.
                    <div class="col-md-2 form-group">
                        <i id="contactTracingStartDate-asterisk" class="fas fa-asterisk fa-fw" style="font-size: 7px; color:red; vertical-align:super" data-bind="visible: (model.IsContactTracingRequired() === 'Y')"></i>
                        <label for="contactTracingStartDate-datepicker_nfd">Contact Tracing Start Date</label>
                        <input type="text" class="form-control datepicker_nfd" id="contactTracingStartDate-datepicker_nfd" 
                               data-bind="value: model.ContactTracingStartDate, 
                              preventFutureDate: model.ContactTracingStartDate, enable: (model.IsContactTracingRequired() === 'Y')" data-emessage="Contract Tracing Start Date" placeholder="Date">
                    </div>

Not Sure what I am missing here but I am fairly new to KnockoutJS but I can't see where the disconnect is. Any Help or suggestions would be appreciated.


Solution

  • The answer is change the line of code

    self.model.ContactTracingStartDate.extend = ko.observable().extend({
    

    TO:

    self.model.ContactTracingStartDate.extend({
    

    The problem was the observerable was reset by the ko.observable().extend instead of just extending the existing observable.