Monday, November 28, 2011

How to Create a Multi step Form with Progress Bar using Jquery and CSS3

we will see how to create a simple multi-step signup form using CSS3 and jQuery. To spice up things a bit, we will include progress bar with the form, so the users will be able to see the percentage of form completion.
We will create four steps in our form:
1. username and password fields
2. first and last name and email address
3. age, gender and country
4. summary

HTML Code

First thing to do is to create the html structure. We need a box container with four divs, one for each step. The basic HTML code is the following:
01<div id="container">
02    <form action="#" method="post">
03 
04        <div id="first_step">
05        <div id="second_step">
06        <div id="third_step">
07        <div id="fourth_step">
08 
09    </form>
10</div>
Inside each box container we will put the fields and a simple helpfull label. You can see the code inside the first box in the code below:
01<!-- #first_step -->
02<div id="first_step">
03    <h1>SIGN UP FOR A FREE <span>WEBEXP18</span> ACCOUNT</h1>
04 
05    <div class="form">
06        <input type="text" name="username" id="username" value="username" />
07        <label for="username">At least 4 characters. Uppercase letters, lowercase letters and numbers only.</label>
08 
09        <input type="password" name="password" id="password" value="password" />
10        <label for="password">At least 4 characters. Use a mix of upper and lowercase for a strong password.</label>
11 
12        <input type="password" name="cpassword" id="cpassword" value="password" />
13        <label for="cpassword">If your passwords aren’t equal, you won’t be able to continue with signup.</label>
14    </div>      <!-- clearfix --><div class="clear"></div><!-- /clearfix -->
15    <input class="submit" type="submit" name="submit_first" id="submit_first" value="" />
16</div>      <!-- clearfix --><div class="clear"></div><!-- /clearfix -->
We have used three input fields: username, password and confirm password and at the end of the box, an input submit for the next step. The other boxes work in the same way.
At the end of the container box you can see a simple progress bar. This is the necessary code:
1<div id="progress_bar">
2    <div id="progress"></div>
3    <div id="progress_text">0% Complete</div>
4</div>
The complete HTML code is the following:
01<div id="container">
02        <form action="#" method="post">
03 
04            <!-- #first_step -->
05            <div id="first_step">
06                <h1>SIGN UP FOR A FREE <span>WEBEXP18</span> ACCOUNT</h1>
07 
08                <div class="form">
09                    <input type="text" name="username" id="username" value="username" />
10                    <label for="username">At least 4 characters. Uppercase letters, lowercase letters and numbers only.</label>
11 
12                    <input type="password" name="password" id="password" value="password" />
13                    <label for="password">At least 4 characters. Use a mix of upper and lowercase for a strong password.</label>
14 
15                    <input type="password" name="cpassword" id="cpassword" value="password" />
16                    <label for="cpassword">If your passwords aren’t equal, you won’t be able to continue with signup.</label>
17                </div>      <!-- clearfix --><div class="clear"></div><!-- /clearfix -->
18                <input class="submit" type="submit" name="submit_first" id="submit_first" value="" />
19            </div>      <!-- clearfix --><div class="clear"></div><!-- /clearfix -->
20 
21            <!-- #second_step -->
22            <div id="second_step">
23                <h1>SIGN UP FOR A FREE <span>WEBEXP18</span> ACCOUNT</h1>
24 
25                <div class="form">
26                    <input type="text" name="firstname" id="firstname" value="first name" />
27                    <label for="firstname">Your First Name. </label>
28                    <input type="text" name="lastname" id="lastname" value="last name" />
29                    <label for="lastname">Your Last Name. </label>
30                    <input type="text" name="email" id="email" value="email address" />
31                    <label for="email">Your email address. We send important administration notices to this address</label>
32                </div>      <!-- clearfix --><div class="clear"></div><!-- /clearfix -->
33                <input class="submit" type="submit" name="submit_second" id="submit_second" value="" />
34            </div>      <!-- clearfix --><div class="clear"></div><!-- /clearfix -->
35 
36            <!-- #third_step -->
37            <div id="third_step">
38                <h1>SIGN UP FOR A FREE <span>WEBEXP18</span> ACCOUNT</h1>
39 
40                <div class="form">
41                    <select id="age" name="age">
42                        <option> 0 - 17</option>
43                        <option>18 - 25</option>
44                        <option>26 - 40</option>
45                        <option>40+</option>
46                    </select>
47                    <label for="age">Your age range. </label> <!-- clearfix --><div class="clear"></div><!-- /clearfix -->
48 
49                    <select id="gender" name="gender">
50                        <option>Male</option>
51                        <option>Female</option>
52                    </select>
53                    <label for="gender">Your Gender. </label> <!-- clearfix --><div class="clear"></div><!-- /clearfix -->
54 
55                    <select id="country" name="country">
56                        <option>United States</option>
57                        <option>United Kingdom</option>
58                        <option>Canada</option>
59                        <option>Serbia</option>
60                        <option>Italy</option>
61                    </select>
62                    <label for="country">Your country. </label> <!-- clearfix --><div class="clear"></div><!-- /clearfix -->
63 
64                </div>      <!-- clearfix --><div class="clear"></div><!-- /clearfix -->
65                <input class="submit" type="submit" name="submit_third" id="submit_third" value="" />
66 
67            </div>      <!-- clearfix --><div class="clear"></div><!-- /clearfix -->
68 
69            <!-- #fourth_step -->
70            <div id="fourth_step">
71                <h1>SIGN UP FOR A FREE <span>WEBEXP18</span> ACCOUNT</h1>
72 
73                <div class="form">
74                    <h2>Summary</h2>
75 
76                    <table>
77                        <tr><td>Username</td><td></td></tr>
78                        <tr><td>Password</td><td></td></tr>
79                        <tr><td>Email</td><td></td></tr>
80                        <tr><td>Name</td><td></td></tr>
81                        <tr><td>Age</td><td></td></tr>
82                        <tr><td>Gender</td><td></td></tr>
83                        <tr><td>Country</td><td></td></tr>
84                    </table>
85                </div>      <!-- clearfix --><div class="clear"></div><!-- /clearfix -->
86                <input class="send submit" type="submit" name="submit_fourth" id="submit_fourth" value="" />
87            </div>
88 
89        </form>
90    </div>
91    <div id="progress_bar">
92            <div id="progress"></div>
93            <div id="progress_text">0% Complete</div>
94    </div>
As you can see, in the fourth step the table is empty. We fill it with the information entered by the users using jQuery.

