Advertisement

Create a Facebook Graph API App in Flash: Loading Events

by

Welcome back to our Facebook Flash application tutorial! In this part, we're going to continue building the Flash interface for creating the embed code. This time, we'll generate a code to load the events from a Facebook Page.


Also Available in This Series:

  1. Create a Facebook Graph API App in Flash: Setup and Design
  2. Create a Facebook Graph API App in Flash: Generating Embed Code
  3. Create a Facebook Graph API App in Flash: Loading Events
  4. Create a Facebook Graph API App in Flash: Displaying Facebook Info

Final Result Preview

This application allows you to select a Facebook album or event list from one of your public pages and turn it into a slideshow for your page tab. When the users enter your page, they will see photos from your chosen album, with your photo title and description, or event name, date and invites ( for the event tab ).

You'll need to be logged in to Facebook in order to see this demo: https://apps.facebook.com/activetuts_tabmaker/


Step 1: Where We Left Off

In the second part, we created the embed code for the album ( basically finding out the album ID from which we load the photos ). This time, we are going to use the Graph API to get a list of a page's events, based on its Page ID.

The functionality is similar to the album choosing mechanism, which we covered previously, so I'll go through these steps a bit faster. Open EventMaker.as from the tabmaker folder and write the following code:

 
package tabmaker 
{ 
	import flash.display.*; 
	import flash.events.*; 
	import flash.net.*; 
	import flash.text.*; 
	import flash.external.ExternalInterface; 
	import flash.system.*; 
	import fl.motion.Color; 
 
	import com.greensock.*; 
	import com.greensock.easing.*; 
 
	import com.facebook.graph.Facebook; 
 
 
	public class EventMaker extends Sprite 
	{		 
		private var state; 
		private var main; 
		private var heading; 
		 
		private var rs; 
		private var page_id; 
		private var container; 
		private var ct; 
		private var next_pager; 
		private var prev_pager; 
		private var offset; 
		private var cbox; 
		private var instr; 
		private var show_event_photos; 
		private var PAGE_ROWS = 3; 
		private var EVENTS = 4; 
		 
		private var EMBED_CODE = '<object src="event_tab.swf?page_id=%s&%arg"></object>'; 
 
		public function EventMaker( m ) 
		{ 
			main = m; 
			main.debug('EventMaker instanced'); 
		} 
         
    } 
     
}

Just as in the case of the AlbumMaker class, we are defining some variables: state, which will hold where we are in the application; heading, which is the same text field we used in the AlbumMaker class; and page_id, which will hold the Page ID we'll need to generate the embed code.


Step 2: Constructor Function

When the class is instantiated, we need to load the user's accounts, just like we did in the AlbumMaker class:

 
public function EventMaker( m ){ 
    main = m; 
    main.debug('EventMaker instanced'); 
     
    state = 1; 
    create_heading('Select a page'); 
     
    //get the accounts 
    Facebook.api('me/accounts', accounts_loaded, {limit: 100} ); 
     
    container = new Sprite(); 
    container.y = 120; 
    addChild( container ); 
     
    next_pager = new NextButton(); 
    next_pager.addEventListener( MouseEvent.CLICK, pager_next ); 
    prev_pager = new PrevButton(); 
    prev_pager.addEventListener( MouseEvent.CLICK, pager_prev ); 
    prev_pager.x = 40; 
    prev_pager.y = next_pager.y = 450; 
    next_pager.x = 200; 
    next_pager.visible = prev_pager.visible = false; 
    addChild( next_pager ); 
    addChild( prev_pager ); 
}

In the constructor, I load the /me/accounts graph endpoint to get the pages. In order to have the same title, we are going to copy the create_heading() function from the EventMaker:

 
private function create_heading( txt ){ 
    if( heading ){ 
        removeChild( heading ); 
    } 
    heading = new TextField(); 
    heading.defaultTextFormat = new TextFormat('Helvetica',14,0xffffff,true ); 
    heading.text = txt; 
    heading.selectable = false; 
    heading.autoSize = 'left'; 
    heading.x = 20; 
    heading.y = 100; 
    addChild( heading ); 
}

Next, we've added the Next and Previous buttons which we'll use to paginate the results ( in case there are a lot of them ).


Step 3: The accounts_loaded() Function

This function is again very similar to AlbumMaker.accounts_loaded(); we need to get only the pages, and not Facebook apps:

 
private function accounts_loaded( succ, fail ){ 
    rs = new Array(); 
    if( succ ){ 
        var i=succ.length; 
        if( i > 0 ){ 
            while( i-- ){ 
                if( succ[i].category !== 'Application' ){ 
                    rs.push( succ[i] ); 
                } 
            } 
        } 
        offset = 0; 
        show_pages(); 
    } else { 
        main.show_error('An error occured loading your pages'); 
    } 
    show_pager(); 
}

Here, I create the same rs variable, which will hold the results, and push every page to it. In case we don't have any results, we show an error message.


