Introduction
In this article. I will demonstrate you how to validate HTML 5 textbox, textarea, select, checkbox, radio button and file upload using bootstrap 4. Validation provides valuable, actionable feedback to your users with HTML 5 form validation available in all our supported browsers. Choose from the browser default validation feedback, or implement custom messages with our built-in classes and starter JavaScript.
Important point to be remember when you form validation
- HTML form validation is applied via CSS’s two pseudo-classes, :invalid and :valid. It applies to <input>, <select>, and <textarea> elements.
- Bootstrap scopes the :invalid and :valid styles to parent .was-validated class, usually applied to the <form>. Otherwise, any required field without a value shows up as invalid on page load. This way, you may choose when to activate them (typically after form submission is attempted).
- As a fallback, .is-invalid and .is-valid classes may be used instead of the pseudo-classes for server side validation. They do not require a .was-validated parent class.
- Due to constraints in how CSS works, we cannot (at present) apply styles to a <label>that comes before a form control in the DOM without the help of custom JavaScript.
- All modern browsers support the constraint validation API, a series of JavaScript methods for validating form controls.
- Feedback messages may utilize the browser defaults (different for each browser, and unstylable via CSS) or our custom feedback styles with additional HTML and CSS.
- You may provide custom validity messages with setCustomValidity in JavaScript.
Custom styles in bootstrap 4
For custom Bootstrap form validation messages, you’ll need to add the novalidate Boolean attribute to your <form>. This disables the browser default feedback tooltips, but still provides access to the form validation APIs in JavaScript.
To use Bootstrap 4 form validation in your project, you need to have the following downloaded or cdn link scripts,
- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
JavaScript require for form validation
- <script type="text/javascript">
- (function () {
- 'use strict';
- window.addEventListener('load', function () {
- var form = document.getElementById('needs-validation');
- form.addEventListener('submit', function (event) {
- if (form.checkValidity() === false) {
- event.preventDefault();
- event.stopPropagation();
- }
- form.classList.add('was-validated');
- }, false);
- }, false);
- })();
- </script>
Bootstrap 4 form validation example
- <!DOCTYPE html>
- <html>
- <head>
- <title>form validation</title>
- <meta charset="utf-8" />
- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
- <script type="text/javascript">
- (function () {
- 'use strict';
- window.addEventListener('load', function () {
- var form = document.getElementById('needs-validation');
- form.addEventListener('submit', function (event) {
- if (form.checkValidity() === false) {
- event.preventDefault();
- event.stopPropagation();
- }
- form.classList.add('was-validated');
- }, false);
- }, false);
- })();
- </script>
- </head>
- <body>
- <div class="container py-5">
- <div class="row">
- <div class="offset-md-2 col-md-8 offset-md-2">
- <div class="card">
- <div class="card-header bg-primary text-white">
- <h4 class="card-title text-uppercase">Employee Form</h4>
- </div>
- <div class="card-body">
- <form id="needs-validation" novalidate>
- <div class="row">
- <div class="col-sm-6 col-md-6 col-xs-12">
- <div class="form-group">
- <label for="firstname">First Name</label>
- <input type="text" id="firstname" placeholder="First Name" class="form-control" aria-describedby="inputGroupPrepend" required />
- <div class="invalid-feedback">
- Please enter first name.
- </div>
- </div>
- </div>
- <div class="col-sm-6 col-md-6 col-xs-12">
- <div class="form-group">
- <label for="lastname">Last Name</label>
- <input type="text" id="lastname" placeholder="Last Name" class="form-control" aria-describedby="inputGroupPrepend" required />
- <div class="invalid-feedback">
- Please enter last name.
- </div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-4 col-md-4 col-xs-12">
- <div class="form-group">
- <label for="Gender">Gender</label>
- <select class="custom-select" required>
- <option value="">Select Gender</option>
- <option value="1">Male</option>
- <option value="2">Female</option>
- </select>
- <div class="invalid-feedback">Please choose gender</div>
- </div>
- </div>
- <div class="col-sm-4 col-md-4 col-xs-12">
- <div class="form-group">
- <label for="email">Email address</label>
- <input type="email" class="form-control" id="email" placeholder="email address" aria-describedby="inputGroupPrepend" required>
- <div class="invalid-feedback">
- Please provide a valid email.
- </div>
- </div>
- </div>
- <div class="col-sm-4 col-md-4 col-xs-12">
- <div class="form-group">
- <label for="phonenumber">Mobile Number</label>
- <input type="tel" pattern="^\d{10}$" class="form-control" id="phonenumber" placeholder="Mobile Number" aria-describedby="inputGroupPrepend" required>
- <div class="invalid-feedback">
- Please enter 10 digit mobile number.
- </div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12 col-md-12 col-xs-12">
- <div class="form-group">
- <label>Mandatory Skills</label>
- </div>
- <div class="form-check-inline">
- <div class="custom-control custom-radio ">
- <input type="radio" class="custom-control-input" id="html" aria-describedby="inputGroupPrepend" name="radio-html" required>
- <label class="custom-control-label" for="html">HTML 5</label>
- <div class="invalid-feedback">Choose skill</div>
- </div>
- </div>
- <div class="form-check-inline">
- <div class="custom-control custom-radio ">
- <input type="radio" class="custom-control-input" id="javascript" aria-describedby="inputGroupPrepend" name="radio-javascript" required>
- <label class="custom-control-label" for="javascript">JavaScript</label>
- <div class="invalid-feedback">Choose skill</div>
- </div>
- </div>
- <div class="form-check-inline">
- <div class="custom-control custom-radio ">
- <input type="radio" class="custom-control-input" id="csharp" aria-describedby="inputGroupPrepend" name="radio-csharp" required>
- <label class="custom-control-label" for="csharp">C# Programming</label>
- <div class="invalid-feedback">Choose skill</div>
- </div>
- </div>
- <div class="form-check-inline">
- <div class="custom-control custom-radio">
- <input type="radio" class="custom-control-input" id="aspdotnet" aria-describedby="inputGroupPrepend" name="radio-aspdotnet" required>
- <label class="custom-control-label" for="aspdotnet">ASP.NET</label>
- <div class="invalid-feedback">Choose skill</div>
- </div>
- </div>
- <div class="form-check-inline">
- <div class="custom-control custom-radio">
- <input type="radio" class="custom-control-input" id="MVC" name="radio-MVC" required>
- <label class="custom-control-label" for="MVC">ASP.NET MVC</label>
- <div class="invalid-feedback">Choose skill</div>
- </div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12 col-md-12 col-xs-12">
- <div class="form-group">
- <label>Profile Picture</label>
- <div class="custom-file">
- <input type="file" class="custom-file-input" id="validatedCustomFile" required>
- <label class="custom-file-label" for="validatedCustomFile">Choose file...</label>
- <div class="invalid-feedback">Choose file for upload</div>
- </div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12 col-md-12 col-xs-12">
- <div class="form-group">
- <label for="address">Address</label>
- <textarea class="form-control" rows="3" id="address" aria-describedby="inputGroupPrepend" required></textarea>
- <div class="invalid-feedback">please enter address</div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12 col-md-12 col-xs-12">
- <div class="form-group">
- <div class="form-check">
- <input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
- <label class="form-check-label" for="invalidCheck">
- Agree to terms and conditions
- </label>
- <div class="invalid-feedback">
- You must agree before submitting.
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12 col-md-12 col-xs-12">
- <div class="float-right">
- <button class="btn btn-danger rounded-0" type="submit">Cancel</button>
- <button class="btn btn-primary rounded-0" type="submit">Register</button>
- </div>
- </div>
- </div>
- </form>
- </div>
- </div>
- </div>
- </div>
- </div>
- </body>
- </html>
Output
Screenshot-1
Screenshot-2
Screenshot-3

