Get up to 80 % extra points for free! More info:

Lesson 8 - Bootstrap - Advanced forms

In the previous lesson, Bootstrap - Forms, we started forms in Bootstrap. In today's CSS tutorial, we'll continue and also finish this topic. There is client-side validation, custom styles, and input groups waiting for us up ahead.

Validation

Another strength of Bootstrap forms are client-side validations. If we define them for form controls, Bootstrap helps us to highlight the invalid controls and shows error messages next to them. For this, the :invalid and :valid pseudo-classes are used internally, highlighting the form controls if the .was-validated class is assigned to the form. The class is assigned automatically by Bootstrap when the form is submitted.

In the example below, we're showing custom messages in client-side validation. Before we can do that, we need to turn off the default browser's messages like "Please fill out this field." by adding the novalidate="novalidate" attribute to the <form> element. We're going to use a custom JavaScript function to render the messages.

<form id="needs-validation" novalidate="novalidate">
    <div class="form-group">
        <label for="form-name">Name</label>
        <input type="text" class="form-control" id="form-name" placeholder="John Doe" required="required">
        <div class="invalid-feedback">
            Please enter your full name.
        </div>
    </div>
    <div class="form-group">
        <label for="form-email">Email</label>
        <input type="text" class="form-control" id="form-email" placeholder="[email protected]" required="required">
        <div class="invalid-feedback">
            Please enter a valid email address.
        </div>
    </div>
    <button class="btn btn-primary" type="submit">Send</button>
</form>

