http://tutorialzine.com
Created by Martin Angelov on Apr 7th, 2010
Today we are making a carbon fiber – style form, build using progressive enhancement. This means that we first ensure that the form works well without JavaScript and fancy CSS support (think of IE6 here) and later move on by layering over cool styling, AJAX and jQuery magic.
The form features its own custom tooltip validation, and is even perfectly usable with JavaScript disabled.
Step 1 – XHTML
The first step includes creating the XHTML backbone of the form. It has to be simple, and, according to the principles defined by progressive enhancement, must be perfectly usable by itself.
demo.html
04 | < form action = "submit.php" method = "post" id = "signupForm" > |
06 | < div class = "fieldContainer" > |
07 | < div class = "formRow" >div > |
11 | < div class = "signupButton" > |
12 | < input type = "submit" name = "submit" id = "submit" value = "Signup" /> |
The
carbonForm div is the main container for the form. It is centered in the middle of the page with the CSS
margin property, and then centered vertically with jQuery (take a look at
our MicroTut for more info about centering).
Inside it we have the heading and the form with the
fieldContainer div. Inside it there are three
formRow divs, which share the markup given below:
demo.html
3 | < label for = "name" >Name:label > |
7 | < input type = "text" name = "name" id = "name" /> |
Each pair of
label and
input elements is positioned inside its own wrapping divs, which are floated to the left. This allows for the layout of the form you can see in the demonstration page. It is important to have the text box names the
same as their
ids, because this is used to display the error tooltips as you will see in the next steps.
Carbon Fiber Signup Form
Step 2 – CSS
The form relies heavily on CSS to achieve the carbon fiber effect. A number of CSS3 rules are used as well, which successfully mimic the effects previously possible only in graphic suites as Photoshop. Only the most interesting styles are given here, you can see the rest in
styles.css in the download archive.
styles.css
03 | background-color : #1C1C1C ; |
04 | border : 1px solid #080808 ; |
09 | -moz-box-shadow: 0 0 1px #444 inset ; |
10 | -webkit-box-shadow: 0 0 1px #444 inset ; |
11 | box-shadow: 0 0 1px #444 inset ; |
16 | background-color : #1E1E1E ; |
17 | border : 1px solid #0E0E0E ; |
21 | -moz-box-shadow: 0 0 20px #292929 inset ; |
22 | -webkit-box-shadow: 0 0 20px #292929 inset ; |
23 | box-shadow: 0 0 20px #292929 inset ; |
26 | #carbonForm,.fieldContainer,.errorTip{ |
28 | -moz-border-radius: 12px ; |
29 | -webkit-border-radius: 12px ; |
47 | font-family :Century Gothic,Myriad Pro, Arial , Helvetica , sans-serif ; |
59 | border : 1px solid white ; |
61 | font-family : Arial , Helvetica , sans-serif ; |
64 | background : url ( "img/box_bg.png" ) repeat-x scroll left top #FFFFFF ; |
70 | border : 1px solid #f4f4f4 ; |
74 | text-transform : uppercase ; |
77 | background : url ( "img/submit.png" ) no-repeat center center #d0ecfd ; |
79 | -moz-border-radius: 6px ; |
80 | -webkit-border-radius: 6px ; |
86 | background-image : url ( "img/preloader.gif" ); |
92 | -moz-box-shadow: 0 0 8px lightblue; |
93 | -webkit-box-shadow: 0 0 8px lightblue; |
94 | box-shadow: 0 0 8px lightblue; |
Most of these rules are pretty straightforward. You may find interesting how we handle the submit button, as this element is quite tricky to style consistently cross-browser.
To hide the text of the button (in our case “
Signup“), we can use the
negative text-indent trick, but in IE it only works if we also specify the
text-transform:uppercase rule. We also add a transparent background image consisting of the text “
Submit” in
Century Gothic, which is replaced with a rotating gif preloader if the button is assigned an “
active” class.
We also use a number of CSS3 effects along with their vendor-specific versions for better compatibility.
border-radius is for rounded corners, and with
box-shadow we can mimic different glow and shadow effects.
CSS3 Rounded Corners & Glow
Step 3 – jQuery
After including the jQuery library and our own
script.js file in the page, we can move on to writing the JavaScript code that will breathe some life into the form.
script.js
01 | $(document).ready( function (){ |
05 | $( '#signupForm' ).submit( function (e){ |
08 | if ($( '#submit' ).hasClass( 'active' )) return false ; |
11 | $( '#submit' ).addClass( 'active' ); |
14 | $( '.errorTip' ).remove(); |
17 | $.post($( '#signupForm' ).attr( 'action' ), |
18 | $( '#signupForm' ).serialize()+ '&fromAjax=1' , function (response){ |
26 | $( 'input[type!=submit]' ).each( function (){ |
28 | var id = elem.attr( 'id' ); |
31 | showTooltip(elem,response[id]); |
34 | else location.replace(response.redirectURL); |
36 | $( '#submit' ).removeClass( 'active' ); |
46 | $(window).resize( function (){ |
47 | var cf = $( '#carbonForm' ); |
49 | $( '#carbonForm' ).css( 'margin-top' ,($(window).height()-cf.outerHeight())/2) |
53 | function showTooltip(elem,txt) |
56 | $( '
').html(txt).appendTo(elem.closest( '.formRow' )); |
Clicking the submit button (or pressing the
enter key while entering text in one of the fields) submits the form. The function that is bound to the submit event prevents this from happening with
e.preventDefault() and issues an AJAX request to
submit.php instead.
The response that is returned is evaluated as JSON code (a JavaScript object), which contains a special
status property. Depending on its value, the script either shows error tooltips on the fields, or redirects the browser to the specified URL in the response.
sample error response
3 | "email" : "Please fill in a valid email!" , |
4 | "pass" : "Please fill in a valid password!" |
The error tooltips are generated by the script while looping though all the fields in the form and checking whether their ids exist as properties in the response object. If they do, a tooltip is created with the
showTooltip() function.
Also notice how we use the
serialize() method on line 18 to send all the form fields at once. Also, on this same line, we set
fromAjax=1, which is going to tell PHP to return the response as JSON.
Now lets see how this response is generated and how the form is validated.
Dynamically Inserted Error Tooltips
Step 4 – PHP
The good thing about this form is that it is usable even if JavaScript is disabled. This works, because the action attribute of the form element is also set to
submit.php. This means that we only have to implement the validation once no matter how the form is sent.
submit.php
02 | error_reporting (E_ALL^E_NOTICE); |
13 | if (! $_POST [ 'name' ] || strlen ( $_POST [ 'name' ])<3 || strlen ( $_POST [ 'name' ])>50) |
15 | $errors [ 'name' ]= 'Please fill in a valid name!
Must be between 3 and 50 characters.' ; |
18 | if (! $_POST [ 'email' ] || !preg_match( "/^[\.A-z0-9_\-\+]+[@][A-z0-9_\-]+([.][A-z0-9_\-]+)+[A-z]{1,4}$/" , $_POST [ 'email' ])) |
20 | $errors [ 'email' ]= 'Please fill in a valid email!' ; |
23 | if (! $_POST [ 'pass' ] || strlen ( $_POST [ 'pass' ])<5) |
25 | $errors [ 'pass' ]= 'Please fill in a valid password!
Must be at least 5 characters long.' ; |
36 | foreach ( $errors as $k => $v ) |
40 | $errString []= '"' . $k . '":"' . $v . '"' ; |
44 | die ( '{"status":0,' .join( ',' , $errString ). '}' ); |
48 | echo '{"status":1,"redirectURL":"' . $redirectURL . '"}' ; |
58 | echo '
'.join( '
' , $errors ). ' '; |
64 | header( "Location: " . $redirectURL ); |
All the encountered errors are added to the
$errors array. This, depending on whether
fromAjax was set or not, is later returned either as a JSON object, or directly printed to the screen.