Creating a Facebook-like Registration Form with jQuery
Introduction
Facebook is a showcase of great UI design. And as it has become a major part of our lives, it has also raised the bar for web development, pushing developers to meet higher expectations.
This however has a good side - it challenges web developers and designers to better themselves and constantly improve their work.
In this tutorial, we are going to learn from the best, and create a facebook-like sign up form. So go ahead and download the demo files to start learning!
The XHTML
We start off by laying down the XHTML backbone, as seen in index.php in the demo files:
<div id="div-regForm"> <div class="form-title">Sign Up</div> <div class="form-sub-title">It's free and anyone can join</div> <form id="regForm" action="submit.php" method="post"> <table> <tbody> <tr> <td><label for="fname">First Name:</label></td> <td><div class="input-container"> <input name="fname" id="fname" type="text" /> </div></td> </tr> <tr> <td><label for="lname">Last Name:</label></td> <td><div class="input-container"> <input name="lname" id="lname" type="text" /> </div></td> </tr> <tr> <td><label for="email">Your Email:</label></td> <td><div class="input-container"> <input name="email" id="email" type="text" /> </div></td> </tr> <tr> <td><label for="pass">New Password:</label></td> <td><div class="input-container"> <input name="pass" id="pass" type="password" /> </div></td> </tr> <tr> <td><label for="sex-select">I am:</label></td> <td> <div class="input-container"> <select name="sex-select" id="sex-select"> <option value="0">Select Sex:</option> <option value="1">Female</option> <option value="2">Male</option> </select> </div> </td> </tr> <tr> <td><label>Birthday:</label></td> <td> <div class="input-container"> <select name="month"> <option value="0">Month:</option> <?=generate_options(1,12,'callback_month')?> </select> <select name="day"> <option value="0">Day:</option> <?=generate_options(1,31)?> </select> <select name="year"> <option value="0">Year:</option> <?=generate_options(date('Y'),1900)?> </select> </div> </td> </tr> <tr> <td> </td> <td><input type="submit" class="greenButton" value="Sign Up" /> <img id="loading" src="img/ajax-loader.gif" alt="working.." /> </td> </tr> </tbody> </table> </form> <div id="error"> </div> </div>
We begin by creating a div container for the form, to which we assign the id div-regForm. In it we are going to position the various form components.
Later we create the headings of the form, properly styled with CSS, as you'll see later.
Then we have the form itself. A note here would be to remember that the form does not actually get submitted by its own - its all done via AJAX, which means that it doesn't really matter what you are going to put in the method and action attributes.
Inside the form, we position a table, which will allow us to easily create a grid layout for the form labels and fields. There's been a debate on using tables in this manner since div layout came to fashion, but mind you that facebook itself is using the same technique, which automatically wins it for me.
Every input field has a respective label element serving as a, you guessed it - a field label. We are even using the for attribute, which means that by clicking the label, you select the textbox on the right.
Next comes a select box and after this we have 3 very interesting lines, that I've highlighted for you. We use a neat little PHP function to generate all the option elements that go into the select boxes comprising the selection of a birth date. We will talk about this in a minute.
Later we have the Sign Up button, and a little gif, which is hidden by default and shown only when AJAX requests are in progress.
The last div element is our error container, also hidden by default.
The CSS
In order to convert our plain XHML coding into something eye-catching and facebook-likey, we need some serious styling.
Lets take a look at our CSS, as defined in demo.css.
/* Page styles */ body,h1,h2,h3,p,td,quote,small,form,input,ul,li,ol,label{ margin:0px; padding:0px; } body{ margin-top:20px; font-family:Arial, Helvetica, sans-serif; color:#51555C; height:100%; font-size:11px; } /* Form styles */ input,select{ padding:3px; color:#333333; border:1px solid #96A6C5; margin-top:2px; width:200px; font-size:11px; } select{ width:auto; padding:2px; } .formline{ padding:3px; } label{ font-size:11px; text-align:right; } table{ width:300px; } td{ font-size:11px; } .input-container{ padding:1px; } #div-regForm,.registered{ border:3px solid #eeeeee; padding:15px; background:url(img/bg.jpg) repeat-x #cbd4e4; color:#203360; margin:30px auto 40px auto; width:400px; } .form-title, .form-sub-title{ font-size:20px; font-family:"Lucida Grande",Tahoma,Verdana,Arial,sans-serif; font-size:20px; font-weight:bold; } .form-sub-title{ font-weight:normal; padding:6px 0 15px 0; } .greenButton{ width:auto; margin:10px 0 0 2px; padding:3px 4px 3px 4px; color:white; background-color:#589d39; outline:none; border:1px solid #006600; font-weight:bold; } .greenButton:active{ background-color:#006600; padding:4px 3px 2px 5px; } #loading{ left:10px; position:relative; top:3px; visibility:hidden; } #error{ background-color:#ffebe8; border:1px solid #dd3c10; padding:7px 3px; text-align:center; margin-top:10px; visibility:hidden; }
Lines 1-6 are where we reset some of the XHTML elements, to ensure that they appear the same in all browsers.
We continue with styling the body section and start styling the form elements.
The first elements we style are input and select. Select shares most of its styling with input, but also differs in width and padding, so we put an additional set of styles to cover them.
Its mostly widths and paddings down to line 81, where we style our sign up button. We have styles for both the normal, non-pressed state, and the active, pressed state. What the active state does, is that it moves the text label of the button to the bottom - right with one pixel, while darkening the background, which gives the illusion of the button being pressed.
The last two styles are #loading and #error, which select the respective elements by their ID's and hide them with visibility:hidden by default. We will only show them with jQuery when it is appropriate.
The PHP code
Remember, when a few minutes ago I mentioned about the generate_options PHP function?
Here it is, taken right from our functions.php file:
function generate_options($from,$to,$callback=false) { $reverse=false; if($from>$to) { $tmp=$from; $from=$to; $to=$tmp; $reverse=true; } $return_string=array(); for($i=$from;$i<=$to;$i++) { $return_string[]=' <option value="'.$i.'">'.($callback?$callback($i):$i).'</option> '; } if($reverse) { $return_string=array_reverse($return_string); } return join('',$return_string); } function callback_month($month) { return date('M',mktime(0,0,0,$month,1)); } /* and here is how we use it (taken from our XHTML code above): generate_options(1,31); // generate days generate_options(date('Y'),1900); // generate years, in reverse generate_options(1,12,'callback_month'); // generate months */
This is a neat little peace of code. Now lets explain what it does.
The first thing you notice in our generate_options function are the parameters $from and $to for the range of options to be generated (days, months and years in our case), and an optional parameter $callback, which is a callback function (more on that in a moment).
Inside the function, we define $reverse as false. If we use the function in the following manner: generate_options(1,31), we are just generating a series of option elements and outputting them in the same order. If we switch the positions of the parameters the output is in reverse order.
This is exactly what we do in line 5. We check if the range of $from and $to is reversed and setting $reverse to true. But in the same time, we are exchanging their values, so that we use the same for construct as in our normal generation. If we haven't done this we would have had to write another for to do this job.
Next we fill an array called $return_string with the generated options, reversing it if necessary and outputting it as string by joining the array elements.
Remember the $callback I talked about earlier? Here comes its part. On line 18 we check if a $callback was supplied - as in generate_options(1,12,'callback_month'), and if it was, we execute the function and supplying the current $i counter's value. In practice, it is the same as if we were doing callback_month($i).
Later we have the callback_month function, which we use as a callback in the month generation. It basically takes an integer parameter (our $i above), and returns the month name as string.
The jQuery source
Ok, now that we have completed the form's looks, we need to be able to send the data over to the PHP backend where it is processed. For this purpose, we are using jQuery, which you can include in page by putting these lines of code in your page's head section:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"> </script>
The library is automatically included from Google's CDN. After that you can use jQuery's ajax method.
Here is the code located in script.js.
$(document).ready(function(){ // UPDATE: commented out because the submit() method was added below instead //$('.greenButton').click(function(){ // register(); //}); $('#regForm').submit(function(e) { register(); e.preventDefault(); }); }); function register() { hideshow('loading',1); error(0); $.ajax({ type: "POST", url: "submit.php", data: $('#regForm').serialize(), dataType: "json", success: function(msg){ if(parseInt(msg.status)==1) { window.location=msg.txt; } else if(parseInt(msg.status)==0) { error(1,msg.txt); } hideshow('loading',0); } }); } function hideshow(el,act) { if(act) $('#'+el).css('visibility','visible'); else $('#'+el).css('visibility','hidden'); } function error(act,txt) { hideshow('error',act); if(txt) $('#error').html(txt); }
The first lines of code in $(document).ready get executed after the page has loaded and bind our register() function with the form's onsubmit event utilizing the preventDefault() method in order to stop the form from being submitted.
And here is the simplicity of the $.ajax method (line 23) - in a few lines of code we send to submit.php by POST all of regForm's fields (regForm is the ID of our registration form). We receive a response in JSON format (for more on that later) which gets processed by the function given in success. In this example (lines 30-37) we process the returned object and decide whether to show an error, or redirect to a registered-user-only page.
Later we have the hideshow() function which hides or shows an element on the page (for example the rotating gif animation on our form) and the error function which manages the displaying of errors on the form.
But how do we decide whether the information in the form is correct, and where to redirect the user if it is?
This is done in submit.php:
// we check if everything is filled in if(empty($_POST['fname']) || empty($_POST['lname']) || empty($_POST['email']) || empty($_POST['pass'])) { die('{status:0,txt:"All the fields are required"}'); } // is the sex selected? if(!(int)$_POST['sex-select']) { die('{status:0,txt:"You have to select your sex"}'); } // is the birthday selected? if(!(int)$_POST['day'] || !(int)$_POST['month'] || !(int)$_POST['year']) { die('{status:0,txt:"You have to fill in your birthday"}'); } // is the email valid? if(!(preg_match("/^[\.A-z0-9_\-\+]+[@][A-z0-9_\-]+([.][A-z0-9_\-]+)+[A-z]{1,4}$/", $_POST['email']))) die('{status:0,txt:"You haven\'t provided a valid email"}'); echo '{status:1,txt:"registered.html"}';
Here we check some of the most typical error situations. Every message, that we output, has to be formatted as a javascript object with status and txt properties. They are accessible in our AJAX as msg.txt and msg.status. The main idea here is that errors return a status with a value of 0 and a successful registration returns a status 1, with txt being a URL of a resource accessible only for registered users.
*Note that you'll have to add code for inserting new database records, creating sessions and a few more error checks on your own, depending on your needs.
And with that our form is finished.
Conclusion
Today we created a fancy looking and functional registration page, inspired by no other than facebook itself. We successfully used jQuery and the $.ajax method to create a real time, asynchronous registration form, complete with error checking and browser redirects.
Bootstrap Studio
The revolutionary web design tool for creating responsive websites and apps.
Learn more
As you stated, the "little PHP function to generate all the option elements that go into the select boxes comprising the selection of a birth date" is very concise coding and a good solution.
On line 23 of the index.php file the href="demo.css"> doesn't self-close. To validate in XHTML the element must be closed with "/>" instead of ">" .
On line 82 of the index.php no alt tag is specified. Also required for validation.
Toward the bottom of the submit.php file you include a note about a need to create a "member-area.php", "where member-area.php is the address on your site where registered users are redirected after registration".
This tutorial would be much more complete if either this "member-area.php" or config.php and sql files were included. The purpose of the config.php file would of course be to implement database parameters, e.g.
// mysqli('localhost', 'yourUsername', 'yourPassword', 'yourDatabase');
$db = new mysqli('localhost', 'yourUsername', 'yourPassword', 'yourDatabase');
The purpose of the sql file is, of course, to create the MySQL tables.
Please provide a link to download the member-area.php file or include further instructions on creating config.php and sql files as an addendum.
Thanks.
Nice tut', but you should add :
$('#regForm').submit(function() { register(); }
Otherwise users won't be able to submit the form with the keyboard (by pressing the return key for example)
@Robert Visser
Thank you for noticing. Now the code validates properly.
As for the registration itself (SQL, sessions etc), I am afraid that it is a bit out of the scope of this tutorial.
If however there is sufficient interest on the subject, I will gladly write a follow-up, explaining how this works and maybe build my examples around this same registration form.
@Thomas Menga
A great suggestion. I added it to the tut and demo files.
Going to help me out on next form...thanks!!
That’s great, never knew it could be that easy!
Thank you for a very good instruction.
Please i would realy appreciate it if you could explain more about how to add code for inserting new database records and creating sessions, with some example on how to do it.
This is part of what i have to do in one of my university course and i am begging you to help me out on that part.
Thank you
Hi,
First of all thanks for the tutorial which I follewed. I only have one question about it;
The function register is called twice, one time on form submit and one time when the submit button is clicked. This results in my situation that de PHP file is loaded twice.
Is this normal of do I have a mistake in my code?
Hope to get an anwser.
Thanks for the comment Orves.
You are right - the login() method is called twice and it shouldn't. Updated the demo and the download files.
The submit() handler was added later on in the tutorial and I've omitted removing the click event handler.
Hi there,
Great tutorial, helped a lot, that is what I was looking for.
dont want to bother You but I tried to make it actually work, I changed few fields (removed sex and DOB, inserted nickname instead). Here is the code that I added:
//Database Information
$dbhost = "localhost";
$dbname = "register";
$dbuser = "user";
$dbpass = "**";
//Connect to database
mysql_connect ( $dbhost, $dbuser, $dbpass)or die("Could not connect: ".mysql_error());
mysql_select_db($dbname) or die(mysql_error());
$name = $_POST['fname'];
$lname = $_POST['lname'];
$email = $_POST['email'];
$nickname = $_POST['nickname'];
$password = md5($_POST['password']);
// lets check to see if the username already exists
$checkuser = mysql_query("SELECT email FROM users WHERE email='$email'");
$username_exist = mysql_num_rows($checkuser);
It kinda works, it insert data into databas, checks if email is unique, but no matter what, it throuws out an error message that I inserted in last peace ("This email Address is already registered!") and doesnt print out echo"You have successfully Registered";
Any ideas?
Thanx :)
@ Domas
In the tutorial, instead of printing that you've been registered successfully, the script redirects you to a success page.
To instead print out that you've been registered you'll have to edit the success function on line 28 of script.js.
Once you've done this you'll also need to echo the messages as a JS object. For example:
echo “You have successfully Registered”;
Will become:
echo '{status:1,msg:"You have successfully registered}';
To make it easier you could create a function in PHP that formats the output messages for you.
thanks for a nice tutorial....i tried and its working..meaning i can display all the errors.
except when i want to display the success page,it doesn`t work for me..help please what i shoul do?
here is where the problem arises...
$query=mysql_query("INSERT STATEMENT HERE");
if($query){
echo'{status:1,txt:"afterreg.php"}';
}
the afterreg.php page is will not display...it only shows the ajax loading image for long time...While the query was successfull.
HELP ME PLEASE.
@ charles
It would be better to check if the query was successful with the mysql_affected_rows() function.
Replace the row:
if($query){
With:
if(mysql_affected_rows($link)==1)
see this is how i did it
$query="INSERT INTO login SET name='$names',location='$country',passreal='$passreal',relation='$relation',gender='$gender',user='$user',email='$email',nywali='$password',date=CURDATE(),day='$day',month='$month',year='$year'";
$result=mysql_query($query,$dbcnx);
if(mysql_affected_rows($result)==1){
echo'{status:1,txt:"afterreg.php"}';
}
if i a register something it goes to the database the problem is just the success message page is not dispplaying.
i`m confused here
And As you know this is the important part in Registartion
I see a problem with your code:
if(mysql_affected_rows($result)==1){
The function mysql_affected_rows takes a mysql link as a parameter. In this case $link should be provided instead of $result.
@Martin Thankx very Much))The problem was as u suggested..Now its working.
be blessed.
Great tutorial, I'm a newbie and have no idea of how to create all the associated files to complete this tutorial. I would very much appreciate if you can either provide the complete tutorial or the complete files for downloading to learn from.
Thanks for a great tutorial, by any chance would you have a complete tutorial to build a CMS system with all the features of bold, italic etc and uploading of pics with css design.
Any help would be much appreciated.
Hi,
Thanks for this great tutorial
I just need to do something additional: Coloring the field that generates the error... How can I do it??? thnks
Great tutorial. You have overlooked one important factor though: the form still validates if you select February 31. When February is selected, Facebook's form resets the day list if it has a selection of 30 or 31, or 29 on a non-leap year.
Thank You Very nice jop i like facebook
Thanks for this useful article. Best regards.
Thank you Thanks for this useful article. Best regards.
Nice article - just one problem. On the Facebook registration page, when you change the month / year fields, the day box automatically updates as well.
For example, if you select February, then the day dropdown contains days up to 29 only, not 31.
Also, if you select a non leap year, it filters to 28 days.
Would have been nice to see that in this example as it is a critical element of the Facebook Registration page :)
HI MArtin, great script and thanks for sharing. The script however does not work with jquery/1.4.1/jquery.min.js. Just wondering if you'd updated it by any chance.
Cheers
Updated to work with jQuery 1.4 and above.
The submit.php from above is a bit wrong. That should be fixed in the Tutorial.
You should write
die('{"status": 0, "txt": "You have to fill in your birthday"}');
instead of
die('{status: 0, txt: "You have to fill in your birthday"}');
(The difference is in the quotes of status and txt)
In the download example this is correct.
And the CSS:
What is that ".formline" Class for? I've seen it nowhere in the HTML.
Great Tutorial by the way.
For production purposes when php.ini's short_open_tag = Off
File in question: index.php
THESE LINES:
<?php=generate_options(1,12,'callback_month') ?>
<?php=generate_options(1,31) ?>
<?php=generate_options(date('Y'),1900) ?>
SHOULD BE CHANGED TO:
<?php echo generate_options(1,12,'callback_month') ?>
<? phpecho generate_options(1,31) ?>
<?php echo generate_options(date('Y'),1900) ?>
Overwriting short_open_tags ini_set() is not very usefull, since this setting should be known by PHP before parsing the php-file.
It is better to ALWAYS use <?php instead of relying on short open tags.
Advice research from:
http://bytes.com/topic/php/answers/567880-why-ini_set-short_open_tag-1-didnt-work
http://forums.devnetwork.net/viewtopic.php?f=1&t=107576
Otherwise the Birthday select option fields will not work.
It will increase the Chances for the application to work on different php servers/machines "IF" the download source code will be modified accordingly.
But this is a great resource anyway, without which I would not be able to say a BIG THANKS! : )
Blessings From God!
Oliver Bob Lagumen
Hi there, great tutorial and managed to get the registration form working fine on a page. I have made a few tweaks such as popping it up in a modal window, dropping a couple of fields i didnt need etc but essentially its works the same.
Just a quick query about the possibility of having 2 of these forms working from the same page.
Basically I want the registration form popping up in a modal window if the register link is clicked but I also want a link on the same page which pops open a modal window using your form but as a log in form rather than a registration form.
Ive given it a go but cant seem to get it working, there is obviously some conflict somewhere.
Dont really know too much about jquery so really not sure what files I need to edit to get this working - any pointers in the right direction welcome.
Nice little post...you defo need to add a sample database insert into the mix...I'm in the middle of troubleshooting getting the data into my database...normal methods don't seem to want to work :)
I just wanted to make up the numbers so you do...
@Domas
if ( $username_exist > 0
this just says if there is an email address kick out error so im not suprised it was kicking back an error...
Best article published.......
great source of knowledge
Helped me a lot in my project.....
thank You
Keep posting.....
an important issue !!!
if we turn off the browser's javascript and fillup the form with any invalid data it will be posted to target php file. means validations bypasses
nice tutorial as always martin, but i have a question
i need to check for email availability in this form for this i add these lines of code in the submit.php
and my db.php is a simple database connection.
but this code is not working it only showing the processing button when i m clicking on sign up, can you please tell me what i m doing wrong.
You shouldn't use mysql_real_escape_string directly on the $_POST variable unless a connection to the database has already been established it needs to be linked to your database function. One way is to return a link_id from your connect function which I see is also not there. An example would be $link_id = mysql_connect ($server,$username,$password) then select database mysql_select_db ($database_name,$link_id ) escape your data $email = mysql_real_escape_string($_POST['email'],$link_id);
query database mysql_query("SELECT * FROM
users
WHERE username = '$email'") then check mysql_affected_rows($link_id) for the count returned by the query. You can ommit the $link_id on the mysql functions but you still need to connect to the database before you can use them including any escaping of input.You mentioned the fact that because Facebook uses tables it wins it for you. However I disagree. Zuckerberg may be a genius when it comes down to marketing but the pages of Facebook is so riddled with erorrs and bad programming it renders the fact that whatever Facebook conciders good practice is isually the opposite. No one is happy with the way Facebook looks, it's appearance is bland to say the least. Yet it hardly ever functions properly due to the countless errors on the pages. Zuckerberg is more interested in turning a profit than what his users think.
Hi! It's great but i have notice something in the birthday part. in facebook, the number of days change depending on what month and year. example, if the month is february, the number of days will only be 29 and not 31 and if the year is not a leap year, the number of days in the month of february will become 28. Will you teach me on how to do that? I'll wait for your reply in my mail.
Thank you Martin for your time writing such a great tutorial. Much appreciated.
I have a question, I try to prevent user from directly execute submit.php.
http://demo.tutorialzine.com/2009/08/creating-a-facebook-like-registration-form-with-jquery/submit.php
by adding this code at the top of submit.php:
It redirects user to index.php if he/she executes the submit.php from the browser.
It's working fine but when I click signup button the form keep showing processing image. How to fix it?. Thanks.
Hey,
I m not able to add the fields into my database.
Where should i write the code for getting the field values in the variables.
If i type echo into submit.php it keeps on loading only.
If i write it in register.php then the post values arent fetched!
swapnil,
FYI, you need to add a semicolon after each "if" statement on submit.php.
Shaun
Hi..
very nice.. here is the updated new facebook style registration form - http://w3lessons.info/2013/10/17/facebook-style-homepage-design-with-registration-form-login-form-using-css3/
Thanks
Hi..
very nice.. here is the updated new facebook style registration form
Thanks
Hey..martin buddy i don't you are reading this comment or not...but man you saved me..your post is like a coin to a begger person..thanks man you are there for me where i need you most..thanks so much :)