Step 4: show_pager() Function

Let's code the show_pager() function which shows the pages we loaded:

 
private function show_pages(){ 
    var ypos = 20; 
    if( rs.length > 0 ){ 
        for( var i=offset; i< (offset+PAGE_ROWS); i++ ){ 
            if( rs[ i ] ){ 
                var p = new PageItem( rs[ i ], main ); 
                p.addEventListener( MouseEvent.CLICK, load_events ); 
                container.addChild( p ); 
                p.y = ypos; 
                ypos += (p.height+20); 
                 
                 
            } 
        } 
         
    } else { 
        main.show_error('You have no pages created.'); 
    } 
    show_pager(); 
}

We're using a variable ypos to put the pages in rows. The PageItem class is the same class we used in AlbumMaker, so we're just going to instantiate it, and it will just work. If you want to see how it's done, look back at Part 2.

If the rs variable is empty, we show an error that the user has no pages created. (You have to always think ahead, as this can be a bit weird for a user who doesn't have any page or doesn't understand the functionality.)

Next, we'll create the pagination, like we did for the AlbumMaker class.


Step 5: Recordset Pagination

Let's code the paging functions:

 
private function show_pager(){ 
    var nrows = 0; 
    if( state == 1 ){ 
        nrows = PAGE_ROWS; 
    } else { 
        nrows = EVENTS; 
    } 
    //main.debug( offset+nrows ); 
 
    next_pager.visible = Boolean(rs[offset + nrows]); 
    prev_pager.visible = Boolean(offset > 0); 
} 
 
private function pager_next( e ){ 
    clear_pages(); 
    if( state == 1 ){ 
        offset += PAGE_ROWS; 
        show_pages(); 
    } else { 
        offset += EVENTS; 
        show_events(); 
    } 
} 
private function pager_prev( e ){ 
    clear_pages(); 
    if( state == 1 ){ 
        offset -= PAGE_ROWS; 
        offset = (offset<0)? 0 : offset; 
        show_pages(); 
    } else { 
        offset -= EVENTS; 
        offset = (offset<0)? 0 : offset; 
        show_events(); 
    } 
} 
 
private function clear_pages(){ 
    while( container.numChildren ){ 
        container.removeChildAt( 0 ); 
    } 
}

These functions are more or less the same as in the AlbumMaker class, so I won't get into these here. The important thing is that once you click the Next button, the pages get paginated ( that sounds a bit redundant! ). We also use the constants PAGE_ROWS and EVENTS to show a certain number of pages.


Step 6: Loading the Events

This is where it gets interesting again: we're going to use the chosen page's ID to load the events of that page:

 
public function load_events( e ){ 
    state = 2; 
    main.debug('Loading events'); 
     
    page_id = rs[ offset+container.getChildIndex( e.target ) ].id; 
     
    clear_pages(); 
    create_heading('Events:'); 
     
    Facebook.api( '/'+page_id+'/events', events_loaded, {limit: 100} ); 
}

Basically, we find out the page ID from its childIndex - remember, the clips are added in the order of the recordset variable, so we can count on the child index to return us the correct index in the rs array. We then clear the pages using the clear_pages() function.

Also, we change the title to "Events:" and call the most important function: the Facebook.api() with the endpoint /{event_id}/events which will return every event the page has ( as long as they are public, of course ).


Step 7: Showing the Events

Now, let's show a couple of events so the user can make sure he is selecting the right page:

 
private function events_loaded( succ, fail ){ 
    rs = new Array(); 
    if( succ ){ 
        var i=succ.length; 
        if( i > 0 ){ 
            while( i-- ){ 
                rs.push( succ[i] ); 
            } 
            offset = 0; 
             
            show_events(); 
            show_codebox(); 
            show_instructions(); 
             
        } else { 
            main.show_error('You have no events set on this page.'); 
        } 
         
    } else { 
        main.show_error('An error occured loading your events'); 
    } 
    show_pager(); 
}

Again, very simple: we populate the rs array again with the event, set the offset variable to 0 and call the show_events(), show_codebox() and show_instructions() functions ( which, if you recall from Part 2, will handle the last part of code generation ).

In the case where there are no events, we also show an error. Again, it's important to have your app show warnings to the user, as otherwise he would get stuck and wouldn't know what to do.


Step 8: Showing the Events, for Real

Okay, let's make the show_events() function:

 
private function show_events(){ 
    var ypos = 20; 
    for( var i=offset; i< (offset+EVENTS ); i++ ){ 
        if( rs[ i ] ){ 
            main.debug( rs[i] ); 
            var p = new EventItem( rs[i], main ); 
            container.addChild( p ); 
            p.y = ypos; 
            ypos += 70; 
        } 
    } 
    show_pager(); 
}

In this function, I am looping through the events and creating an EventItem from each; we'll create this class next.


Step 9: The EventItem Movie Clip

