Saturday, April 23, 2011

Validation: set maxlength of a text box using MVC validation

Given a view model as below:
public class EmployeeFormViewModel
{
[Required(ErrorMessage = "*")]
    [StringLength(20,ErrorMessage = "Max length 20 characters")]
    public string Name { getset; }
}
And when client validation and unobtrusive JavaScript are enabled in a MVC 3 app in web.config in the root directory:

  <appSettings>
    <add key="ClientValidationEnabled" value="true"/> 
    <add key="UnobtrusiveJavaScriptEnabled" value="true"/> 
  appSettings>



A view:

<h2>Employee Formh2>
@using (Html.BeginForm("Employee","SaveEmployeeForm","Home",FormMethod.Post)){
    @Html.TextBoxFor(model=>model.Name)
    <br />
    <input type="submit" value="Submit" />
}

renders into Html on the client side:



<form action="/SaveEmployeeForm/Home?Length=4" method="post">
 <input data-val="true" 
  data-val-length="Name must not be longer than 20 characters long" 
  data-val-length-max="20" 
  data-val-required="*" 
  id="Name" 
  name="Name" 
  type="text" 
  value="" />    
 <br />
    <input type="submit" value="Submit" />
form>


This works great: it shows the error message when the user types a name longer than 20 characters and leaves the text box.  But it still allows the user to type in more than 20 letters before the focus leaves the text box.
  
What if I want to keep the user from keying in 20 characters? 

Well, the maxlength attribute of the input tag is the answer.  When it is set to 20, the user is only allowed to type in 20 characters.  I really don't want to keep setting "maxlength" to every single text box that I create and more importantly I want validation attribute "StringLength" to control this value.  But the generated code does not set the "maxlength" attribute.  How do I set the value of maxlength attribute using the value of data-val-length-max attribute?
A little JQuery sweetness does the trick:
<script language="javascript" type="text/javascript">
    $(document).ready
    (
        function () {
            $('input[data-val-length-max]').each
            (
                function (index) {
                    $(this).attr('maxlength', $(this).attr('data-val-length-max'));
                })
        });
script>
What the code above says is that for every input tag with the attribute of "data-val-length-max", use the value of it to set the value of "maxlength" attribute.

About Cullen

My photo
Christian, Father, Software Developer/Architect who enjoys technology and using it to make people's lives easier!

Followers