Write Social Applications for Imeem in ActionScript Using Adobe Flex: Part 4

Wagz Lu
Welcome to part 4 of the series of tutorials about writing social applications for imeem using ActionScript in Adobe Flex. In the last article, we completed the login functionality - allowing users to log in to imeem via our application. We have yet to allow them to log out. So far, our app looks like this.

Today we'll see how we can add a song to an existing playlist. Here's how the functionality will work (be implemented):

  1. Users search for songs
  2. Search results are displayed in the datagrid
  3. Users right click on a song, then menu will show up with the option "Add song to playlist"
  4. If they are logged in, we'll pop up a window populated with their existing playlists and allow them to choose a playlist to add the song to. We'll then add the song to the chosen playlist - if song is already in playlist.
  5. If they are not logged in, we'll void the whole add to playlist stuff and show the login screen. They will then log in and retry the "add song to playlist" function.
  6. ...and that'll be it - at least, for now!
From our specifications above, we can see that items 1 & 2 have been completed. Also, the login function is already in place. So we'll start with item 3: allowing context menu for the datagrid. Let's get to it!

Using Source View on the original mxml file, declare a variable of type ContentMenu, like this:

private var m:ContextMenu;

Then inside the onInit method, let's create the context menu functionality for the datagrid. Add these 2 lines to the onInit method:

createContextMenu();
dgResults.contextMenu = m;

Now let's create the newly introduced method, createContextMenu.

private function createContextMenu() : void {
m = new ContextMenu();
m.hideBuiltInItems();

//create array to hold our custom commands for the context menu
var customItemsArr : Array = new Array();
//we only have 1 item
var plAdd : ContextMenuItem = new ContextMenuItem("Add Song to Playlist");
//when users click on that item, this method will be called
plAdd.addEventListener("menuItemSelect", onPlaylistAdd);

//add single to array
customItemsArr.push(plAdd);
//add our custom items to Context Menu
m.customItems = customItemsArr;
}

Refer to the comments for clarification. Now, let's define the method that'll take care of clicking on Add Song to Playlist.

private function onPlaylistAdd(e:ContextMenuEvent) : void {
//if user is not logged in, show login screen and return
//TODO: show login screen if not logged in

//else proceed
var grid : DataGrid = DataGrid (e.contextMenuOwner);
var dgItemRenderer : DataGridItemRenderer = e.mouseTarget as DataGridItemRenderer;

//make sure there's a valid item
if(dgItemRenderer == null) return;

var itemIndex : Number = grid.itemRendererToIndex(dgItemRenderer);
var item : Object = grid.dataProvider[itemIndex];

//pass id of chosen song to method SavePlaylist to add song to playlist
SavePlaylist(item.id);
}

Before we write the method SavePlaylist, let's talk about what it'll do.

  1. Show pop up window with current playlists for user - in a combo box
  2. Determine if song should be added to playlist - tell user if song is already there!
  3. Close pop up window
Did you guess that we'll need another MXML component (much like the login screen)? That's right; we need one!

Go to File -> New -> MXML Component. Name it UserPlaylist. Set Based on to TitleWindow. Click Finish. In Design View, give it a title (Add Song to Playlist). Set Show close button to true. Like this. Give IDs to both controls (combo box, ID = cbPlaylist; button, ID = btnSave).

Switch to Source View to write some code.

Locate the mx:TitleWindow tag, and add this: close="titleWindow_Close(event)". Locate mx:Combobox and add labelField="title". Generate the mx:Script section, and add the following:

import mx.managers.PopUpManager;
import mx.events.CloseEvent;

private function titleWindow_Close(e:CloseEvent) : void [
PopUpManager.removePopUp(this);
}

Save UserPlaylist.mxml. Now go back to the original mxml file (imeemMusicExtension.mxml); we'll define the SavePlaylist method.

Go to the variable section and declare:
private var plWin : UserPlaylist;

While you're in that section, let's add a variable that will hold the current user ID. We need it to load the playlists; playlists are loaded by userID.
private var currentUserID : String;

Then scroll down to the methods section, and define:

private function SavePlaylist(id:String) : void {
plWin = PopUpManager.createPopUp(this, UserPlaylist, true) as UserPlaylist;
PopUpManager.centerPopUp(plWin);
var t:Array = new Array();
t.push("musicPlaylist");

imeemService.playlists.getByUser(currentUserID, t, "personal", (function (e){
plWin.cbPlaylist.dataProvider = e.data;}));
}

In the above method, we create/show the pop up. We query imeem for the current user's playlists and load them into the combo box. We'll come back to the different parameters used above - when we talk about imeem API. One thing to note here is that we use an inline function for the callback method expected. We do so by: (function (e) { plWin.cbPlaylist.dataProvider = e.data; } ). More on that later.

What about setting the currentUserID field? It happens inside the function that loads the user's info: onUserLoaded. So go to that function, and add: currentUserID = result.data.id;

You should be able to run the application and see something like this. First, log in. Second, search for songs/artists. Third, right click on a song and you should see the option "Add Song to Playlist". Click it and you'll see all of your playlists show up in the combo box - that's if you currently have any playlists on imeem. If you don't have any playlists, go create one and try again.

Next time, we'll add the Save functionality - so that users can actually add songs to their playlists. Also, we'll finish anything that's left for this section, e.g. the TODO section above.

Stay tuned!

Published by Wagz Lu

View profile

2 Comments

Post a Comment
  • Wagz Lu (article author)11/16/2009

    Watson, you are right about the missing import. We do need to import DataGridItemRenderer
    like so,
    import mx.controls.dataGridClasses.DataGridItemRenderer;

    Hopefully, you will see my comment. By the way, if anyone is interested in getting the complete source code (.zip) give me your email and I'll send it to you.

    Thanks.

  • watson11/16/2009

    there seems to be an error in your code.
    What is the DataGridItemRenderer?
    you never import it and I can't find it in the help.

    anyone else having trouble with this step

Displaying Comments

To comment, please sign in to your Yahoo! account, or sign up for a new account.