We need to make the "event item" movieclip. Open tabmaker_app.fla and create a 65x300pc rectangle, turn it into a movie clip, and add two text fields, as in this picture:



Step 10: The EventItem Class

We're going to use these two text fields to show the event title and the event description. Build the class:

 
package tabmaker { 
	 
	import flash.display.*; 
	import flash.events.*; 
	import flash.net.*; 
	import flash.text.*; 
	import flash.external.ExternalInterface; 
	import flash.desktop.*; 
	import fl.motion.Color; 
	 
	import com.greensock.*; 
	import com.greensock.easing.*; 
	 
	public class EventItem extends MovieClip { 
		 
		private var cfg; 
		private var main; 
		private var ct; 
		 
		public function EventItem( cfg, main ) { 
			this.cfg = cfg; 
			this.main = main; 
			this.addEventListener( Event.ADDED_TO_STAGE, init ); 
			 
			ct = new Color(); 
			ct.tintColor = 0xFFFFFF; 
			ct.tintMultiplier = 0.1; 
		} 
		 
		private function init( e ){ 
			title_txt.text = cfg.name; 
			var time = cfg.start_time.split('T'); 
			var loc = (cfg.location)? 'In '+cfg.location+' at ' : 'At ';  
			desc_txt.text = loc+time[0]+' '+time[1]; 
			mouseChildren = false; 
			buttonMode = true; 
			 
			this.addEventListener( MouseEvent.MOUSE_OVER, on_over ); 
			this.addEventListener( MouseEvent.MOUSE_OUT, on_out ); 
		} 
		 
		private function on_over( e ){ 
			this.transform.colorTransform = ct; 
		} 
		 
		private function on_out( e ){ 
			this.transform.colorTransform = new Color(); 
		} 
		 
	} 
	 
}

Let's see what happens here:

  • We receive the cfg object, which contains the title and description.
  • We use Event.ADDED_TO_STAGE to make sure the text fields exist when I set the text; otherwise, we could get a compile time error.
  • We also construct the description, manually adding the location and time.
  • The rest is just a hover and mouseout function for the movieclip.

Step 11: The EventMaker's Codebox

I used the same CodeBox class from Part 2 to generate the embed code:

 
private function show_codebox(){ 
    show_event_photos = new CheckBox(0, 'Cycle event photos'); 
    show_event_photos.x = 380; 
    show_event_photos.y = 110; 
    addChild( show_event_photos ); 
    show_event_photos.addEventListener( MouseEvent.CLICK, cycle_handler ); 
     
    cbox = new CodeBox( EMBED_CODE, page_id ); 
    cbox.x = 380; 
    cbox.y = 140; 
    addChild( cbox ); 
} 
 
private function cycle_handler( e ){ 
    cbox.set_argument( 'cycle_photos='+show_event_photos.check_state ); 
} 
 
private function show_instructions(){ 
    instr = new Instructions(); 
    instr.x = 380; 
    instr.y = 300; 
    addChild( instr ); 
}

This function is fairly simple: I created a checkbox, like in Part 2, which will set an argument in the embed code. I also create a CodeBox class and add it to the stage. Finally, we have the cycle_handler() which sets the argument.

The show_instructions function is just a simple function which adds the Instructions movieclip ( which we also created in Part 2 ).


Step 12: Bonus: Publishing to the Feed

Okay, now let's add a bit of interaction to the app.

We want to advertise this Facebook app, but we don't want to spend thousands of dollars on Facebook advertising. Let's make a little modification so that we show the user a share dialog which will publish a small update to his wall. This means that people who see his wall might get interested in the app and use it too.

In the show_codebox() function, add this little bit:

 
private function show_codebox(){ 
    show_event_photos = new CheckBox(0, 'Cycle event photos'); 
    show_event_photos.x = 380; 
    show_event_photos.y = 110; 
    addChild( show_event_photos ); 
    show_event_photos.addEventListener( MouseEvent.CLICK, cycle_handler ); 
     
    cbox = new CodeBox( EMBED_CODE, page_id ); 
    cbox.x = 380; 
    cbox.y = 140; 
    addChild( cbox ); 
    cbox.getChildByName('copy_btn').addEventListener( MouseEvent.CLICK, publish_feed ); 
} 
 
private function publish_feed( e ){ 
    Facebook.ui('feed', {name: 'TabMaker app', caption: 'Tabmaker App', description: 'I just used the Tabmaker App to create a cool page tab!'}); 
}

Using the Facebook.ui function we can show a Facebook dialog ( triggered with JavaScript ) which will encourage the user to share his code generation. It's important to not publish to the feed directly from an app, as some users don't want to share those little informations.

Publishing an item on the user's wall will create a connection between the user and the app, as the status is automatically turned into a link to the application. Talk about free advertising!


The End of Part 3

This is the end of Part 3. In the next and part, we'll tackle the creation of the album slider and event slider, which is the main entry point of this whole application. See you all then and thanks for reading!

Advertisement
Related Posts