3
votes

I'm fairly new to knockoutjs, so there is a very good possibility this exists and I'm just not searching for the right thing.

I have a <select> element that can have multiple selections. On load, I want nothing to be selected, but I don't want to fire the validation at the user before they've even done anything. I can get the validation to fire if something is selected and unselected or a little 'none' button that empties the selected array. This is fine. My <select> looks like this:

<select multiple data-bind="options: PossibleValues, 
                            selectedOptions: SelectedValues,
                            validationCore: SelectedValues">
</select>

Like I said, if I explicitly empty the SelectedValues, then I get my client-side validation message. If I don't, then isValid() returns true and I don't see any messages.

So, how can I make the multiple select required and fail validation on submit if it is empty, but not highlight it as a problem on load?

EDIT

I tried to simplify my example for my question, but basically I have a ViewModel, which has a child ViewModel and that child has an object that is a ko.observable() and is also a ViewModel. It then has, get this, a child object that is a ko.observableArray() of ViewModels. This lowest level is where I'm attempting to see the validation errors (adding { deep: true } only yells about being too deep). The problem is that the lowest level - let's call it greatgrandchildVM - returns true when I call isValid() despite very clearly not being valid. Looping through greatgrandchildVM's array allows me to see that errors() has values in it.

Why are these not bubbling up and throwing isValid() to false? Obviously, I can hack together a for loop to iterate through my greatgrandchildVM array and do it myself, but I'm guessing there is a knockout way to do this and I'm just too new to know it yet.

3
Can you put a fiddle together? - Luis

3 Answers

0
votes

This is a very common problem with select elements.

After you set the SelectedValues to empty do this:

SelectedValues.isModified(false);

That should fix it

0
votes

Try using this syncModified extender.

Propagate forced validation and reset

If having a complex data structure, the use of ko.validation.group with the deep:true can often be a major pain. On the other hand, the complex data structure probably also includes arrays and objects that needs to be validated.

Note: This is an extender, not a validation rule.

0
votes

Use the 'optionsCaption' binding

<select multiple data-bind="options: PossibleValues, 
                        selectedOptions: SelectedValues,
                        validationCore: SelectedValues,
                        optionsCaption: 'emptyValueText'">
</select>

This gives adds an empty value which displays emptyValueText when no value is selected.

If no optionsCaption is specified, knockout just selects the first from your PossibleValues, which then goes on to validate the selection.

The optionsCaption can also be an observable, or just an empty string

Hope this helps