Christmas Wishes With Facebook Connect

22 January 2010 Friday

This application was viewed 735 times




Christmas Wishes With Facebook Connect

Providing a simple way for users to authenticate themselves can turn a web application in a much more personal place. But a registration is a time taking process which visitors prefer to go without.

This is exactly where services such as Facebook Connect step in. They let you dive inside their multimillion user base, skipping that tedious registration process that drives people off. Another benefit is that Connect enables you to communicate user activity back to facebook, which is a great promotional tool.

Today, we will develop a webapp which will allow users to add christmas wishes using facebook connect and share them with their friends. We are using CSS, jQuery, PHP, AJAX and MySQL for data storage.

Feel free to download the tutorial files and continue with step one.

View The DEMO

Step 1 – Creating a facebook application

The first step you have to take, is to enable developer functionality for your facebook account.  Providing that you already have a registration, you have to visit the following URL and install the developer application.

After you’ve done that, you’ll need to set up a new application, which will generate a special API key you’ll later have to include in your JavaScript files (more on that in a moment).

For more information on facebook connect, you can watch this great video by the facebook team, and visit the facebook wiki.

The main idea is that we are going to allow users to authenticate themselves with facebook connect, and store only their unique facebook IDs in the database as their identity. We are later using Connect to dynamically fetch additional details about the person (such as the profile picture and the person’s name) and insert it directly into the page.

Another benefit of using Connect is that the wish can easily be posted to the user’s wall with a link to your web app – a great way to promote your site.

Step 2 – XHTML

Now that we’ve set everything up, we can start off by laying down the XHTML structure of the site.

The main part of the markup is generated at run time by the PHP back-end and inserted into the page at designated places.

index.php

01.<div id="main">
02.  
03.<h1 class="tutTitle">Christmas Wishes With Facebook Connect</h1>
04.  
05.<div id="wishesContainer">
06.  
07.<?php
08.// Outputting the wishes to the page:
09.echo $wishes;
10.?>
11.  
12.</div>
13.  
14.<?php
15.  
16.// If this is the first page, show the submit form:
17.  
18.if($page==1):
19.?>
20.  
21.<div id="addWish" class="wish add">
22.<div class="stage">
23.<div class="topIcon"></div>
24.<div class="profile-pic"><fb:profile-pic uid="1" facebook-logo="true" size="s"></fb:profile-pic></div>
25.<div class="name"></div>
26.<div id="share" class="body">
27.  
28.<div class="toggleContent">
29.Connect with facebook to post a wish<br />
30.<fb:login-button onlogin=""></fb:login-button>
31.</div>
32.  
33.<div class="toggleContent" style="display:none">
34.<form action="" method="post" id="wForm">
35.<p>
36.<textarea name="wish" id="wish" cols="20" rows="2"></textarea>
37.<input name="" id="sbutton" type="submit" value="Submit" />
38.<label for="cb">Post my wish to facebook as well</label>
39.<input name="cb" id="cb" type="checkbox" value="1" checked="checked" />
40.<input name="key" id="key" type="hidden" value="<?php echo $_SESSION[´key´] ?>" />
41.</p>
42.</form>
43.</div>
44.</div>
45.<div class="clear"></div>
46.</div>
47.</div>

On line 9 you can see that we output the contents of the $wishes variable on the page. It holds all the markup formed according to the individual entries in the database (covered in detail in Step 4).

Also worth noting are those unfamiliar fb: tags that you’ve probably never seen before.  Those are special tags used by facebook (hence the fb prefix) and are dynamically replaced with real data from facebook’s severs based on the attributes of those tags.

But in order to use those, we have to insert a special xmlns (XML namespace) attribute in the opening <html> tag of our document:

Also you can see the submit form that allows the visitors to add their Christmas wishes to the webapp. Worth noting is that this form is only shown if the user is on the first (or home) page of the site.

Lets continue with the next step.

Step 3 – CSS

Functionality is nothing without looks. So lets add in some styles.

All of our styles are positioned positioned in demo.css. I’ve divided the code into three chunks so it is easier to digest:

demo.css – Part 1

