Knockout Validation evaluates immediately on load
Asked Answered
P

3

21

I'm using MVC, Knockout, and Knockout Validation to validate my view model.

I'm running into an issue where the validation for view model properties are firing immediately upon loading. In other words, "This field is required" shows up next to my inputs before a user has attempted to change their values.

This problem is specifically happening with dropdown (select) controls.

I'm guessing that this is a problem that I've created by somehow unintentionally changing/accessing/mutating the observable in another part of my javascript code. However, I don't know how to track this down.

Is there a way that I can somehow subscribe or track the even that fires that causes validation in Knockout Validation? I just need to know why this is firing in the way it is. I'm pretty confident that the value of the isValid() function is consistently false.

Here's a sample of how my HTML is setup on page load, unmolested:

<select class="highlightable validationElement" name="obsstate" data-bind="value: standardAnswers.ans106_1.value" required="true">
    <option value="">-- Select -- </option>
        <option value="AK">AK</option>
        <option value="AL">AL</option>
        etc...

</select>

As displayed on my local machine

Philipson answered 3/12, 2012 at 20:27 Comment(0)
P
9

I figured out this issue on my own.

The problem exists between the razor engine templating the select options, and then later binding the value of the selected element to Knockout.

Despite the fact that there is no user-inputted value in the select box, the default value, the "--select--" actually contains a value. In my case it was an empty string. Therefore, when I applied the knockout bindings, my viewmodel property was "updated" with the empty string value, and therefore validation fired.

To get around this in my case I set the default value of my model to be an empty string. Therefore when the bindings are applied, there is no valueHasMutated event fired on the Knockout observable, and thus no validation.

Philipson answered 4/12, 2012 at 0:42 Comment(1)
I set the model to empty string but its still firing on load. One of the things I noticed is that optionsCaptions: 'Select...' does put in the item, but the value is not value="" its just <option value>Select...</option>Jadajadd
Z
21

After applying the bindings for the viewmodel. Then for that viewmodel make showAllMessages as false

Example

YourViewmodelname.errors.showAllMessages(false);
Zohara answered 6/11, 2013 at 9:42 Comment(3)
Slightly different syntax that was useful in my situation: ko.validation.group(viewModel()).showAllMessages(false);Plectognath
@JonathanStrate Thanks for posting that - In my case viewmodel.errors was undefined, and your version worked.Plucky
After ko.applyBindings(...), group the errors and call the method: ko.validation.group(yourViewModel, { deep: true }).showAllMessages(false);Stelly
G
11

Quoting KO page.... ( http://knockoutjs.com/documentation/options-binding.html )

KO will prefix the list of items with one that displays the text “Select an item…” and has the value undefined. So, if myChosenValue holds the value undefined (which observables do by default), then the dummy option will be selected. If the optionsCaption parameter is an observable, then the text of the initial item will update as the observable’s value changes.

So, I solved it by setting "undefined" when defining the property, see example below:

self.myProperty = ko.observable(undefined).extend({
    required :  {"Field Required"}
});

Hope this helps...

Geriatric answered 22/5, 2013 at 12:39 Comment(0)
P
9

I figured out this issue on my own.

The problem exists between the razor engine templating the select options, and then later binding the value of the selected element to Knockout.

Despite the fact that there is no user-inputted value in the select box, the default value, the "--select--" actually contains a value. In my case it was an empty string. Therefore, when I applied the knockout bindings, my viewmodel property was "updated" with the empty string value, and therefore validation fired.

To get around this in my case I set the default value of my model to be an empty string. Therefore when the bindings are applied, there is no valueHasMutated event fired on the Knockout observable, and thus no validation.

Philipson answered 4/12, 2012 at 0:42 Comment(1)
I set the model to empty string but its still firing on load. One of the things I noticed is that optionsCaptions: 'Select...' does put in the item, but the value is not value="" its just <option value>Select...</option>Jadajadd

© 2022 - 2024 — McMap. All rights reserved.