Tooltips
If your form layout allows it, you can swap the
.{valid|invalid}-feedback classes for .{valid|invalid}-tooltip classes to display validation feedback in a styled tooltip. Be sure to have a parent with position: relative on it for tooltip positioning. In the example below, our column classes have this already, but your project may require an alternative setup.Bootstrap form validation with tooltips example
- <!DOCTYPE html>
- <html>
- <head>
- <title>form validation</title>
- <meta charset="utf-8" />
- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
- <script type="text/javascript">
- (function () {
- 'use strict';
- window.addEventListener('load', function () {
- var form = document.getElementById('needs-validation');
- form.addEventListener('submit', function (event) {
- if (form.checkValidity() === false) {
- event.preventDefault();
- event.stopPropagation();
- }
- form.classList.add('was-validated');
- }, false);
- }, false);
- })();
- </script>
- </head>
- <body>
- <div class="container py-5">
- <div class="row">
- <div class="offset-md-2 col-md-8 offset-md-2">
- <div class="card">
- <div class="card-header bg-primary text-white">
- <h4 class="card-title text-uppercase">Employee Form</h4>
- </div>
- <div class="card-body">
- <form id="needs-validation" novalidate>
- <div class="row">
- <div class="col-sm-6 col-md-6 col-xs-12">
- <label for="firstName">First Name</label>
- <input type="text" class="form-control" id="firstName" placeholder="First Name" required>
- <div class="invalid-tooltip">
- Please enter first name.
- </div>
- </div>
- <div class="col-sm-6 col-md-6 col-xs-12">
- <label for="lastName">Last Name</label>
- <input type="text" class="form-control" id="lastName" placeholder="Last Name" required>
- <div class="invalid-tooltip">
- Please enter last name.
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-4 col-md-4 col-xs-12">
- <label for="Gender">Gender</label>
- <select class="custom-select" required>
- <option value="">Select Gender</option>
- <option value="1">Male</option>
- <option value="2">Female</option>
- </select>
- <div class="invalid-tooltip">Please choose gender</div>
- </div>
- <div class="col-sm-4 col-md-4 col-xs-12">
- <label for="email">Email address</label>
- <input type="email" class="form-control" id="email" placeholder="email address" aria-describedby="inputGroupPrepend" required>
- <div class="invalid-tooltip">
- Please provide a valid email.
- </div>
- </div>
- <div class="col-sm-4 col-md-4 col-xs-12">
- <label for="phonenumber">Mobile Number</label>
- <input type="tel" pattern="^\d{10}$" class="form-control" id="phonenumber" placeholder="Mobile Number" aria-describedby="inputGroupPrepend" required>
- <div class="invalid-tooltip">
- Please enter 10 digit mobile number.
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12 col-md-12 col-xs-12">
- <div class="form-group">
- <label>Mandatory Skills</label>
- </div>
- <div class="form-check-inline">
- <div class="custom-control custom-radio ">
- <input type="radio" class="custom-control-input" id="html" aria-describedby="inputGroupPrepend" name="radio-html" required>
- <label class="custom-control-label" for="html">HTML 5</label>
- <div class="invalid-tooltip">Choose skill</div>
- </div>
- </div>
- <div class="form-check-inline">
- <div class="custom-control custom-radio ">
- <input type="radio" class="custom-control-input" id="javascript" aria-describedby="inputGroupPrepend" name="radio-javascript" required>
- <label class="custom-control-label" for="javascript">JavaScript</label>
- <div class="invalid-tooltip">Choose skill</div>
- </div>
- </div>
- <div class="form-check-inline">
- <div class="custom-control custom-radio ">
- <input type="radio" class="custom-control-input" id="csharp" aria-describedby="inputGroupPrepend" name="radio-csharp" required>
- <label class="custom-control-label" for="csharp">C# Programming</label>
- <div class="invalid-tooltip">Choose skill</div>
- </div>
- </div>
- <div class="form-check-inline">
- <div class="custom-control custom-radio">
- <input type="radio" class="custom-control-input" id="aspdotnet" aria-describedby="inputGroupPrepend" name="radio-aspdotnet" required>
- <label class="custom-control-label" for="aspdotnet">ASP.NET</label>
- <div class="invalid-tooltip">Choose skill</div>
- </div>
- </div>
- <div class="form-check-inline">
- <div class="custom-control custom-radio">
- <input type="radio" class="custom-control-input" id="MVC" name="radio-MVC" required>
- <label class="custom-control-label" for="MVC">ASP.NET MVC</label>
- <div class="invalid-tooltip">Choose skill</div>
- </div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12 col-md-12 col-xs-12">
- <div class="form-group">
- <label>Profile Picture</label>
- <div class="custom-file">
- <input type="file" class="custom-file-input" id="validatedCustomFile" required>
- <label class="custom-file-label" for="validatedCustomFile">Choose file...</label>
- <div class="invalid-tooltip">Choose file for upload</div>
- </div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12 col-md-12 col-xs-12">
- <label for="address">Address</label>
- <textarea class="form-control" rows="3" id="address" aria-describedby="inputGroupPrepend" required></textarea>
- <div class="invalid-tooltip">please enter address</div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12 col-md-12 col-xs-12">
- <div class="form-check">
- <input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
- <label class="form-check-label" for="invalidCheck">
- Agree to terms and conditions
- </label>
- <div class="invalid-tooltip">
- You must agree before submitting.
- </div>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12 col-md-12 col-xs-12">
- <div class="float-right">
- <button class="btn btn-danger rounded-0" type="submit">Cancel</button>
- <button class="btn btn-primary rounded-0" type="submit">Register</button>
- </div>
- </div>
- </div>
- </form>
- </div>
- </div>
- </div>
- </div>
- </div>
- </body>
- </html>
Output
Screenshot-1
Screenshot-2
Screenshot-3


Xowana LandPosted Feb 17, 2021, 11:04 PM
And if you only want to validate some fields, example, 5 fields out of 8.
Prashanth OlekarPosted Nov 4, 2019, 1:15 AM
How you will validate bootstrap4-datetimepicker using bootstrpa4 validation? I did same as you did everything working fine but datetimepicker not showing invalid-feedback, im using below date time picker https://gijgo.com/datepicker
gowtham pPosted Aug 22, 2019, 5:25 AM
Nice one...how will you use in sharepoint site without using form tag
Diego CromeyerPosted Jul 9, 2019, 3:33 PM
Thank you Farhan! this is great. I just have one question, if form is valid should I just add an else: if (form.checkValidity() === false) { event.preventDefault(); event.stopPropagation(); } else { alert("Valid"); } form.classList.add('was-validated');
JosephsPosted Sep 10, 2018, 11:14 PM
Nice one how to use this same login form angular js
Datta Sai KrishnaPosted Sep 10, 2018, 3:10 PM
Great Stuff Farhan