01.body{
02.    /* Setting default text color, background and a font stack */
03.    color:#eeeeee;
04.    font-size:13px;
05.    background:url(img/flakes.jpg) repeat;
06.    font-family:Arial, Helvetica, sans-serif;
07.}
08.  
09.h1.tutTitle{
10.    /* Hiding the H1 - it is only visble by search engines */
11.    display:none;
12.}
13.  
14.#main{
15.    /* The main container */
16.    margin:15px auto;
17.    text-align:center;
18.    width:865px;
19.    position:relative;
20.    display:none;
21.}
22.  
23.a, a:visited {
24.    color:#0196e3;
25.    text-decoration:none;
26.    outline:none;
27.}
28.  
29.a:hover{
30.    text-decoration:underline;
31.}
32.  
33.#header{
34.    width:100%;
35.    height:160px;
36.  
37.    /* Setting the background of the header to show in the center of the page
38.       and blend seemlessly with the background color: */
39.  
40.    background:url(img/header_bg.jpg) no-repeat #ad0303 center bottom;
41.    border-bottom:1px solid #d84b4e;
42.    text-align:center;
43.    margin-bottom:60px;
44.  
45.    /* Relative positioning, so that the #backToTut div is positioned accordingly */
46.    position:relative;
47.}
48.  
49.#backToTut{
50.    /* Positioning the "Back to the tut" link */
51.    position:absolute;
52.    right:30px;
53.    top:40px;
54.}
55.  
56.#logo{
57.    width:880px;
58.    text-align:left;
59.    margin:0 auto;
60.}
61.  
62..wish{
63.    /* A common class, shared by all .wish divs */
64.    padding:10px;
65.    text-align:left;
66.    width:600px;
67.    margin:0 auto 45px;
68.    position:relative;
69.}
70.  
71./* Individual CSS rules for each color: */
72.  
73..wish.green{
74.    background:url(img/green_bg.jpg);
75.    border:1px solid #3ccd1b;
76.}
77.  
78..wish.red{
79.    background:url(img/red_bg.jpg);
80.    border:1px solid #e9403c;
81.}
82.  
83..wish.add{
84.    background:url(img/blue_bg.jpg);
85.    border:1px solid #2976BB;
86.}

The site has a basic structure with a header on the top (the div with an id of header), which takes the full width of the page and the main container, which holds all the content of the site and is centered on the page.

The header’s background is an image with a fixed width (aren’t they all) which fades gracefully to the background color of this same div. This way no matter how wide the visitor’s screen is, they are guaranteed to see a uniform heading section of the site.

You can also see that we’ve defined a general .wish class, which we build on by defining custom backgrounds for the different color classes.

demo.css – Part 2

01..profile-pic{
02.    float:left;
03.    margin-right:10px;
04.}
05.  
06.div div.profile-pic img{
07.    /* Re-designing the facebook avatars */
08.    border:2px solid white;
09.  
10.    /* CSS3 Box Shadow */
11.    -moz-box-shadow:0 0 1px #666666;
12.    -webkit-box-shadow:0 0 1px #666666;
13.    box-shadow:0 0 1px #666666;
14.}
15.  
16.a.fbconnect_login_button {
17.    /* The facebook button */
18.    display:block;
19.    margin-top:7px;
20.}
21.  
22..stage{
23.    /* The .stage divs, which hold the text of the wish */
24.    background:url(img/bg_gwg.png) repeat-y  center top #eeeeee;
25.    border:3px solid white;
26.    padding:8px;
27.  
28.    /* CSS3 Box Shadow */
29.    -moz-box-shadow:0 0 3px #666666;
30.    -webkit-box-shadow:0 0 3px #666666;
31.    box-shadow:0 0 3px #666666;
32.  
33.    /* Fixing the peekaboo bug in IE by triggering the
34.       hasLayout mechanism with the zoom property */
35.    zoom:1;
36.}
37.  
38..topIcon{
39.    /* The icons at the top */
40.    width:128px;
41.    height:120px;
42.    position:absolute;
43.    top:-40px;
44.    right:-40px;
45.}
46.  
47..wish.red .topIcon{
48.    background:url(img/mistletoe.png) no-repeat;
49.}
50.  
51..wish.green .topIcon{
52.    background:url(img/jingle.png) no-repeat;
53.}
54.  
55..name{
56.    color:#888888;
57.    margin-left:114px;
58.}
59.  
60..body{
61.    /* Text of the wish */
62.    color:#555555;
63.    font-size:20px;
64.    padding-top:6px;
65.    margin-left:114px;
66.}
67.  
68.#addWish .name{
69.    /* Initially hiding the name field of the comment form */
70.    display:none;
71.}
72.  
73.#cb{
74.    /* The checkbox */
75.    position:relative;
76.    top:2px
77.}
78.  
79.#sbutton{
80.    /* The submit button */
81.    background:#155C9C;
82.    border:1px solid #093F6F;
83.    color:white;
84.    cursor:pointer;
85.    font-family:Arial,Verdana,Sans-serif;
86.    font-size:12px;
87.    padding:3px;
88.}

