Frog Developer Platform

Getting Profile Pictures for a Group

4:09PM Mar 04th
2
*

This is a guest tutorial from Ben Dixon, Senior Technician at Queensbridge School in Birmingham. If you would like to contribute a tutorial, email fdp@frogtrade.com!

Introduction

As we rolled out the Social Networking features within Frog it became obvious that we needed a method of monitoring the pupils profile pictures. Before FDP we had to manually look at each user in the toolkit in order to see their picture, and relied on other people to report inappropriate ones to us. Using FDP we now have a single page that allows us to see multiple users profile pictures all at once. This is how we did it...

Basic HTML

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:frog="http://fdp.frogtrade.com/ns/">
<head>
<title>Social Networking Profile Pictures</title>
<meta name="author" content="ben.dixon@queensbridge.bham.sch.uk" />
<meta name="froglib" content="1.1" />
<frog:roles>
    <role name="api.users.search" />
    <role name="api.users.getinfo" />
    <role name="api.groups.getall" />
    <role name="group.view.all.members" />
    <role name="group.view.all" />
    <role name="user.view.skeleton" />
    <role name="user.image.view"/>
</frog:roles>
<script>
//<![CDATA[
////// GLOBAL VARIABLES ///////
var defaultImageSource = "../sysimages/no_profile_image.jpg";
var profilePicWidth = "128";
var profilePicHeight = "128";
//////                  ///////
var groupId;
//]]>
</script>
</head>
<body>
<div class="main">
    <div class="ClassList"></div>
    <div class="Submit">
        <a href="#" onclick="widget.loadPictures();">Go!</a>
    </div>
</div>
<div class="Pictures"></div>
</body>
</html>

Styling the Page & Global Variables

I used the following css styling to organise the layout and appearance of the page. You can change this to whatever you like although I suggest you start with this and adapt it once you’ve completed this tutorial.

<style>
.ClassList {
   float:left;
   width: 190px;
   height: 50px;
}
.Submit{
    float:left;
    width: 50px;
}
.Pictures{
    clear:both;
}
.Pictures img {
    border: 0px;
    padding: 1px;
}
.main .Submit a {
    color: white;
    font: arial;
    font-size: 10pt;
}
</style>

There are also three global variables that are used:

  1. defaultImageSource This is the “blue head” default image that is shown if no profile picture has been set for a user. The location of this might be different in your Frog so this will need to be changed to suit you.
  2. profilePicWidth The width of the profile picture on the page. Users can choose to set their profile picture to a much larger size so this makes them all a sensible size. You can change this to suit your liking
  3. profilePicHeight The height of the profile picture on the page. Users can choose to set their profile picture to a much larger size so this makes them all a sensible size. You can change this to suit your liking

The Functions

There are six functions within this page. They are:

  1. displayGroups this displays the dropdown box containing all of the groups.
  2. displayUsers this adds the profile pictures to the page
  3. displayGroupList this contains the API call to get the groups
  4. displayUsersPictures this makes the API call to get the members of the specified group
  5. loadPictures this gets called when the user selects a group to view.
  6. handleError this handles any errors with the API calls

displayGroups

This function first gets the “ClassList” element on the page (the empty ‘div’ we created in our basic page). It extends this so that we can use the FDP to more easily perform actions on it. We then create a ‘form’ and add a ‘select’ element inside that. This creates the dropdown box.

We now need to populate it with options. The for loop loops through every object within “data” (the array of groups passed into the function), creates an ‘option’ element and sets the name to the group name, and the value to the groupId. There are some ‘dummy’ groups (Temp Group) within the array so these are ignored. This is then added to the select element, and it moves onto the next object. Once the for loop has finished the form is then added to the page.

widget.displayGroups = function(data){
    var groupList = widget.body.getElementsByClassName('ClassList')[0];
    UWA.extendElement(groupList);   
    var t_form = widget.createElement("form");
    var t_select = t_form.appendChild(widget.createElement("select"));
    for (var i=0;i<data.length;i++) {
      // Strip out *Temp Group* from the list. These are dummy groups from mis import for form groups.
      if (data[i].name != "*Temp Group*"){
          var o = widget.createElement('option').setText(data[i].name);
          o.setAttribute("value", data[i].id);
          t_select.appendChild(o);
      }
    }
    groupList.appendChild(t_form);
}

