Publishers of technology books, eBooks, and videos for creative people

Home > Articles > Design > Voices That Matter

Web Design Reference Guide

Hosted by

Toggle Open Guide Table of ContentsGuide Contents

Close Table of ContentsGuide Contents

Close Table of Contents

Designing With Code: Collaboration

Last updated Oct 17, 2003.

By Kris Hadlock

Have you read my friend Robert Hoekman’s new column that he’s writing for the Web Design Reference Guide? His Designing the Obvious Clinics focus on how specific Web applications measure up to the principles discussed in his new book, Designing the Obvious: A Common Sense Approach to Web Application Design. While Robert’s columns focus on how well a Web application meets his design standards, my columns will focus on how to implement a specific feature in those applications.

Robert’s latest column takes a look at Google Docs & Spreadsheets. In this companion piece to his article, I’ll show you how to integrate PHP and MySQL with Ajax to create a collaboration system that could be used as the core upon which to create a more advanced application—like Google Docs. This core system would be easily customizable on both the back and the front-end. Make sure you download the source code from my website, as some Ajax basics have been left out of this tutorial.

Creating Collaboration

The core of designing a collaborative system is a model that I call the Data-Reflection Model. This model reflects data from the database on a continual basis if it has been updated, which allows for collaboration from multiple browser instances. We'll get started by creating the database table that will store the collaboration data.

Creating the Database Table (informit_ajaxpatterns.sql)