There is one aspect of Facebook Connect that might surprise you at first – it automatically includes a stylesheet in your page that might overwrite the styles you’ve set up for things such as the user avatars and names.

For this purpose you can use the !important modifier next to your rules (font-size:12px !important;) or do what I’ve done – provide more elements in the description of the classes, which adds more weight to your rules and overrides those of facebook ( div div.profile-pic img instead of just .profile-pic img, line 6).

demo.css – Part 3

01.#wish{
02.    /* The textarea */
03.    border:1px solid #AAAAAA;
04.    color:#606060;
05.    font-family:Arial,Verdana,Sans-serif;
06.    font-size:20px;
07.    padding:3px;
08.    width:400px;
09.    display:block;
10.}
11.  
12.label{
13.    font-size:10px;
14.}
15.  
16.a img{
17.    border:none;
18.}
19.  
20./* Styling the pagination at the bottom of the page: */
21.  
22..pagination{
23.    font-size:10px;
24.    margin:-15px auto 10px;
25.    text-transform:capitalize;
26.    width:620px;
27.}
28.  
29..pagination a,.pagination a:visited,.pagination span{
30.    background-color:#F2F2F2;
31.    border:1px solid white;
32.    color:#545454;
33.    display:inline;
34.    float:left;
35.    margin:3px 5px 0 0;
36.    padding:4px 6px;
37.    text-decoration:none;
38.}
39.  
40..pagination a:hover{
41.    background-color:#eaf7ff;
42.    color:#444444;
43.}
44.  
45..pagination span{
46.    background-color:#BBBBBB;
47.    border:1px solid #CCCCCC;
48.    color:#666666;
49.}
50.  
51./* The clearfix hack */
52.  
53..clear{
54.    clear:both;
55.}
56.  
57.p{
58.    /* The tut info on the bottom of the page */
59.    padding:10px;
60.    text-align:center;
61.}

In the third part of the code, we style the form elements and the pagination, displayed on the bottom of the page.

Step 4 – PHP

As I mentioned in step one, PHP generates all of the christmas wishes XHTML markup dynamically, after fist selecting them from the database. Lets see how this works.

index.php

01.// Error reporting
02.  
03.error_reporting(E_ALL^E_NOTICE);
04.  
05.// Including additional files
06.require "connect.php";
07.require "functions.php";
08.  
09.// If there is no key, create a new one
10.if(!$_SESSION[´key´])
11.{
12.    // Making a new unique key:
13.    $key = md5(time().$_SERVER[´REMOTE_ADDR´]);
14.    // Saving it to the session. Will be used in post.php;
15.    $_SESSION[´key´] = $key;
16.}
17.  
18.// The total number of wishes. Used in the pagination:
19.list($total)=mysql_fetch_array(mysql_query("SELECT COUNT(*) FROM christmas_wishes"));
20.  
21.$results_per_page=5;
22.$page=1;
23.if((int)$_GET[´page´]>1) $page = (int)$_GET[´page´];
24.  
25.$start=($page-1)*$results_per_page;
26.  
27.// Selecting the wishes from the database. Using te LIMIT cause:
28.$res = mysql_query("SELECT * FROM christmas_wishes ORDER BY id DESC LIMIT ".$start.",".$results_per_page);
29.  
30.$wishes=´´;
31.$c = ´´;
32.$i=0;
33.  
34.while($row=mysql_fetch_assoc($res))
35.{
36.    $c=´red´;
37.    if($i++%2 == 0) $c=´green´;
38.    $wishes .= ´
39.        <div class="wish ´.$c.´">
40.        <div class="stage">
41.        <div class="topIcon"></div>
42.        <div class="profile-pic"><fb:profile-pic uid="´.$row["facebook_id"].´" facebook-logo="true" size="s"></fb:profile-pic></div>
43.        <div class="name"><fb:name uid="´.$row["facebook_id"].´" useyou="false"></fb:name>&nbsp;wished</div>
44.        <div class="body">´.htmlspecialchars($row["wish"]).´</div>
45.        <div class="clear"></div>
46.        </div>
47.        </div>
48.    ´;
49.}

First we generate a special key which is used to check whether the form has been submitted properly and put it add it as a session variable.

As you can see from the XHTML section of the tut, this key is also inserted as a hidden field inside of the form and is later submitted back to the server along the textual body and other data.

