Imagine you have a form with 10 required fields on it. That’s a bit larger than your average form on the internet and a good bit of work for a user. You might lose some users along the way, which is never a good thing. Perhaps to encourage finishing the form, you let them know how close to completion they are, and display motivational messages along the way.

1. HTML for Required Inputs
Inputs wouldn’t necessarily need to be required
for this demo, but it makes for a clean demo. Filling out an optional field doesn’t bring you any closer to the minimum requirements for submitting a form. So for this demo, we’ll have 5 required fields down a typical form that collects information for payment.
<form id="payment-form" action="#">
<label for="name">Full Name</label>
<input required id="name" name="name">
<!-- etc -->
</form>
2. HTML for Progress
There is an HTML element specifically for visually displaying progress. Literally, <progress>
. Let’s have one of these available (with an ID so it’s easy to target with JavaScript). Place it where you will.
<progress max="100" value="0" id="progress"></progress>
Making the max
attribute 100 means for easy math. The progress bar is as full as the value in percentage is. E.g. value="20"
== bar is 20% full.

3. Watch for Changes
We’ll use jQuery here to make event binding and element selection easy. All our inputs here will be text-y, making keyboard events relevant. So…
$("#payment-form input").keyup(function() {
// calculate progress
});
4. Count Number of Valid Inputs
Whether or not any particular input is valid or not in its current state is part of the DOM now. Once we have a pointer to it, we just check this.validity.valid
for true or false.
var numValid = 0;
$("#payment-form input[required]").each(function() {
if (this.validity.valid) {
numValid++;
}
});
5. Adjust the Progress Bar / Display Messages
Now that we have an integer of how many inputs are valid, we just set up some basic logic to adjust the progress bar’s current value.
This is where we could also display our motivational messages. Perhaps there is a <p>
element somewhere on the page which we have a pointer to (progressMessage) and we simply adjust the text inside it to match the progress.
// "Cached" somewhere once
var progress = $("#progress"),
progressMessage = $("#progressMessage");
// Logic that runs after counting every time
if (numValid == 0) {
progress.attr("value", "0");
progressMessage.text("The form, it wants you.");
}
if (numValid == 1) {
progress.attr("value", "20");
progressMessage.text("There you go, great start!");
}
Browser Support
If browser support is a concern, you’ll probably want to run a little Modernizr test first. If it passes, then load scripts, inject elements, however you want to handle it.
if (Modernizr.input.required) {
// Modernizr.load, inject elements, whatever.
}
If you need more help on that, read this article.
Demo on CodePen
Do whatever you’d like with it.
That’s a great idea! Love that concept especially the dynamic progress bar! We’ll use that. Thanks!!
I wasn’t aware of
this.validity.valid
, very handy. Good article as well!Pressing key isn’t the only way to change input field. You can also do it for example with drag & drop or pasting using middle mouse button in some linux distributions.
Very good point, Hallo.
I would change the trigger event to focus/blur or something.
Otherwise love the idea!
Autofill also confuses it. But I great concept once the kinks are worked out.
This is a great example of progressive enhancement. It does bring up the question that will be asked: How stylable is that progress bar.
Brilliant use of progress bar….I have been thinking of a way to demonstrate the HTML progress bar in a way that was easy to explain and show……This fits the bill perfectly…Thank you for sharing…
You should probably use the “input” event via
.on("input")
. Note it’s not supported in IE lower than 9 (I think), so you could use both (.on("input keyup")
). Also on windows (7 at least) the progress bar is constantly animated, so maybe a custom progress bar or the<meter>
element , which has “custom” styling in the browsers as far as I know, would be better…I think this goes without saying but IE9 hates this.
Nice. Would be cool to animate the progress bar too. Something like this:
http://jsfiddle.net/526hM/
Not my code, though; comes from this SO thread, from someone named “Thomas”.
I did not know there was a
<progress>
element in HTML. I’m surprised you don’t see this element much for ‘loading’ pages.If someone can please explain to me where the validation of this form is being handled on the demo i would appreciate it thank you.
It’s in the HTML, using the “pattern” attribute. I believe the JS also checks for empty/filled inputs, to make the progress bar and messages proceed.
The “pattern” attribute is new in HTML5 and lets things get validated client side without extra JavaScript.
Got it. Thank you. Will have to read up on all the new HTML5 form elements.
Just be careful about Safari 5 (and Mobile Safari 5). It aggressively deletes progress elements instead of just ignoring them. You might have to test to see whether the progress element exists at all first.
Nice, thank you!
Setting the percentages manual is a mess.
How about to add classes like “valid” if valid and change the width of the progressbar to (amount of inputs)/(valid inputs)?
As many forms are accompanied by JS client validations I would consider updating the progress only after the required value is already validated (and valid). Also using an animator function as Louis mentioned would be a nice addon.
The autofill could be workarounded by another event handler after the page is loaded that will walk through the fields and validate them (and as we would have our progress update hooked on validations the progress would immediately update to corresponding value).