Drupal Block for Google Plus Activities with jQuery

social networks

In a previous article we talked about how to build a Drupal block for Google Plus activities (I encourage you to take a look at it before continuing). This time we shall be making an enhanced version of the same block by using jQuery. The goal will be to build a Drupal block for displaying a fixed number of Google Plus activities and give the user the ability to show more activities by clicking a button without refreshing the entire page. It is the same way as Youtube allows visitors to show more videos. In other words, we are going to paginate the activities with AJAX by using jQuery. You can see how it works on the home page of this site.

The block for Google Plus activities that you can find now on the home page of this site does not use the technique this article covers to retrieve the user's activities.

In order to carry out this new project we need the Google Plus library for PHP; the jQuery library (it comes along with Drupal); a javascript library called rfc3339date.js for parsing the dates (JavaScript is not able to parse this date format by default); and a Drupal block containing the following code:

<div id="activities">
</div>
<button id="more" value="" class="more-button">Show more</button>

The application is made up of the following components:

  • activities.php
  • activities.js
  • rfc3339date.js

activities.php

This is the main component of the application. It is responsible for retrieving the Google Plus activities and encoding them in JSON format. We are going to save this script along with the Google Plus library for PHP in a subfolder of the current theme. The code for activities.php is the following:

<?php
/**
 * First of all we put apiClient.php and apiPlusService.php
 * into the script. This allows Google to be able to identify our app
 * and lets us use the methods for listing the activities.
 */

require_once('google-api-php-client/src/apiClient.php');

require_once('google-api-php-client/src/contrib/apiPlusService.php');

// We create a client object and store it by using a variable.

$client = new apiClient();

// We set the name for the application and our developer key.

$client->setApplicationName('enter here the name for your application');

$client->setDeveloperKey('enter here your developer key');

// We create the object that allows us to use the methods for
// listing the activities.

$plus = new apiPlusService($client);

/**
 * We set the maximum number of activities to be displayed and
 * the continuation token to page through large result sets.
 * Provide this value in a subsequent request to return the next
 * page of results.
 */

if ($_GET['token'] && $_GET['token'] != '') {

  $optParams = array('maxResults' => 5, 'pageToken' => $_GET['token']);

} else {

  $optParams = array('maxResults' => 5);

}

/**
 * Now we pass listActivities our client id, the type of posts to
 * be retrieved as well as the array named optParams. Next, we store the output by
 * using a variable.
 */

$activities = $plus->activities->listActivities('enter here your client id',
 'public', $optParams);

// Finally, if the variable named activities is set, we encode
// its content in JSON format and print it.
if (isset($activities)) {

  print json_encode($activities);

}
?>

activities.js

This is the Javascript code to be inserted in the <head> tag. It is responsible for populating the Drupal block with the first set of activities and get the next set of activities in a subsequent request every time a button with an appropriate class is clicked:

jQuery.(document).ready(function() {

  var url_activities = '/path/to/myscript.php';

  // To be used in a next article.
  var $ajax_loader = jQuery('#ajax-loader');

  var $button_more = jQuery('#more');

  var $activities_wrapper = jQuery('#activities');

  var my_activities = '';
 
  /**
   * The first time the application assigns the appropriate value
   * to the button's value attribute to return the next page of
   * results and displays the first set of activities.
   * In addition, an alert message is displayed if there is an error.
   */
  
  jQuery.ajax({

    url: url_activities,

    dataType: 'json',

    // If success, a set of activities is returned in JSON format.
  
    success: function(data) {

      // We assign the value to the button for the subsequent request.
   
      $button_more.val(data.nextPageToken);

      // We iterate through the data and build the HTML structure
      // to display the activities.
   
      jQuery.each(data.items, function(i, item) {

        var d = Date.parseRFC3339(item.published);

        var published = new Date(d);

        my_activities += '<div class="activity">
        <span class="activity-date">' + published.toDateString()
        + '</span><p>' + item.object.content + '</p></div>\n';

      }) // End of jQuery.each().

      // We append the first set of activities. In addition, we store
      // an empty string in my_activities for later use. 

      $activities_wrapper.append(my_activities);

      my_activities = '';
   
      // The button is hidden by default. We show it for being used by
      // the visitor.

      $button_more.show();

    },

    error: function() {

      alert('Failed to connect to Google Plus. Please try later.');

    },

  }); // End of jQuery.ajax().

  // Every time we click a button with an ID of more.

  $button_more.click(function() {

    jQuery.ajax({

      url: url_activities,

      type: 'get',

      // We pass the script the value of the button's value attribute.
  
      data: { token: $button_more.val() },

      dataType: 'json',

      success: function(data) {

        // If there are activities, we assign the nextPageToken's
        // value to the button.
    
        if (data.nextPageToken) {

          $button_more.val(data.nextPageToken);

        // Otherwise, there are no more activities and we must hide
        // the button. 
    
        } else {

          $button_more.hide();

        }

        jQuery.each(data.items, function(i, item) {

          var d = Date.parseRFC3339(item.published);

          var published = new Date(d);

          my_activities += '<div class="activity">
          <span class="activity-date">' + published.toDateString() +
          '</span><p>' + item.object.content + '</p></div>\n';

        }); // End of jQuery.each().

        // We check to see if there is a set of activities to be displayed. 

        if (my_activities != '') {

          $activities_wrapper.append(my_activities);

        }

        // Again, we store an empty string in my_activities
        // for later use. 

        my_activities = '';

      },

      error: function() {

        alert('Failed to connect to Google Plus. Please try later.');

      },

    }); // End of jQuery.ajax().

  }); // End of $button_more.click().

});

rfc3339date.js

Since JavaScript is not able to parse the date format used by Google Plus, we need a library to do that. Do not forget to add this library before activities.js. If you don't know how to add a javascript library to Drupal 7, please click here.

This little application assumes that the PHP script will return one Google Plus activity as a minimum. If you are not sure about it, then you should instruct activities.js to show a warning message if the user does not have any activity.

This is really easy to achieve. The first time we load the page, activities.js should check if data.nextPageToken exists by using an IF loop. If it does not exist, then the user does not have any activity and the script should display a message indicating that there are no activities to be displayed. In addition, the button should remain hidden to prevent the user from showing a nonexistent thing.