displayUsers

This function first gets the ‘Pictures’ element on the page (the other empty ‘div’ we created on the basic page), and extends it into FDP. It empties the element so that we start with no pictures. The for loop loops through the data (the array of users that are in the chosen group) and creates an img element for each one. The source (src) of the image is set to their profile picture or the defaultImageSource if no profile picture has been set. The users username is added to the alt tag which is displayed when you hover over the users picture. The images height and width are set using the profilePicWidth and profilePicHeight variables. The image is then added to the ‘Pictures’ element.

widget.displayUsers = function(data){
    var userPics = widget.body.getElementsByClassName('Pictures')[0];
    UWA.extendElement(userPics);
    userPics.empty();    
    for (var i=0;i<data.length;i++) {
        var image = widget.createElement('img');
        if (data[i].image == null){
            // If no profile image then show the default profile image
            image.setAttribute("src", defaultImageSource);
        }
        else {
            image.setAttribute("src", data[i].image);
        }

        image.setAttribute("alt", data[i].username);
        image.setAttribute("width", profilePicWidth);
        image.setAttribute("height", profilePicHeight);
        userPics.appendChild(image);
    }
}

displayGroupList

Uses “Frog.API.get” to get all the groups that are available in Frog. If it successfully gets these it calls the displayGroups function.

widget.displayGroupList = function(){
    var _displayGroups = function(data){
        widget.displayGroups(data);
    }
    var _handleError = function(err){
        widget.handleError(err);
    }
    Frog.API.get('groups.getAll',{onSuccess: _displayGroups,onError: _handleError});
}

displayUserPictures

Uses “Frog.API.get” to search for users who have a groupid matching the one selected in the dropdown list. If successful it calls the displayUsers function.

widget.displayUserPictures = function(){
    var _handleError = function(err){
        widget.handleError(err);
    }
    var _displayUsers = function(data){
        widget.displayUsers(data);
    }
    Frog.API.get("users.search", {"params": {"group": groupId, "details": "image", "limit": 100}, "onSuccess": _displayUsers, "onError": _handleError});
}

loadPictures

Gets the value selected in the dropdown box, then the associated groupId. It then calls the displayUserPictures function.

widget.loadPictures = function(){
    var choice = widget.body.getElementsByTagName('select')[0];
    var selected = widget.body.getElementsByTagName('option')[choice.selectedIndex];
    groupId = selected.value;
    widget.displayUserPictures();
}

handleError

Simply outputs a message that an error occurred. It also logs the error message in the widget.log

widget.handleError = function(err){
    widget.setBody('<p>Sorry, an error occurred.</p>');
    widget.log(err.message);
}

Extensions

There are several things that could be added to this page, some ideas include:

  • The current status of each user could be displayed along with their picture.
  • You could display the username underneath their picture rather than only when hovering over it.

Full Code

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:frog="http://fdp.frogtrade.com/ns/">
<head>
<title>Social Networking Profile Pictures</title>
<meta name="author" content="ben.dixon@queensbridge.bham.sch.uk" />
<meta name="froglib" content="1.1" />
<frog:roles>
    <role name="api.users.search" />
    <role name="api.users.getinfo" />
    <role name="api.groups.getall" />
    <role name="group.view.all.members" />
    <role name="group.view.all" />
    <role name="user.view.skeleton" />
    <role name="user.image.view"/>    
</frog:roles>
<script>
//<![CDATA[
////// GLOBAL VARIABLES ///////
var defaultImageSource = "../sysimages/no_profile_image.jpg";
var profilePicWidth = "128";
var profilePicHeight = "128";
//////                  ///////
var groupId;

widget.onLoad = function() {
    widget.displayGroupList();
}

widget.loadPictures = function(){
    var choice = widget.body.getElementsByTagName('select')[0];
    var selected = widget.body.getElementsByTagName('option')[choice.selectedIndex];
    groupId = selected.value;
    widget.displayUserPictures();
}