It is then checked whether it corresponds with the key in the session. If it does not, this means that the form was submitted without visiting index.php first (a sure sign of a spam bot).

This technique will also prevent double posting, because the session key is unset after a successful insert in the database.

The form is submitted via AJAX, which sends the data to post.php, which is given below:

ajax/post.php

01.// Error reporting
02.  
03.error_reporting(E_ALL^E_NOTICE);
04.require "../connect.php";
05.require "../functions.php";
06.  
07.if(!$_POST[´uid´] || !$_POST[´wish´] || !$_POST[´key´]) die(´0´);
08.  
09.// Checking to see whether the key is in place:
10.if(!$_SESSION[´key´] || $_SESSION[´key´]!=$_POST[´key´]) die(´0´);
11.  
12.$uid = (int)$_POST[´uid´];
13.if(!$uid) die(err(´Please login to facebook first!´));
14.  
15.// Escaping the string and stripping the HTML:
16.$wish = mysql_real_escape_string(strip_tags($_POST[´wish´]),$link);
17.  
18.if(mblen($wish)<4) die(err(´Your wish is too short!´));
19.  
20./* Inserting a new record in the christmas_wishes DB: */
21.mysql_query(´   INSERT INTO christmas_wishes (facebook_id,wish)
22.            VALUES (´.$uid.´,"´.$wish.´")´);
23.  
24.if(mysql_affected_rows($link)==1)
25.{
26.    echo ´{status:1}´;
27.    unset($_SESSION[´key´]);
28.}
29.else echo err(´Something went wrong. Try again!´.mysql_error($link));

It is pretty straightforward. The variables are validated, the data is escaped and inserted in the database. A JSON object is returned which has a status and text property (the latter is initialized only if there is an error and contains the error message).

There is another PHP file – functions.php, which will not be discussed here, but is worth taking a look. Now lets take a look at jQuery.

Step 5 – jQuery

Before being able to use the jQuery library, we have to include it into the page.

index.php

1.<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
2.<script type="text/javascript" src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php"></script>
3.<script type="text/javascript" src="jquery.scrollTo-min.js"></script>
4.  
5.<script type="text/javascript" src="script.js"></script>

I included jQuery directly from Google’s AJAX CDN – this enables us to have the benefits of their huge infrastructure and the likely possibility that the library is already cached in the visitors browser.

The next scripts are the facebook connect library, the jQuery scrollTo plugin (which you’ll see in action in a moment) and our own script file.

All of our JavaScript code is located inside script.js. I’ve split the code in two parts:

script.js – Part 1

