Pin My Friends Application (using Google Maps and Facebook APIs) – Part 2: Displaying the friends list
- Part 1 – Introduction
- Part 2 – Displaying the friends list
- Part 3 – Displaying the friends on the map
This part will handle the displaying of the user’s friends:
- T.4 – Grab the current user’s friends and display them in a list (no fancy paging just a dumb scrollable list)
- T.5 – Upgrade the above list by displaying the friend location
T.4 – Grab the current user’s friends and display them in a list (no fancy paging just a dumb scrollable list)
- The friend profile will look very similar to the user profile and because there will be a lot of friends to show the best way to avoid messy code is to use a template engine. Because jQuery Templates are discontinued and soon to be replaced by jsRender the former will be used. Create a partial view called _FriendsList in the Views\Shared folder:
<script src="https://raw.github.com/BorisMoore/jsrender/master/jsrender.js"></script> <script id="friendTemplate" type="text/html"> <li> <a href="{{=profile}}" target="_blank"> <img class="left profilePicture" src="{{=picture}}" alt="Friend picture" title="{{=name}}" /> <div class="left"> <div class="profileName"> {{=name}} ({{=gender}}) </div> </div> </a> </li> </script> <div id="friendsList"> </div>
The jsRender script is referenced directly from the github repository. The template is not so different from a jQuery Template version.
-
Render the partial in the _Layout.cshtml view: Just drop @Html.Partial(MVC.Shared.Views._FriendsList) after @RenderBody().
-
Add some styles in Site.css:
/*Friends styling*/ #friendsList { position: absolute; left: 5px; top: 5px; z-index: 500; background-color: transparent; display: none; height: 90%; width: 500px; overflow: auto; } #friendsList ul { margin: 0; padding: 0; list-style-type: none; } #friendsList li { margin: 0; height:64px; } #friendsList a { display: block; margin: 10px; text-decoration: none; background-color: rgba(98,122,172,0.5); border-radius: 10px; height: 64px; } #friendsList a:hover { background-color: rgba(51, 102, 153, 0.5); }
-
Add code in the facebook.js script file to get the friends from Facebook and render the friendTemplate:
function displayFriendsList() { FB.api('/me/friends', { fields: 'name,id,gender' }, function (response) { if (!response || response.error) { //TODO: Display a proper error message alert('An Error Occurred'); } else { var friends = $.map(response.data, function (friend) { return { 'id': friend.id, 'name': friend.name, 'picture': 'http://graph.facebook.com/' + friend.id + '/picture', 'profile': 'http://www.facebook.com/' + friend.id, 'gender': friend.gender == 'male' ? 'M' : (friend.gender == 'female' ? 'F' : 'N/A') }; }); var friendsList = $('<ul></ul>'); friendsList.html($('#friendTemplate').render(friends)); $('#friendsList').html(friendsList).show(); } }); } function clearFriendsLocation() { $('#friendsList').html(''); }
The idea is very simple: Make a call to the Graph API asking the friends of the current user and also limit the fields to: id, name and gender (actually is not limiting but extending because by default only id and name are returned). If everything is ok a new JSON object is returned and passed to the render function. A call to these two methods must be added in the showFacebookProfile and hideFacebookProfile functions.
-
The result:
Figure 2-1. Clicking on a friend in the list will open the Facebook profile
T.5 - Upgrade the above list by displaying the friend location
-
Getting the location (from the current user or for a friend) requires additional permissions from the current user (user_location and friends_location). First step is to modify the Facebook application to require the permissions:
Figure 2-2. Edit the Pin My Friends application and go to Settings\Auth Dialog
-
Modify the FB.login call to include the scope parameter:
//user is not connected to your app or logged out loginText.html('Login with Facebook'); loginButton.unbind('click'); loginButton.bind('click', function () { FB.login(function (response) { if (response.authResponse) { showFacebookProfile(); } }, { scope: 'user_location,friends_location' }); });
-
Modify the displayFriendsList function to request and show each friend location (also add addition code to the template):
function displayFriendsList() { FB.api('/me/friends', { fields: 'id,name,gender,location' }, function (response) { if (!response || response.error) { //TODO: Display a proper error message alert('An Error Occurred'); } else { var friends = $.map(response.data, function (friend) { var location; if (!friend.location || friend.location.id == '') { location = 'Location N/A' } else { location = friend.location.name; } return { 'id': friend.id, 'name': friend.name, 'picture': 'http://graph.facebook.com/' + friend.id + '/picture', 'profile': 'http://www.facebook.com/' + friend.id, 'gender': friend.gender == 'male' ? 'M' : (friend.gender == 'female' ? 'F' : 'N/A'), 'location': location }; }); var friendsList = $('<ul></ul>'); friendsList.html($('#friendTemplate').render(friends)); $('#friendsList').html(friendsList).show(); } }); }
-
The result:
Figure 2-3. Friends list with location