<script>
(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>

The result:

Validation in Bootstrap
form_validati­on.html

If you omit the JavaScript part, the messages will be rendered only one at a time by the browser and wouldn't be shown all at once. Let's try the same code without the script and the novalidate attribute.

Validation in Bootstrap
form_validati­on.html

Server-side validation

If we wanted to highlight the form like this even when performing the server-side validation, we'd just assign the .is-valid and .is-invalid classes to its controls. In this situation, the form doesn't have to have the .was-validated class anymore.

We should always perform the server-side validation, because the client-side validation can never be trusted!** The client-side validation just makes the user experience better since they get error messages before the form is even sent to the server.

We can also alter the client-side validation in JavaScript, see the setCustomValidity() method.

Custom styles

The appearance of checkboxes, radio buttons, file inputs, and selects is often adopted from the operating system or the default browser settings, which doesn't always look nice. That's why Bootstrap allows to style these controls completely on our own. This is internally achieved by hiding them via opacity: 0. We'll assign the .custom-control class to the <label> element and add the new controls in place of the hidden ones as <span> elements with the .custom-control-indicator and .custom-control-description classes.

A form with custom control styles would have the following source code:

<form>
    <div class="form-check">
        <label class="custom-control custom-checkbox">
            <input class="custom-control-input" type="checkbox" value="">
            <span class="custom-control-indicator"></span>
            <span class="custom-control-description">I agree to the Terms of Service</span>
        </label>
    </div>
    <div class="form-check">
        <label class="custom-control custom-radio">
            <input class="custom-control-input" type="radio" name="payment-method" id="payment-method1" value="card" checked>
            <span class="custom-control-indicator"></span>
            <span class="custom-control-description">Credit Card</span>
        </label>
    </div>
    <div class="form-check">
        <label class="custom-control custom-radio">
            <input class="custom-control-input" type="radio" name="payment-method" id="payment-method2" value="wiretransfer" checked>
            <span class="custom-control-indicator"></span>
            <span class="custom-control-description">Wiretransfer</span>
        </label>
    </div>
    <div class="form-group">
        <label for="form-select">Size</label>
        <select class="custom-select" id="form-select">
            <option>S</option>
            <option>M</option>
            <option>L</option>
            <option>XL</option>
        </select>
    </div>
    <div class="form-group">
        <label class="custom-file">
            <input type="file" class="custom-file-input">
            <span class="custom-file-control"></span>
        </label>
    </div>
</form>

For checkboxes, we assign the .custom-checkbox class to the <label> elements and the .custom-control-input class to the <input>s. Checkboxes also support the indeterminate property which makes the checkbox is neither checked or unchecked (the dash - symbol is rendered on it). The property has to be eventually set via JavaScript. For radiobuttons, we assign the .custom-radio class to the <label> elements and .custom-control-input to the <input>s. For selects, we assign the .custom-select class. And for file inputs, we assign the .custom-file-input class and add a <span> with the .custom-file-control class.

The result:

Validation in Bootstrap
form_validati­on.html

If you wanted to translate the text on the file input, it depends on the language defined for the page in the lang attribute of the <html> element. The texts are taken from the Bootstrap's SASS source codes, specifically the $custom-file-text variable. Unfortunately, the default build renders custom file inputs only for the en language.

Custom controls will align next to each other. If we want them one under another, we have to put them in divs as shown in the example above. We used the .form-group class here. Bootstrap also provides the .custom-controls-stacked class, if we used it, we won't have to put controls in individual divs, we could put them in a single <div> with this class assigned.

Input groups

In the Bootstrap CSS framework, input groups allows us to insert other elements, such as texts or buttons, on the sides of text inputs. These extensions are called addons. We have already seen such inputs in the lesson about forms, but never described them in detail. Let's show a basic example:

<div class="form-group">
    <div class="input-group">
        <span class="input-group-addon" id="address-addon">ict.social/</span>
        <input type="text" class="form-control" placeholder="article name" aria-label="Article name" aria-describedby="address-addon">
    </div>
</div>
<div class="form-group">
    <div class="input-group">
        <input type="text" class="form-control" placeholder="Your name" aria-label="Your name" aria-describedby="email-addon">
        <span class="input-group-addon" id="email-addon">@ict.social</span>
    </div>
</div>

We insert the <input> in a <div> with the .input-group class. We put the text on the left or right side of the <input> using the <span> element with the .input-group-addon class. Another text input controls or labels are not supported.

The result:

Input groups in Bootstrap
input_groups.html

Sizes

To change the <input> size we assign one of the following classes to the <div> element with the .input-group class.

  • .input-group-lg for a large size
  • None for the standard size
  • .input-group-sm for a small size

Other addons

We can also put multiple add-ons next each other on the sides. Except for the text addons shown above, we can also add checkboxes, radio buttons, buttons, and dropdowns. Let's show another example of advanced addons.

<div class="input-group">
    <span class="input-group-addon" id="checkbox-addon">
        <input type="checkbox" aria-label="Checkbox">
    </span>
    <span class="input-group-addon" id="text-addon">Text</span>
    <span class="input-group-btn">
        <button class="btn btn-secondary" type="button">Button</button>
    </span>
    <input type="text" class="form-control" aria-label="Sample input">
    <div class="input-group-btn">
        <button type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
            Dropdown
        </button>
        <div class="dropdown-menu">
            <a class="dropdown-item" href="#">Item 1</a>
            <a class="dropdown-item" href="#">Item 2</a>
            <div role="separator" class="dropdown-divider"></div>
            <a class="dropdown-item" href="#">Item 3</a>
        </div>
    </div>
</div>

For correct functionality of dropdown buttons, don't forget to link the Bootstrap's JavaScript. The result in the browser:

Input groups in Bootstrap
advanced_input_grou­ps.html

We can also segment dropdowns, i.e. divide them into 2 separate buttons where the larger button works independently and the smaller button drops the options.

<div class="input-group-btn">
    <button type="button" class="btn btn-secondary">Dropdown</button>
    <button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
      <span class="sr-only">Toggle dropdown</span>
    </button>
    <div class="dropdown-menu dropdown-menu-right">
        <a class="dropdown-item" href="#">Item 1</a>
        <a class="dropdown-item" href="#">Item 2</a>
        <div role="separator" class="dropdown-divider"></div>
        <a class="dropdown-item" href="#">Item 3</a>
    </div>
</div>

The result:

Input groups in Bootstrap
segmented_drop­down.html

If you wanted the dropdown on the left side, don't assign the .dropdown-menu-right class to the menu. Now, we've finished the forms :) Next time, in the lesson Bootstrap - Jumbotron and Badges, we'll discuss Jumbotron component and learn how to use Bootstrap badges.


 

Previous article
Bootstrap - Forms
All articles in this section
Bootstrap
Skip article
(not recommended)
Bootstrap - Jumbotron and Badges
Article has been written for you by David Capka Hartinger
Avatar
User rating:
3 votes
The author is a programmer, who likes web technologies and being the lead/chief article writer at ICT.social. He shares his knowledge with the community and is always looking to improve. He believes that anyone can do what they set their mind to.
Unicorn university David learned IT at the Unicorn University - a prestigious college providing education on IT and economics.
Activities