Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC3 Client side validation erratic/inconsistent

Server side validation works great but client side will not work on some fields.

Using :

"jquery-1.5.1.min.js"  
"modernizr-1.7.min.js"  
"jquery.validate.min.js"  
"jquery.validate.unobtrusive.min.js". 

HTML5 semantic markup

MVC3, Razor, Code First

Class Data Annotations:

using System.ComponentModel.DataAnnotations;

[Required, MaxLength(30, ErrorMessage = "First Name must be {1} characters or less")]
public string FirstName { get; set; }

[Range(20, 50, ErrorMessage = "{0} must be between {1} and {2}")]
public double Waist { get; set; }

View:

The view is strongly typed.

@using (Html.BeginForm()) { @Html.ValidationSummary(true)

    <span class="editor-label">  First Name </span>

    <span class="editor-field">

    @Html.EditorFor(model => model.FirstName)

    @Html.ValidationMessageFor(model => model.FirstName)

    </span><br /><br />

    <span class="editor-label">@Html.LabelFor(model => model.Waist): 20 to 50</span>

    <span class="editor-field">

    @Html.EditorFor(model => model.Waist)

    @Html.ValidationMessageFor(model => model.Waist)

    </span><br /><br />

Client side validation works for Waist but not FirstName. Server side works for both.

When I look at the source code Waist has a data-val-range.

data-val-range = "Waist must be between 20 and 50"

There is no data-val-range for FirstName.

Any help greatly appreciated.

Thank you,

Joe

I'm using IE9 64 bit.

Upon further investigation Required and String Length partially work. I changed the Dataannotation attributes to this.

  [Required(ErrorMessage = "First Name is required")]       [StringLength(30, MinimumLength = 2, ErrorMessage = "First Name must be {2} to {1} characters")]     public string FirstName { get; set; }

Now when I go to my edit view and clear the FirstName textbox and tab to the next I get no validation error. If I then enter one character I get the StringLength message, when I subsequently clear the field I then get the Required message. Getting closer but it is still not working correctly.

data-val-length= gets added to the source when I use StringLength

like image 452
Joe Avatar asked Mar 09 '12 06:03

Joe


1 Answers

MaxLength and MinLength doesn't work with client side validation. You could use StringLength instead:

[Required]
[StringLength(30, ErrorMessage = "First Name must be {1} characters or less")]
public string FirstName { get; set; }

And there's a MinimumLength property that you could set if you wanted to simulate the MinLength attribute:

[Required]
[StringLength(30, MinimumLength = 10, ErrorMessage = "First Name must be between 10 and 30 characters")]
public string FirstName { get; set; }

UPDATE:

It seems that you want to trigger the validation eagerly even if the form is not submitted. You could add the following script to achieve that:

<script type="text/javascript">
    $(function () {
        var settngs = $.data($('form')[0], 'validator').settings;
        settngs.onfocusout = function (element) { $(element).valid(); };
    });
</script>

UPDATE 2:

Here's a full example. Create a new ASP.NET MVC 3 project using the internet template.

Model:

public class MyViewModel
{
    [Required(ErrorMessage = "First Name is required")]
    [StringLength(30, MinimumLength = 2, ErrorMessage = "First Name must be {2} to {1} characters")]
    public string FirstName { get; set; }
}

Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel
        {
            FirstName = "foo"
        });
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        return View(model);
    }
}

View:

@model MyViewModel

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>
<script type="text/javascript">
    $(function () {
        var settngs = $.data($('form')[0], 'validator').settings;
        settngs.onfocusout = function (element) { $(element).valid(); };
    });
</script>

@using (Html.BeginForm())
{
    @Html.EditorFor(x => x.FirstName)
    @Html.ValidationMessageFor(x => x.FirstName)
    <button type="submit">OK</button>
}
like image 139
Darin Dimitrov Avatar answered Nov 02 '22 08:11

Darin Dimitrov