14
Apr

One of the things you will see in many OpenSocial applications is a list of a person's friends combined with a mechanism to move from one page to another. With this list, you might want to just show who the person's friends are, allow the user to pick a set of friends to send a message to, or something else. It's your application, so the choice is up to you. Regardless, the foundation is getting that list of friends and showing it to everyone. It seems like it is about time that I wrote a post showing how to do this common task. For our purposes, we will have a simple page where we want to show a bunch of users and display these 15 users per page. To start with, we have some basic markup defining some CSS styles, a tag to display our list, and a select tag to pick a page.

<style type="text/css">

  .gadget

  {

    background-color: Black;

    height: 100%;

    width: 100%;

  }

 

  h1

  {

    color: White;

    font-family: Verdana,Sans-Serif;

    margin: 15px;

  }

 

  #friendView

  {

    background-color: White;

    width: auto;

    height: 300px;

    margin: 15px;

    overflow: scroll;

  }

 

  #paging

  {

    color: White;

    font-family: Verdana,Sans-Serif;

    margin-left: 15px;

  }

 

  .numberSelect

  {

    background-color: White;

    color: Black;

    width: 70px;

  }

 

  .blockItem

  {

    width: 150px;

    height: 90px;

    float: left;

    margin: 15px;

  }

 

  .nickName

  {

    background-color: Black;

    color: White;

    font-family: Verdana,Sans-Serif;

    text-align: center;

  }

 

  .thumbNail

  {

    background-color: Black;

    vertical-align: middle;

    height: auto;

    width: auto;

    text-align: center;

  }

 

  img.hasMargin

  {

    margin: 15px;

  }

</style>

<div class="gadget">

  <h1>

    Your Friends

  </h1>

  <div id="friendView">

  </div>

  <div id="paging">

    Jump to page:

    <select id="pageNumber" class="numberSelect">

    </select>

    / <span id="numberOfPages"></span>

    <button onclick="jumpToPage();">

      Go

    </button>

  </div>

</div>

As you can see– this is a very simple application. The work happens when someone clicks on the Go button and jumpToPage() gets called. We also want that function to get called when the gadget initially loads and have the function jump to page 1. At startup we call:

gadgets.util.registerOnLoadHandler(function() {

    jumpToPage(1);

});

To load a set of friends, the container (MySpace) needs to know the following information:

  1. Who owns the list? Typically, this is the gadget viewer (logged in user) or gadget owner (individual who installed the application).
  2. Which group should be shown? Normally, the group is the well known group named 'FRIENDS'.
  3. What is the maximum number to return? You can either set the value or accept defaults. I suggest setting the value to a number less than 100 but always set the number so that, if a change happens, your user interface has consistent behavior.
  4. What is the first index to return? Typically, this will be some multiple of the page size. Indexing is 1 based. To get the first page, you set the first index to 1.

The first two items in the list, whom and which group, are satisifed by specifying an IdSpec where one sets the USER_ID and GROUP_ID on a simple JavaScript object. The maximum number is satisified via the MAX and FIRST parameters being set on another JavaScript object. We pass this information to a newFetchPeopleRequest and then send the request to the container. A callback defined by the application is invoked when the response is ready or an error occurs. We can now write jumpToPage(pageNumber):

var stepSize = 15;

 

function jumpToPage(pageNumber) {

    if (pageNumber == undefined) {

        var page = document.getElementById("pageNumber");

        pageNumber = page.options[page.selectedIndex].value;

    }

    var dataRequest = opensocial.newDataRequest();

    var params = {};

    params[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.VIEWER;

    params[opensocial.IdSpec.Field.GROUP_ID] = 'FRIENDS';

 

    var fetchPeopleParams = {};

    fetchPeopleParams[opensocial.DataRequest.PeopleRequestFields.MAX] = stepSize;

    fetchPeopleParams[opensocial.DataRequest.PeopleRequestFields.FIRST] = stepSize * (pageNumber – 1) + 1;

    var idspec = opensocial.newIdSpec(params);

    var fetchPeople = dataRequest.newFetchPeopleRequest(idspec, fetchPeopleParams);

 

    dataRequest.add(fetchPeople, 'fetchPeople');

    dataRequest.send(fetchPeopleResponse);

}

When the response comes back, we get a bunch of information:

  1. We learn how many friends the Viewer has.
  2. We learn some basic information about each friend:
    • Nickname
    • Thumnail URL
    • Profile page URL
    • User ID

The callback function has one parameter that contains the response. The response we want has the name 'fetchPeople' and contains an array. We will get the array out and then display all of our friends. If the callback has never been executed, we'll also populate the <select> box with a list of all the pages one can select, based on the total number of friends and the size of a single fetch. After each callback, the innerHTML of the friendView <div> will contain pictures for the current page of friends.

var totalFriends = -1;

function fetchPeopleResponse(response) {

    var ppl = response.get('fetchPeople').getData().asArray();

    var i;

    var html = "";

    for (i = 0; i < ppl.length; ++i) {

        var person = ppl[ i ];

        html += "<div class='blockItem' id='" + person.getField(opensocial.Person.Field.ID) + "'>" +

                "<div class='thumbNail'><img class='hasMargin' src='" +

                person.getField(opensocial.Person.Field.THUMBNAIL_URL) + "' alt='" +

                person.getField(opensocial.Person.Field.NICKNAME) + "'/></div>" +

                "<div class='nickname'>" + person.getDisplayName() + "</div></div>";

    }

    var friendView = document.getElementById("friendView");

    friendView.innerHTML = html;

    if (totalFriends < 0) {

        totalFriends = response.get('fetchPeople').getData().getTotalSize();

        var pageNumber = document.getElementById("pageNumber");

        var numberOfPages = document.getElementById("numberOfPages");

 

        var numPages = (totalFriends / stepSize + 0.5).toFixed();

        numberOfPages.innerHTML = numPages;

        pageNumber.options.length = numPages;

        for (var j = 1; j <= numPages; ++j) {

            pageNumber.options[j - 1].value = j;

            pageNumber.options[j - 1].text = j;

        }

    }

}

If you wanted to add other functionality, such as navigation to a friend's profile page, send a request to invite a friend, or some other feature, you just need to add extra code. But, that is a topic for a future post.  

Related posts:

  1. HAS_APP filtering You don't always want to fetch all of a person's...
  2. How to figure out Maximum OpenSocial Query Result Sizes Many social web sites, Hi5, Orkut, MySpace, and others, all...
  3. Running JavaScript on Startup in OpenSocial I recently had the opportunity to help some folks debug some...
  4. Running JavaScript on Startup in OpenSocial I recently had the opportunity to help some folks debug some...
  5. Keep Your Friends Organized: Twitter Expands Lists Beta Twitter rolled out a limited beta of its new lists...

Related posts brought to you by Yet Another Related Posts Plugin.