简体   繁体   中英

MVC Unobtrusive validation for a dropdown using knockout.js?

I am using knockout.js to populate a dropdown:

<select data-bind="options: AvailableUsers, optionsText: 'DisplayName', value: SelectedUser, optionsCaption: '-- Select a User --'" data-val="true" data-val-required="You must select a user." id="SelectedUser" name="SelectedUser"></select>
<span class="field-validation-valid" data-valmsg-for="SelectedUser" data-valmsg-replace="true"></span>

and I am registering the validator to the form and having it called on the submithandler (I dont think this is related to the problem since the validation is executing):

$.validator.unobtrusive.parse("#UserProfileCreation");
$("#UserProfileCreation").data("validator").settings.submitHandler = mappedModel.save;

However when trying to submit the page, it always acts like the dropdown has no selected value. Even when I confirm via console that SelectedUser has a value. I have successfully done the same thing in other pages for textareas like so:

<textarea style="width: 100%; height: 50px; min-height: 30px;" name="GroupReply" id="GroupReply" data-bind="value: GroupReply" data-val="true" data-val-required="You must enter a reply."></textarea><br/><span class="field-validation-valid" data-valmsg-for="GroupReply" data-valmsg-replace="true"></span>

And that works fine. So I am not sure what I am missing for the dropdown, but whether I select an option or not, it keeps acting like it's blank and bringing up the validation error message. What am I missing?

I figured it out and it was quite simple due to my lack of understanding of how knockout handles dropdown's selected values.

My AvailableUsers in the KO View Model consisted of a list of KeyValueModels which were based off a C# MVC class (converted using the KO mapping plugin):

public class KeyValueModel{
   public Guid Id {get; set;}
   public string DisplayName {get; set;}
}

I simply needed to add optionsValue: 'Id' to the data-bind attribute of the dropdown. However it should be noted that this only works because I am passing a Guid as the SelectedUser property of the MVC View Model in the action parameter.

There have been times where I wanted to pass an entire javascript object that the dropdown selection represents to the MVC view model, in those cases this solution wouldn't work.

Note in console, if you do NOT have the optionsValue: 'Id' you select an option from the dropdown and type mappedModel.SelectedUser() you get:

Object {Id: "adb9ae2d-01c8-468d-96e6-06ec39039e29", DisplayName: "Johnson, John"}

Because knockout can store the whole selected object. HOWEVER, knockout does not set ANY value to the options in the dropdown in the actual HTML markup, they are all null (which is why the validation was failing).

If you do add optionsValue: 'Id' and type mappedModel.SelectedUser() into console, then you would simply get:

"adb9ae2d-01c8-468d-96e6-06ec39039e29"

Which for my purposes on this page is fine. As mentioned if you wanted to pass an entire object to the MVC action based on that selection, this setup would not work. You would probably have to do something like setup a hidden field and set it's value to the SelectedUser().Id and put the validation on that hidden field.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM