Form validation with Bootstrap, Formvalidation.io and ASP.NET
Formvalidation.io is an excellent JavaScript/jQuery plugin to validate form fields designed with Bootstrap, Foundation, Pure, SemanticUI, UIKit and others.
In this tutorial I'll cover a small example which uses regular ASP.NET Web Forms with Web API, but the same result can be achieved with any other technology, such as ASP.NET MVC.
First, you need to download the plugin and add the necessary JavaScript references, I added these in my Site.master file.
<!-- Bootstrap CSS v3.0.0 or higher -->
<link rel="stylesheet" href="/vendor/bootstrap/css/bootstrap.min.css">
<!-- FormValidation CSS file -->
<link rel="stylesheet" href="/vendor/formvalidation/dist/css/formValidation.min.css">
<!-- jQuery v1.9.1 or higher -->
<script type="text/javascript" src="/vendor/jquery/jquery.min.js"></script>
<!-- Bootstrap JS -->
<script src="/vendor/bootstrap/js/bootstrap.min.js"></script>
<!-- FormValidation plugin and the class supports validating Bootstrap form -->
<script src="/vendor/formvalidation/dist/js/formValidation.min.js"></script>
<script src="/vendor/formvalidation/dist/js/framework/bootstrap.min.js"></script>
<!-- Note, this file is different from the boostrap.min.js provided by the Bootstrap framework! -->
From the version 4.0 version of the .NET framework onwards, we can set our ClientIDMode to static, which means that the ClientID value is set to the value of the ID property, a very different approach to the previous predictable property, which named our controllers with a mixture of the ClientID with the parent container id.
To do this, I set the whole page to static, although this can be done to individual controllers.
<%@ Page Title="Add User" Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.Master" CodeBehind="AddUser.aspx.cs" Inherits="MyProject.AddUser" ClientIDMode="Static" %>
In the file containing the form tag, which usually is the Site.Master file, be sure to assign an ID to it:
<form runat="server" id="GlobalForm">
<!-- The rest of the page goes here -->
</form>
After this, we need to create our form. I created it in a file called AddUser.aspx.
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<h2>Users</h2>
<!-- Be sure to use the form-group classes, otherwise FormValidation won't recognize the inputs -->
<div class="form-horizontal">
<div class="form-group">
<asp:Label runat="server" AssociatedControlID="UserName" CssClass="col-md-2 control-label">User Name</asp:Label>
<div class="col-md-7">
<asp:TextBox runat="server" ID="UserName" CssClass="form-control" />
</div>
</div>
<div class="form-group">
<asp:Label ID="Label1" runat="server" AssociatedControlID="Name" CssClass="col-md-2 control-label">Name</asp:Label>
<div class="col-md-7">
<asp:TextBox runat="server" ID="Name" CssClass="form-control" />
</div>
</div>
<div class="form-group">
<asp:Label ID="Label2" runat="server" AssociatedControlID="LastName" CssClass="col-md-2 control-label">Last Name</asp:Label>
<div class="col-md-7">
<asp:TextBox runat="server" ID="LastName" CssClass="form-control" />
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<button type="submit" class="button" runat="server" id="Add" onclick="if (!isValidForm()) return false;" >Register</button>
</div>
</div>
</div>
</asp:Content>
This code creates a form with 3 basic input fields and an Add button. I created the text fields with the asp:TextBox syntax, but they can be created with a regular HTML 5 input syntax.
I also added an onClick function which indicates our button's action once it is clicked. Please note that it is better overall practice to do this with a Callback Function.
Then, I created the addUser.js file, and then I added the reference at the bottom of the AddUser.aspx page.
<script src="addUser.js" type="text/javascript"></script>
In our addUser.js file, we configure our form:
$(document).ready(function () {
$('#GlobalForm').formValidation({
framework: 'bootstrap',
submitButtons: $('#Add'),
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh'
},
live: 'enabled',
message: 'This value is not valid',
submitButtons: 'button[type="submit"]',
trigger: null,
fields: {
UserName: {
selector: '#UserName',
message: 'The username is not valid',
validators: {
notEmpty: {
message: 'The user name is required.'
},
remote: {
message: 'The user name already exists',
url: '../api/Users/VerifyUser',
data: function (validator) {
return {
UserName: $('#UserName').val()
};
},
type: 'POST',
}
}
},
Name: {
selector: '#Name',
message: 'The name is not valid',
validators: {
notEmpty: {
message: 'Name is required.'
}
}
},
LastName: {
selector: '#LastName',
message: 'The last name is not valid.',
validators: {
notEmpty: {
message: 'Last name is required.'
}
}
}
}
});
});
The above code validates the UserName, Name and LastName input fields. All of them are verified so that they are not empty, and the UserName is verified with a POST method in order to see if it is not already in use. The important aspect is that we are using the selector property, which indicates what input field is each one (it is done this way since we used the asp:Textbox for our inputs, with the HTML 5 input property that step would not have been necessary).
Lastly, I added a function in addUser.js that verifies if the form is correct, and if it is, to add our user.
// This method is called by the Add button when it's clicked
function isValidForm() {
var formValidation = $('#GlobalForm').data('formValidation');
// Checks if the form is valid
if (formValidation.isValid()) {
var User = ({ UserName: $('#UserName').val(), Name: $('#Name').val(), LastName: $('#LastName').val() });
$.ajax({
type: "POST",
data: JSON.stringify(User),
url: "../api/Users/PostUser",
contentType: "application/json",
success: function (response) {
// Success code goes here
},
error: function (response) {
// Error code goes here
}
});
}
else {
formValidation.validate();
}
};
And that's pretty much it. The trick of integrating the FormValidation.io plugin into ASP.NET is the names of our controllers, the site's documentation contains another example with a different approach.