01.$(function(){
02.  
03.    /* This code is run on page load */
04.  
05.    /* Showing the wishes, hidden by the CSS. */
06.    $(´#main´).show();
07.  
08.    /* Listening for the submit event on the form */
09.    $(´#wForm´).submit(function(e){
10.        addWish();
11.        e.preventDefault();
12.    });
13.  
14.    function init(){
15.        /* Run on page load if the user is logged into facebook */
16.        $(´#share .toggleContent´).toggle();
17.  
18.        $(´#addWish .name´).html(´Hi, <fb:name uid="loggedinuser" useyou="false" firstnameonly="true"></fb:name>, add your wish below:´).show();
19.        $(´#addWish .profile-pic´).children().attr(´uid´,FB.Connect.get_loggedInUser());
20.        FB.XFBML.Host.parseDomTree();
21.    }
22.  
23.    /* Initializing facebook connect */
24.    FB.init("bcf260ae02d453654be01ec11e2d0aa0","xd_receiver.htm",{"ifUserConnected" : init});

In this first part of the script, we set the code to be run after the DOM has been completely loaded (and all page elements are accessible).

We later define a init() function that displays the submit form and initialize facebook connect (notice the ifUserConnected property – the init() functon is run on page load if the user has logged in previously).

The first parameter of the FB.init function is the API key of the app we created earlier.

script.js – Part 2

01.var commencing = false;
02.  
03.function addWish()
04.{
05.    /* If there is another AJAX process already active stop the function: */
06.    if(commencing) return false;
07.  
08.    /* Stripping HTML tags */
09.    var wish = $(´#wish´).val().replace(/<[^>]*>/g,´´);
10.  
11.    if(wish.length<3) { alert(´Your wish is too short or empty!´); return false; }
12.    if(!FB.Connect.get_loggedInUser()) { alert(´You are not logged in!´); return false; }
13.  
14.    commencing=true;
15.  
16.    /* Sending the data to post.php */
17.    $.post(´ajax/post.php´,{uid:FB.Connect.get_loggedInUser(),wish:wish,key:$(´#key´).val()},function(msg){
18.  
19.        /* This function is run if the data was successfully sent */
20.        commencing=false;
21.  
22.        if(msg.status)
23.        {
24.            /* If there were no errors */
25.            if($(´#cb´).attr(´checked´))
26.            {
27.                var attachment = {
28.                    name:´Christmas Wishes´,
29.                    href:´http://christmas-wishes.tutorialzine.com/´,
30.                    description:´What do you wish for this christmas?´
31.                };
32.  
33.                var action_link=´´;
34.  
35.                setTimeout(function(){
36.                    FB.Connect.streamPublish(wish, attachment, action_link);
37.                },1000);
38.            }
39.  
40.            /* Insert a new wish by duplicating and changing the first wish currently on the page */
41.            var el = $(´.wish´).eq(0).clone()
42.  
43.            if(el.hasClass(´green´))
44.            {
45.                el.addClass(´red´).removeClass(´green´);
46.            }
47.            else el.addClass(´green´).removeClass(´red´);
48.  
49.            el.find(´.body´).html(wish);
50.            el.hide().html(el.html().replace(/uid=\"\d+\"/g,´uid="´+FB.Connect.get_loggedInUser()+´"´));
51.            $(´#wishesContainer´).prepend(el);
52.  
53.            /* Parsing the fb tags: */
54.            FB.XFBML.Host.parseDomElement(el.get(0));
55.  
56.            el.fadeIn(´slow´);
57.  
58.            /* Scrolling the page to show the newly added wish into view: */
59.            $.scrollTo(el,800);
60.            $(´#share´).html(´Thank you!´);
61.        }
62.        else
63.        {
64.            alert(´There was an error trying to add your comment!\nPlease try again in a few moments.´);
65.            return false;
66.        }
67.    },´json´)
68.}
69.});

The second part of the code holds the addWish() function which posts the data via AJAX.

You can see that I’ve used a variable called commencing to figure out whether there is an active transfer in the progress, which allows only one AJAX call at once (and thus preventing unnecessary double-posting caused by multiple clicks on the submit button).

Also, you can see on line 39 that I’ve used the jQuery ScrollTo plugin to scroll the window smoothly so that the newly inserted element is in view.

Step 6 – MySQL

In order to make this work on your own server, you’ll need to create the christmas_wishes MySQL table by running tables.sql, which is included in the download archive.

You’ll have to change your MySQL credentials in connect.php and replace the API key used in script.js with your own.

With this our Christmas Wishes webapp is complete!

Tags: facebook, connect, jquery,


Christmas Wishes With Facebook ConnectBookmark and Share

You write your thoughts

Please login to post comments here from the right corner.

your add
icon free icon icon set vector icon free catalog catalog template jquery news ticker widget tools tutorial php slider video youtube effects menu thumbnail forms facebook zoom image combo multiselect modal polaroid gallery expand code feedback contact navigation slider tagcloud Skateboard psd templates files badges subscribe panel login temlate file free office holland free template tabs prototype css scriptaculous opacity moo autocomplete wordpress themes design theme button images photoshop fonts font nav pdf logo style high javascript pretty photo jqery lightbox Themes Blog popular blog desing joomla xhtml brushes hair footer admin mootols slide show blackbox new download class first plugin upload browse Page effect modalbox web application urlitooltips sliding boxes captions flatchat chat ajax messaging browser hoverlightbox CSS Dev General Javascript PHP SQL search avatar vector Drupal Joomla Oscommerce javaScript phototype manager ajaxplorer flash xml rotator bookmarking pageflip slideshow poll text component script mediaplayer imagegallery pictograms car poster player mp3 radio onlineradio navigations drop-down collection brush tree textures paper pop-up bumpbox web2.0 iphone film frame twitter page fan mail delete dynamic calender form handbook city social paint timeline clock connect bar sharing accordion quotes ticker photo-effects background 3D media player graphic rss leaf green glossy bubble icon comic clean cool web 2.0 png actionscript ietter rotating Menu animated textured site masking pasword app layer sponge bob popup bubble tooltips horizontal prototip tooltip pack charachters comics blog action icon.psd flavour navi tango gradients istanbul mixed css3 sleek animations program html5 website Layer styles ultimate candy Media icons dropdown snow icon innerfade hover sub tag