1

I have a form where say I have 2 controls. A select control which has been customized using bootstrap-selectpicker and a textbox which are strongly typed with a viewmodel. Below are the details of the project structure and here is the DEMO and validation is using jquery-validate

SampleViewModel.cs

public class SampleViewModel
{
        [Required(ErrorMessage="Please Select a Role")]
        //Not sure whether Required has to be assigned to RoleId or Roles
        public int RoleId { get; set; }
        public SelectList Roles { get; set; }
        [Required(ErrorMessage="Please Enter a name")]
        public string name{get;set;}
}

View

<div class="container">
    <div class="col-md-6 col-md-offset-3">
        <h1>Hello Stranger</h1>
            @using (Html.BeginForm("", "", FormMethod.Post, 
                             new { enctype = "multipart/form-data", id="frmSample" }))
            {
                <div class="form-group">
                    @Html.DropDownListFor(m => m.RoleId, Model.Roles, "Please Select your Country", new{@class="selectpicker"})
                    @Html.ValidationMessageFor(m=>m.RoleId)
                </div>
                <div class="form-group">
                    @Html.TextBoxFor(m => m.name, null, new{@class="form-control"}) 
                    @Html.ValidationMessageFor(m=>m.name)
                </div>
                <button type="button" class="btn btn-success submit">Ask</button>
            }
            <br/><br/>
        </div>
</div>

Controller

public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        SampleViewModel model=new SampleViewModel();
        model.Roles = new SelectList(new string[] { "Admin", "Manager" });
        return View(model);
    }
}

JS

$(document).ready(function(){
    $('.selectpicker').selectpicker();
    $("#frmSample").validate({
        onfocusout: true
    });
});
$('.submit').on('click',function(){
    if($("#frmSample").valid())
        alert(true);
});

Problem

  • The problem I am facing is my dropdown element doesn't get validated using jquery validation whereas my textbox gets validated. May be the problem is the way I am initializing or assigning the Required attribute to the particular model attribute and I am not sure for which one to assign the required attribute.
  • I have given onfocusout:true to validate on focus out but unless you type something on textbox and delete the content, the validation doesn't happen

Any help on this is highly appreciated.

Guruprasad J Rao
  • 29,410
  • 14
  • 101
  • 200
  • 1
    `.selectpicker()` I assume is a jquery plugin, which will be hiding the ` –  Sep 10 '15 at 11:24
  • Always with a good reply @StephenMuecke and I was expecting this.. :) But as per my research I need to set `ignore: []` on validation according to **[this question and answers](http://stackoverflow.com/questions/8466643/jquery-validate-enable-validation-for-hidden-fields)** but still this isn't helpful.. :( – Guruprasad J Rao Sep 10 '15 at 11:29
  • 1
    That should work fine, but your demo has `@Html.ValidationMessageFor(m=>m.Roles)` - it should be `RoleId` –  Sep 10 '15 at 11:32
  • 1
    I have [forked the fiddle here](https://dotnetfiddle.net/qsUa7R) to show that it works :) –  Sep 10 '15 at 11:34
  • @StephenMuecke.. I have re-forked your fiddle and yea that was a good catch. But now I am facing different issue. Even though if you select a Role its giving a different error.. Here is the **[fiddle](https://dotnetfiddle.net/9F6m4X)**. Any idea on this? – Guruprasad J Rao Sep 10 '15 at 11:36
  • That's because property `RoleId` is type of `int` but you `SelectList` is generated from `List` (an `int` cannot be bound to "Admin" or "Manager"). Either make it `string RoleId` or change the way you generate the `SelectList` (e.g. using the `Text` and `Value` properties of `SelectListItem` –  Sep 10 '15 at 11:40
  • Awesome.. :) Can you post this as answer please.. :) and also if possible both the approaches, [Text and Value].. :) plus any idea on 2nd problem? :) @StephenMuecke – Guruprasad J Rao Sep 10 '15 at 11:42
  • 1
    Have updated the [fiddle here](https://dotnetfiddle.net/qsUa7R). Need a short break so will add an answer a bit later. –  Sep 10 '15 at 11:50

1 Answers1

2

Your jquery plugin hides the <select> element that the DropDownListFor() method generates (display:none;) and adds its own html. By default hidden inputs are not validated by jquery.validate.js so you need to override this behavior using

$.validator.setDefaults({ 
  ignore: []
});

Note this will validate all hidden inputs so to just validate this one, you could use ignore: ":hidden:not('#RoleId')"

In addition, you have other errors. Your RoleId property is typeof int but your SelectList will generate options with values that are strings ("Admin" and "Manager") and cannot be bound to int. Either change the property to string RoleId or create a SelectList with values that are typeof int. For example if you have a Roles table with fields int ID and string Name, then

var roles = db.Roles();
model.Roles = new SelectList(roles, "ID", "Name");

or

model.Roles = roles.Select(r => new SelectListItem()
{
  Value = r.ID.ToString(),
  Text = r.Name
};

Refer DotNetFiddle