Forms in Bootstrap are the biggest paradigm shift for us as ColdFusion developers. We all use cfform and its cfinput tags to perform standard form functionality and validation. Bootstrap forces us to use HTML5 instead of ColdFusion to perform these tasks. This is actually a good thing. Using the defined HTML5 methods gives us more control over how things are validated.
Another major shift in thinking is using tables to layout your forms. This has been the one exception to the "don't use tables" rule. The cool thing is Bootstrap allows us to use their grid system - or a version of it - to layout forms quickly and easily. We will cover that in "part 2" below.
Part 1: The Fields
Let's start easy here and look over the standard markup for form fields.
Text Input
Nothing too fancy here - just a plain ordinary text field. Let me draw your attention to three key items here.
The label tag is not strictly required but is highly recommended. Note that the value of the for attribute is the same as the value of the field's id attribute.
The id attribute should be there as it is used for HTML5 validation and adds accessibility.
The class is set to form-control. That's really all you need to make your form elements use Bootstrap's visual style!
By default fields in Bootstrap are as wide as their parent container. So of you have one in a col-xl-12 column it will be as wide as the whole layout. If you forget and just plop the field into a blank HTML page it will span the width of the viewport.
Date Select
Note!
IE11 doesn't like the HTML5 date picker that spawns with this field. While IE11 is becoming less of an issue, the best work-around is to use the datepicker with jQueryUI. You can steal it from the source on this page.
E-mail Input
This one is pretty nifty. It automatically validates the input as an e-mail address.
Password Input
Readonly Input
Readonly plain-text Input
This one is useful if you want to display data but not let the user know it is a form field.
Textarea Input
Like the input fields, the textarea always spans 100% of its parent container. You can adjust the height by changing the value of the rows attribute.
Select Box
Checkboxes - stacked layout
Checkboxes - inline layout
Radio Buttons - stacked layout
Radio Buttons - inline layout
Part 2: Form Layout
Now we will take the form field elements and put them into an attractive and useful layout. Bootstrap uses a slightly different version of its grid system for form layout.
Each row of fields is contained within a form-row and each field is contained in a form-group which also uses the grid col-{breakpoint}-{column-number} grid class format. You can apply margins and padding to this grid in the same way you would a standard layout grid.
The coolest part of the form grid is that it functions the same as the layout grid - so your forms are instantly mobile-friendly!
Bootstrap Tip:
You can use any permutation of the form-row and form-group col-{size}-{number} setup to construct an attractive form. The way I usually do this is to draw out the form on a hunk of paper first so I can visualize where things will go, create the layout, enter the inputs and tweak as needed.
Part 3: Form Validation
Once you get a handle on using Bootstrap to validate your forms, I think you'll agree that it is pretty simple. At first - and if you try to follow their documentation - you might find it confusing.
The first thing I recommend is applying the class needs-validation to your form tag. Then add the keyword novalidate to the form tag. Now, be confused for a second....needs-validation...novalidate? Yes, they cancel out. The needs-validation class tells Bootstrap to validate the form and novalidate tells HTML5 not to validate the form.
To validate a field, add the required keyword to the field then, beneath the field add a DIV with the class invalid-feedback containing the message you want displayed if the user doesn't fill out the field. You can also add a DIV with the valid-feedback class to provide a message if they do fill it in correctly. Personally, I rarely do this - but it changes asynchronously as the user corrects the fields they miss - which is kinda neat.
ColdFusion Tip: The JavaScript you see in this snippet below the form is required to make the validation work. Because HTML5 and Bootstrap require the use of client-side scripting to validate the form, it really is no different than our old CFFORM uses. Pay attention to your users and if, as happens sometimes, they have JavaScript disabled, you will want to perform server-side validation with ColdFusion. If this ever comes up let me know and I will give you my prototype using session variables.
One last note about that JavaScript: You don't need to edit it in any way. What you see here works globally for any form on your page flagged with that needs-validation class.
Part 4: Curiosities
There are a few additional elements and oddities with using Bootstrap forms. Thankfully there are some simple work-arounds.
Field Sizes
Yep - there are three possible sizes to your form fields. Small, default, and large - of course. The large fields come in handy if you know your app will be used on a mobile device. The small ones would be better used in an admin environment or in a layout where space is limited.
Setting a field to small or large is very easy. Just add the form-control-sm or form-control-lg class chained after the usual form-control class and the size will change.
The Custom File Field
I think we can all agree that Bootstrap form fields are much prettier than normal fields. The one exception to that rule is the file browser field. Every browser has a different way of displaying this poor thing. Thankfully we can standardize it with Bootstrap!
Here's the normal file field:
Here's the "custom" field in Bootstrap.
You should note that there is a chunk of jQuery associated with this field. Without it the field will still work but the name of the file the user selects will not appear in the field. Add the script, edit the $('#customFile') to be the ID of your field and you are in business.
Custom Checkboxes
You can pretty-up the standard radio buttons and checkboxes using the custom-control-input class.
Custom Radio and Checkboxes - inline
To display custom radio buttons or checkboxes inline, just add the custom-control-inline class to the containing DIV.
Switches
One of the new things you see on the web these days is the "switch" style field. These are pretty neat and would really work well with allowing users to select a yes/no or on/off option. The switch is actuallty a skinned checkbox. As with any checkbox, if it's not checked then it doesn't exist when the form is submitted.
You can use my little JavaScript voodoo to change the label when the switch is checked.
Warning:
You can't scale the toggle switches up. They are one size fits all.
Custom Select
This one is pretty simple. It adds the primary color of Bootstrap to the selected element and changes the arrow.
You can apply the size changes to the select boxes by adding custom-select-lg or custom-select-sm in chain with the custom-select class.
Accessible Forms and Screen Readers
Screen readers will have trouble with your forms if you don't include a label for every input. Since we are bound by the lovely Section 508 guidelines you must use - or start using if you haven't been - label tags to correspond with your form fields.
Sometimes these labels get in the way. Here's an example
See how the username and password labels get in the way? Getting them out of there is simple! And no, you can't just remove the label text because the size and shape of the label still exists. Just add the class sr-only to the label itself and it will only appear on screen readers.
This class can be used to hide ANYTHING you want to display to screen readers alone.
A couple of notes about the code above since it shows off two additional features you will find useful.
This is an example of an inline form. Note the class form-inline added to the form tag. Because we are displaying the form in a single line it does not need any form-row or form-group tags.
Note the super groovy field asking for the username with the @ appended to the field. This is an "input group". Because this is so cool I will give you a separate couple of snippets for this below.
$
.00
Please check the box.
Constraint Validation
This is one of those things that when you find out that it exists and how easy is it to use that it makes you kind of mad and excited at the same time. Constraint validation....this is actually an HTML5 thing that the W3 added. It allows you to validate fields against each other with a couple of lines of code. No jQuery or javascript needed.
Let's say you have a form wherein you want to make sure the user enter their e-mail address two times to make sure they get it right. Normally you would need to add a script to do this and it can be a huge mess. All you need to do with this new method is add an event to your form tag.
Here's a simple example:
Here's a quick breakdown of what this is doing....
oninput="email2.setCustomValidity(email2.value != email1.value ? 'Email addresses do not match.' : '');"
The oninput event triggers when a user enters something into the specified input field. Then we name the second field by ID, "email2" and set a custom validity through HTML5 if the value of the second field isn't equal to the value of the first field. If you are really sharp you will recognize the syntax is the ternary operator value = value ? 'do this if true' : 'do this if false'. So we check if the values are equal and if they aren't it adds a custom message to the field. Super simple!
That pretty much covers everything you need to implement Bootstrap forms into your apps. The snippets herein are perfect for snippets in your text editor too.