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!
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...
<!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>
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:
There are six functions within this page. They are:
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);
}
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);
}
}
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});
}
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});
}
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();
}
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);
}
There are several things that could be added to this page, some ideas include:
<!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>
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
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; }