CSS Code

Now we need to add the style on the form. First, we use the @fontface rule for using a custom font. I’ve used the Cantarell font. The complete CSS Code is listed below:
001/* CSS Reset (Eric Meyer) */
002html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,
003p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,
004font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,
005dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td
006{border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent;
007margin:0;padding:0}body{line-height:1}
008ol,ul{list-style:none}blockquote,q{quotes:none}:focus
009{outline:0}ins{text-decoration:none}del
010{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0}
011 
012@font-face {
013   font-family: 'Cantarell';
014   src: url(../fonts/Cantarell-Regular.eot);
015   src: local('Cantarell'), url('../fonts/Cantarell-Regular.ttf') format('truetype');
016}
017 
018body {
019    background-color: #f9f9f9;
020    color: #222;
021    font-family: Cantarell, Verdana, sans-serif;
022    font-size: 12px;
023}
024 
025input[type="submit"]::-moz-focus-inner, input[type="button"]::-moz-focus-inner { border : none; }
026input[type="submit"]:focus, input[type="button"]:focus { outline : none; }
027 
028.clear { clear: both; }
029 
030#container {
031    background: url('../images/container.png') no-repeat;
032    width: 754px;
033    height: 370px;
034    margin: 20px auto;
035    padding: 50px 0;
036    overflow: hidden;
037    position: relative;
038}
039    #container #first_step, #second_step, #third_step, #fourth_step { display: none; }
040    #container #first_step { display: block; }
041 
042    #container .form { margin: 66px 72px 0 72px; }
043 
044    #container h1, #container h2 {
045        font-size: Cantarell, Verdana, sans-serif;
046        text-align: center;
047        font-size: 24px;
048        text-shadow: 1px 1px 2px #222;
049    }
050        #container h1 span { color: #a90329; }
051 
052    #container h2 {
053        color: #888;
054        font-size: 20px;
055        text-align: left;
056        text-shadow: none;
057    }
058 
059    #container table {
060        margin: 20px 40px;
061        font-size: 14px;
062        font-weight: bold;
063    }
064        #container table td {
065            padding: 5px 10px;
066        }
067            #container table td:nth-child(2) {
068                color: #a90329;
069            }
070 
071    #container input, #container select {
072        background: url('../images/input.png') no-repeat;
073        color: #888;
074        border: 1px solid #ccc;
075        font-family: Cantarell, Verdana, sans-serif;
076        font-weight: bold;
077        font-size: 15px;
078        width: 300px;
079        height: 35px;
080        padding: 0 25px;
081        margin: 20px 0;
082        float: left;
083 
084        border-radius: 6px;
085        -moz-border-radius: 6px;
086        -webkit-border-radius: 6px;
087    }
088        #container input.submit {
089            background: url('../images/button.png') no-repeat;
090            border: none;
091            cursor: pointer;
092            width: 85px;
093            height: 38px;
094            position: relative;
095            bottom: 2px;
096            left: 655px;
097        }
098            #container input.submit:focus { border: none; }
099 
100        #container input.send{ background: url('../images/send.png') no-repeat; }
101 
102        #container input.error { border: 1px solid red; }
103        #container input.valid { border: 1px solid #1FFF00; }
104 
105        #container input:focus, #container select:focus {
106            border: 1px solid #a90329;
107            color: #a90329;
108        }
109 
110    #container select { padding: 5px 0 5px 25px; }
111        #container option { padding: 0 15px; }
112 
113    #container label {
114        color: #666;
115        font-size: 12px;
116        font-weight: bold;
117        line-height: 14px;
118        float: right;
119        margin: 23px -25px;
120        width: 270px;
121    }
122 
123#progress_bar {
124    background: url('../images/progress_bar.png') no-repeat;
125    width: 339px;
126    height: 24px;
127    margin: 0 auto;
128    position: relative;
129}
130 
131#progress {
132    background: url('../images/progress.png') repeat-x;
133    width: 0px;
134    height: 23px;
135 
136    border-radius: 20px;
137    -webkit-border-radius: 20px;
138    -moz-border-radius: 20px;
139}
140#progress_text {
141    position: relative;
142    line-height: 21px;
143    text-align: center;
144    font-weight: bold;
145    color: white;
146    text-shadow: 1px 1px 2px #222;
147    width: 339px;
148    height: 24px;
149    top: -23px;
150    left: 0;
151}