widget.displayGroups = function(data){
    var groupList = widget.body.getElementsByClassName('ClassList')[0];
    UWA.extendElement(groupList);   
    var t_form = widget.createElement("form");
    var t_select = t_form.appendChild(widget.createElement("select"));
    for (var i=0;i<data.length;i++) {
      // Strip out *Temp Group* from the list. These are dummy groups from mis import for form groups.
      if (data[i].name != "*Temp Group*"){
          var o = widget.createElement('option').setText(data[i].name);
          o.setAttribute("value", data[i].id);
          t_select.appendChild(o);
      }
    }
    groupList.appendChild(t_form);
}

widget.displayUsers = function(data){
    var userPics = widget.body.getElementsByClassName('Pictures')[0];
    UWA.extendElement(userPics);
    userPics.empty();    
    for (var i=0;i<data.length;i++) {
        var image = widget.createElement('img');
        if (data[i].image == null){
            // If no profile image then show the default profile image
            image.setAttribute("src", defaultImageSource);
        }
        else {
            image.setAttribute("src", data[i].image);
        }

        image.setAttribute("alt", data[i].username);
        image.setAttribute("width", profilePicWidth);
        image.setAttribute("height", profilePicHeight);
        userPics.appendChild(image);
    }
}

widget.handleError = function(err){
    widget.setBody('<p>Sorry, an error occurred.</p>');
    widget.log(err.message);
}

widget.displayUserPictures = function(){
    var _handleError = function(err){
        widget.handleError(err);
    }
    var _displayUsers = function(data){
        widget.displayUsers(data);
    }
    Frog.API.get("users.search", {"params": {"group": groupId, "details": "image", "limit": 100}, "onSuccess": _displayUsers, "onError": _handleError});
    }

widget.displayGroupList = function(){
    var _displayGroups = function(data){
        widget.displayGroups(data);
    }
    var _handleError = function(err){
        widget.handleError(err);
    }
    Frog.API.get('groups.getAll',{onSuccess: _displayGroups,onError: _handleError});
}
//]]>
</script>
<style>
.ClassList {
   float:left;
   width: 190px;
   height: 50px;
}
.Submit{
    float:left;
    width: 50px;
}
.Pictures{
    clear:both;
}
.Pictures img {
    border: 0px;
    padding: 1px;
}
.main .Submit a {
    color: white;
    font: arial;
    font-size: 10pt;
}
</style>
</head>
<body>
<div class="main">
    <div class="ClassList"></div>
    <div class="Submit">
        <a href="#" onclick="widget.loadPictures();">Go!</a>
    </div>
</div>
<div class="Pictures"></div>
</body>
</html>
Why when I run this code do I only get a drop down box with user groups in it? - Stuart

2 Comments

9:56AM Nov 01st
0

Hi,

whilst i understand the basics of this tutorial I am a novice developer trying to make a couple of slight adjustments but failing.

Is it possible to display just the groups for the current user i.e teacher instead of the the list of all groups?

Also instead of putting the name as an ALT tag can the full name be placed underneath each picture?

I am thinking of releasing this for our parents evening to help teachers recognise their pupils easier.

Thanks,

Jon

Hi John, It's possible to get the classes for a teacher using the timetable API, timetables.getClasses will list the classes for a student or teacher. To get the current user's ID, you can use UWA.Environment.user.id and pass that in to the timetable.getClasses API. If you need an example please let us know! - Damien McMahon
Hi Damien, i would appreciate an example if possible in this tutorial. Thanks - Jon Duffy
10:53AM May 22nd
0

Great Tutorial Ben, Thanks! Stuart - the GO button is in white so you just cant see it, easiest way is to change the color of the frog page from white or change the color in the styles from white

.main .Submit a { color: white; font: arial; font-size: 10pt; }

Ask a Question
Widget code generator
Watch our FDP Screencasts
Download our FDP Cheat Sheet

Badges

We've introduced badges to the FDP, get involved to open up more badges.

  • gold cup badge 500+ points
  • silver cup badge101-499 points
  • red rosette badge51-100 points
  • green rosette badge6-50 points
  • blue rosette badge0-5 points

FDP Support

This site should become your first port of call for all things FDP. If you have feedback or would like to see additional services on this site please contact us on fdp@frogtrade.com

a Frog site