I'm using html5/Razor/MVC3 leveraging the Bootstrap template from Twitter. I want to have form validation that looks slick like they've documented (http://twitter.github.com/bootstrap/#forms). So if we take a look at how the standard boiler-plate MVC3 for account registration, the markup would look like:
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class="form-stacked" })) {
@Html.ValidationSummary(true, "Snap! Something went wrong")
<div>
<fieldset>
<legend>Account Information</legend>
<div class="clearfix error">
@Html.LabelFor(m => m.UserName)
<div class="input">
@Html.TextBoxFor(m => m.UserName)
<span class="help-inline">@Html.ValidationMessageFor(m => m.UserName)</span>
</div>
</div>
<div class="clearfix">
@Html.LabelFor(m => m.Email)
<div class="input">
@Html.TextBoxFor(m => m.Email)
<span class="help-inline">@Html.ValidationMessageFor(m => m.Email)</span>
</div>
</div>
<div class="clearfix">
@Html.LabelFor(m => m.Password)
<div class="input">
@Html.PasswordFor(m => m.Password)
<span class="help-inline">@Html.ValidationMessageFor(m => m.Password)</span>
</div>
</div>
<div class="clearfix">
@Html.LabelFor(m => m.ConfirmPassword)
<div class="input">
@Html.PasswordFor(m => m.ConfirmPassword)
<span class="help-inline">@Html.ValidationMessageFor(m => m.ConfirmPassword)</span>
</div>
</div>
</fieldset>
<div class="actions">
<button class="btn large primary" type="submit">Register</button>
</div>
</div>
What I want to do is have the container div inject the "error" class like I've hard-coded in the first input. (So upon entering the page, the div would have a class of "clearfix" but if that input block failed validation, it would tag it as "clearfix error"). I figure I'm going to have to update the div block to include an id of some sort and perhaps add a new data- attribute to the ValidationMessage. I don't have a problem extending the ValidationMessageFor helper. I'm just not 100% sure what the approach should be for extending the library that's there. Any suggestions on how to approach this?
TIA.
UPDATE:
I am thinking this approach is reasonable:
<div id="UserNameContainer" class="clearfix error">
@Html.LabelFor(m => m.UserName)
<div class="input">
@Html.TextBoxFor(m => m.UserName)
<span class="help-inline">@Html.ValidationMessageFor(m => m.UserName, null, new { @data_container = "UserNameContainer" })</span>
</div>
</div>
By decorating my validation message with a data-container name, I could then target the container div. Now I just need to figure out how to intercept the validation message.
The
$.validator.setDefaults
method solved this issue for me with Bootstrap from Twitter. I'm usingjquery.validate.js
andjquery.validate.unobtrusive.js
.Since unobtrusive validation on DOM ready scans your document and caches unobtrusive validation options for each form it encounters, it is needed to call the
$.validator.setDefaults
method before document scan occurs.Came accross the same issue. I am tackling it by adding and extesion to the HtmlHelper Class.
This is what I did for the ValidationSummary:
And in the .cshtml file I replace Html.ValidationSummary with this:
Remember to add the namespance of your extension class in the views folder web.config file.
I will post here later if I tackle the individual input item before you. HTH
You can integrate MVC3 validation with Bootstrap framework by adding the following javascript to your page (View)
Besides, on the Views (for example "Create.cshtml") make sure that the fields in the form are formatted as the following...
With this solution, it will most likely be enough to just add a javascript without edit the View.
I prefere to change the CSS of bootstrap. Just added the classes of jQuery validate in the right place. field-validation-error and input-validation-error
Rather than reinventing this particular wheel, check the validationEngine plugin available at http://www.position-absolute.com/articles/jquery-form-validator-because-form-validation-is-a-mess/.
You can customize the popup elements as you want, and it is trivial to connect to jQuery.validate.js.
I needed to solve this using Bootstrap 3.1 and Razor. This is what I used:
This is a combination of @german's answer and help from this post by "theBraindonor". Updated to use new Bootstrap 3 classes.