jQuery Code

We’re going to use jQuery for:
- slide the steps
- check if the data are valid
- change the completion percentage of progress bar
We need load jQuery library inside the page and then to use two plugins:
- jQuery UI, the most famous plugin used to extend the jQuery functionality.
- jQuery inputfocus, my jQuery plugin used to manage focus and blur events of the form.
Our jQuery code is listed below:
001$(function(){
002    //original field values
003    var field_values = {
004            //id        :  value
005            'username'  : 'username',
006            'password'  : 'password',
007            'cpassword' : 'password',
008            'firstname'  : 'first name',
009            'lastname'  : 'last name',
010            'email'  : 'email address'
011    };
012 
013    //inputfocus
014    $('input#username').inputfocus({ value: field_values['username'] });
015    $('input#password').inputfocus({ value: field_values['password'] });
016    $('input#cpassword').inputfocus({ value: field_values['cpassword'] });
017    $('input#lastname').inputfocus({ value: field_values['lastname'] });
018    $('input#firstname').inputfocus({ value: field_values['firstname'] });
019    $('input#email').inputfocus({ value: field_values['email'] });
020 
021    //reset progress bar
022    $('#progress').css('width','0');
023    $('#progress_text').html('0% Complete');
024 
025    //first_step
026    $('form').submit(function(){ return false; });
027    $('#submit_first').click(function(){
028        //remove classes
029        $('#first_step input').removeClass('error').removeClass('valid');
030 
031        //ckeck if inputs aren't empty
032        var fields = $('#first_step input[type=text], #first_step input[type=password]');
033        var error = 0;
034        fields.each(function(){
035            var value = $(this).val();
036            if( value.length<4 || value==field_values[$(this).attr('id')] ) {
037                $(this).addClass('error');
038                $(this).effect("shake", { times:3 }, 50);
039 
040                error++;
041            } else {
042                $(this).addClass('valid');
043            }
044        });
045 
046        if(!error) {
047            if( $('#password').val() != $('#cpassword').val() ) {
048                    $('#first_step input[type=password]').each(function(){
049                        $(this).removeClass('valid').addClass('error');
050                        $(this).effect("shake", { times:3 }, 50);
051                    });
052 
053                    return false;
054            } else {
055                //update progress bar
056                $('#progress_text').html('33% Complete');
057                $('#progress').css('width','113px');
058 
059                //slide steps
060                $('#first_step').slideUp();
061                $('#second_step').slideDown();
062            }
063        } else return false;
064    });
065 
066    $('#submit_second').click(function(){
067        //remove classes
068        $('#second_step input').removeClass('error').removeClass('valid');
069 
070        var emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
071        var fields = $('#second_step input[type=text]');
072        var error = 0;
073        fields.each(function(){
074            var value = $(this).val();
075            if( value.length<1 || value==field_values[$(this).attr('id')] || ( $(this).attr('id')=='email' && !emailPattern.test(value) ) ) {
076                $(this).addClass('error');
077                $(this).effect("shake", { times:3 }, 50);
078 
079                error++;
080            } else {
081                $(this).addClass('valid');
082            }
083        });
084 
085        if(!error) {
086                //update progress bar
087                $('#progress_text').html('66% Complete');
088                $('#progress').css('width','226px');
089 
090                //slide steps
091                $('#second_step').slideUp();
092                $('#third_step').slideDown();
093        } else return false;
094 
095    });
096 
097    $('#submit_third').click(function(){
098        //update progress bar
099        $('#progress_text').html('100% Complete');
100        $('#progress').css('width','339px');
101 
102        //prepare the fourth step
103        var fields = new Array(
104            $('#username').val(),
105            $('#password').val(),
106            $('#email').val(),
107            $('#firstname').val() + ' ' + $('#lastname').val(),
108            $('#age').val(),
109            $('#gender').val(),
110            $('#country').val()
111        );
112        var tr = $('#fourth_step tr');
113        tr.each(function(){
114            //alert( fields[$(this).index()] )
115            $(this).children('td:nth-child(2)').html(fields[$(this).index()]);
116        });
117 
118        //slide steps
119        $('#third_step').slideUp();
120        $('#fourth_step').slideDown();
121    });
122 
123    $('#submit_fourth').click(function(){
124        //send information to server
125        alert('Data sent');
126    });
127 
128});
The code from row 3 to 20 activate the inputfocus plugin to each input field. The code from row 27 to 64 check the validity of the data entered by the user (if username and password length is greather than 4 characters, if the password and confirm password fields are equal), then update the progress bar value and then slide to second step.
The code from row 71 to 100 check the data integrity for the second step (if first and last name aren’t empty and if the email address is valid). The rest is similar to the previous code.

Conclusions

We have seen how simple its to create a multistep signup form. This is only an example so I omitted some features as back button, and more others. Anyway the example is ready to use and it needs only to change the form action with the link of your php file used to store data and to edit the jQuery line 125 to: $(‘form’).unbind(‘submit’).submit();. You can also decide to use an AJAX calls to send the informations to server, and again it’s very easy to implement.
The article source:http://webexpedition18.com/articles/how-to-create-a-multi-step-signup-form-with-css3-and-jquery/

No comments:

Post a Comment