CREATE TABLE ´informit_ajaxpatterns´ (
 ´date´ datetime NOT NULL default ’0000-00-00 00:00:00’,
 ´description´ longtext NOT NULL,
 ´title´ varchar(33) NOT NULL default ’’,
 ´id´ int(11) NOT NULL auto_increment,
 PRIMARY KEY (´id´)
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

On the front end, we’ll import a JavaScript object called Ajax into our index, to make our requests.

<script type="text/javascript" src="js/Ajax.js"></script>

Although I won’t go into the basics of how to create the Ajax request, I will discuss one specific method. This method is called dataReflection, which will create a recursive model calling any method that we pass it at a specified time delay.

Reflecting Data Through Recursion (Ajax.js)

this.dataReflection = function(_delay, _callbackMethod)
{
  setTimeout(_callbackMethod, _delay);
}

We'll use this method to create a recursive request model that checks for new updated data in the database. First, create a JavaScript object called Collaborator.

Collaborator = new Object();

Import it into the index.

<script type="text/javascript" src="js/Collaborator.js"></script>

Next, create the following methods in the Collaborator object: initialize, onResponse, save, and get. In the onload event of the body tag, call the initialize method.

<body onload="javascript:Collaborator.initialize();">

This method will set all of the variables, make a request to a PHP file through the Ajax object, and set a callback method for the response called Collaborator.onResponse. The onResponse method will receive the response, parse the XML, and populate the index with the latest data. The Collaborator’s initialize method will also call the get method, which will start the data reflection process.

Initializing the Collaborator Object (Collaborator.js)

Collaborator.initialize = function()
{
  Collaborator.ajax = new Ajax();
  Collaborator.ajax.makeRequest(’POST’, ’serviceConnector.php?method=get’, Collaborator.onResponse);
  
  Collaborator.get();
  Collaborator.date = null;
}

Making Requests and Reflecting Database Data (Collaborator.js)

Collaborator.get = function()
{
  Collaborator.ajax.makeRequest(’GET’, ’serviceConnector.php?method=get’, Collaborator.onResponse);
  Collaborator.ajax.dataReflection(1000, Collaborator.get);
}

Now that we have a way to update data in the index, we need a way to save new data, so we’ll create a form to enter and display new data.

<input id=’username’ style="width: 100%;"><br/>
  <textarea id=’description’ wrap=’virtual’ style="width: 100%; height: 200px;"></textarea><br/>

  <div id="date"></div>
  <input type=’button’ name=’submit’ value=’save’ onclick="javascript:Collaborator.save();">

This form displays data that is retrieved via the get method and saves data through a method called save.

Saving New Data (Collaborator.js)

Collaborator.save = function()
{
  var username = document.getElementById("username").value;
  var description = document.getElementById("description").value;
  Collaborator.ajax.makeRequest(’POST’, "serviceConnector.php?method=save&id="+ Collaborator.id +"&title="+ username +"&description="+ description, Collaborator.onResponse);
}

Now that we have the front-end programming completed, let's take a look at how to connect to the database.

Bridging The Gap Between The Front-End And The Back-End

The PHP file that we’re requesting is called serviceConnector.php. This file will bridge the gap between the front-end Ajax object and the server-side PHP object.

Bridging the Gap Between Ajax and MySQL (serviceConnector.php)

<?
  require_once("classes/Collaborator.class.php");
  $collaborator = new Collaborator();
  $collaborator->$_GET[’method’]($id, $title, $description);
?>

Connecting To The Server And Returning XML

The Collaborator PHP class is where we connect to the database table that we created and return a dynamic XML file. The constructor function includes a file called mysql_connect, which makes the initial connection to the database and sets some global variables for later use. The constructor function also sets a local class variable called table, which is the name of the database table that we created up front.

Constructing the Collaborator Object (Collaborator.class.php)

var $table

public function Collaborator()
{
  require_once(’...path_to_file/mysql_connect.php’);
  $this->table = "informit_ajaxpatterns";
}

Connecting to the Database (mysql_connect.php)

<?
DEFINE (’DB_USER’, ’your_username’);
DEFINE (’DB_PASSWORD’, ’your_password’);
DEFINE (’DB_HOST’, ’localhost’);
DEFINE (’DB_NAME’, ’your_databasename’);

// Make the connnection and then select the database.
$dbc = @mysql_connect (DB_HOST, DB_USER, DB_PASSWORD) OR die (’Could not connect to MySQL: ’ . mysql_error() );
mysql_select_db (DB_NAME) OR die (’Could not select the database: ’ . mysql_error() );
?>

Make sure to change the variable values to values that are relevant to your server. It is also very important to move the connection file to a directory that is not accessible by a browser and make sure to change the path in the Collaborator’s constructor. The dbconnect method is our last database-related method; it will be used to define the connection to the database when we want to retrieve data.

private function dbConnect()
{
  DEFINE (’LINK’, mysql_connect (DB_HOST, DB_USER, DB_PASSWORD));
}

Once we have the database connection in place, we can start retrieving from the database. The get method will handle making the construction of an XML string based on database data and return it to the serviceConnector as valid XML.

public function get()
{
  $this->dbConnect();
  $query = "SELECT * FROM $this->table ORDER BY id";
  $result = mysql_db_query (DB_NAME, $query, LINK);
  
  $xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n";
$xml .= "<posts>\n";
  while($row = mysql_fetch_array($result))
  {
    $xml .= "<post>\n";
    $xml .= "<id>" . $row[’id’] . "</id>\n";
    $xml .= "<date>" . $row[’date’] . "</date>\n";
    $xml .= "<title><![CDATA[" . $row[’title’] . "]]></title>\n";
    $xml .= "<description><![CDATA[" . $row[’description’] . "]]></description>\n";
    $xml .= "</post>\n";
  }
  $xml .= "</posts>";
  mysql_close();
  
  // Return xml to requesting file when an update is made
  header("Content-Type: application/xml; charset=UTF-8");
  echo $xml;
}

The save method will be used to store new data in the database. The data will come from the index form via the Ajax engine, which will be delivered as POST data to the serviceConnector.

public function save($id, $title, $description)
{
  $this->dbConnect();
  $query = "SELECT * FROM $this->table WHERE id=’$id’";
  $result = @mysql_query ($query);
  if (mysql_num_rows($result) > 0)
  {
    $query = "UPDATE $this->table SET title=’$title’, description=’$description’, date=NOW() WHERE id=’$id’";
    $result = @mysql_query($query);
  }
  else
  {
    $query = "INSERT INTO $this->table (title, description, date) VALUES (’$title’, ’$description’, NOW())";
    $result = @mysql_query($query);
  }
  mysql_close();
  $this->get();
}

More Information

Now our application has the ability to save and display up-to-date information. This creates a process that allows multiple users to use the same application and see data reflected from all ends. The next step would be creating a system that allows users and saves multiple records. There are many additions that can be made to this code to bring it to a level that is equivalent to Google Docs, but hopefully this will provide you with the core logic to create your own collaborative application.