Tutorials

How to make a Slide and Hide with Yahoo YUI

Javascript transitions are becoming more and more popular with the Web 2.0 sites. We simply couldn’t use an Ajax powered site without some sort of visual notifications, and although animation is not absolutely neccessary the sites that do use it stand out from the crowd.

There are quite a few transitions covered in the Yahoo Design Pattern Library but I’m going to show you my way of Sliding and Hiding a div. Unlike the design pattern library, I’m not going to tell you why the effect should be used, but exactly how to create it.

Before we get started, you might want to look at the finished product, so you know what the goal of this is.

Overview of the process

When I wanted tp make this transition for a page of mine, as a programmer I thought about how the div would dissapear:

  • The div would maintain size and hide beneath another div with a higher z-index or
  • The div would decrease in size, height or width depending on the orientation of the transition.

Although hiding the slider div beneath another div might have worked, what would happen if the slider moved off the visible screen area? You’d get those nasty scrollbars in the browser window…

So the second option sounded better. But (yes so many buts) what happens to the content of the div when the height/width shrinks? Yes, it moves with it. The solution for that is a small CSS property: overflow:hidden;

That’s a good start, but it’s still nto perfect. For example, when shrinking the width of a div, the content (in the case of text) would wrap as much as possible before it will overflow. It looks tacky believe me.

I’ve found that you can wrap the sliding div with another div, and set the width of the inner div, while setting overflow:hidden on the outer div. If you didn’t quite catch that, have a look at this diagram:

Slide and Hide Diagram

The outer div compresses to the dimensions specified by the transition, while the inner div overflows because the width is set.

Have a look at the source of the example for CSS and Javascript.

Technorati: yahoo, yui, javascript, css, slide, hide

How to dynamically return XML data using PHP

This is the second part of a tutorial covering the Front-end browser part of Ajax’ing and the Back-end part of sending data with PHP. The first part can be found here.

So we’ve covered how to request an interpret XML data from a webpage using Sarissa. Now we want to control what data is being returned, dynamically.

The basic principal behind setting up the script is to make the browser think it’s an XML document, not a PHP script. There are 2 ways you can do this:

  1. Add a content-type header into your script
  2. Add an apache handler to treat xml files as scripts (which still involves step 1 anyway)

So I’ll only cover the first option. On top of that, I’m going to throw you in the deep end here, and show you the entire script:

<?php
//simulate a remote connection
sleep(2);
 
//include any libraries you want to use here.
 
//get the $mode var
$mode = stripslashes($_GET['mode']);
//Set the content-type header to xml
header("Content-type: text/xml");
//echo the XML declaration
echo chr(60).chr(63).'xml version="1.0" encoding="utf-8" '.chr(63).chr(62);
?>
<xmlresponse>
  <?php
  //make a decision based on $mode
  switch ($mode) {
    case 'getitems':
      //set items in a test array
      $items_array[] = array(
        'id'=>15,
        'name'=>'Finger Bun',
        'price'=>'$0.80 ea'
      );
      $items_array[] = array(
        'id'=>16,
        'name'=>'Donuts',
        'price'=>'$0.50 ea'
      );
      $items_array[] = array(
        'id'=>17,
        'name'=>'Apple Pie',
        'price'=>'$1.20 slice'
      );
      $items_array[] = array(
        'id'=>18,
        'name'=>'Double Choc Chip Cup Cakes',
        'price'=>'$1.00 ea'
      );
 
      //echo a count of items
      echo '<item_count>'.count($items_array).'</item_count>';
      //echo the array in XML style
      for ($x=0;$x<count($items_array);$x++) {
        echo '<item>';
        echo '<id>'.htmlspecialchars($items_array[$x]['id']).'</id>';
        echo '<name>'.htmlspecialchars($items_array[$x]['name']).'</name>';
        echo '<price>'.htmlspecialchars($items_array[$x]['price']).'</price>';
        echo '</item>';
      }
 
      //set a No Error response - function defined below
      SetErrorNode();
      break;
 
    default:
      //inccorrect mode, let the hacker know!
      SetErrorNode(404,'Stop hacking. Get a real job.');
      break;
  } //end switch
  ?>
</xmlresponse><?php
 
//FUNCTIONS
//this sets the error code node - essential for every xml document to be returned.
function SetErrorNode($code=0,$text='') {
  echo "<error_code>" . $code . "</error_code>\\n<error>" . htmlspecialchars($text) . "</error>";
}
?>

Download this code: _ajax.php

Here’s an explanation. First we simulate an internet connection delay (for those using local development servers) incase you’ve got any features such as a waiting screen on the front-end that you want to admire for two seconds.

Next we get the $mode variable from the GET array (as used in part one of this tutorial) so we can decide what to do with it later. Then we send the content-type headers to the browser, so that it knows this is an XML document. Then we echo the XML declaration. You might be wondering why I’ve used chr everywhere there. This is so we don’t have to turn off php short tags just to make this thing work, a tip for all you out there.

Then we echo the root tag, xmlresponse. I’m not sure if changing this will affect Sarissa’s interpretations, but I don’t change it anyway.

The rest of the script is echo’ing data for our application to use. The only thing to mention is that any data you want to send within xml tags should be coded using htmlspecialchars. Even HTML code should be coded. Sarissa will automatically convert it back for you on the front-end.

Finally, we use the function SetErrorNode to echo our error tags as we want to.

Well that’s all I’m going to cover this time around, but I’m sure this can help a lot of begginners out there. Leave a comment if you have any questions (like how to get the front-end to recognise more than 500 characters of data within a single tag, muahaha).

Technorati: php, ajax, xml, tutorial

How to use Sarissa Ajax Library

I’ll spell it out for you. Or even better, I’ll just give you the code! This is the first part of a tutorial covering the Front-end browser part of Ajax’ing and the Back-end part of sending data with PHP. The second part can be found here.

I am only going to explain the minimums for accomplising this goal. A bigginers lesson if you want. I won’t cover more complex options as I don’t need to use them myself, yet.

The Sarissa Ajax library is my choice for Ajax’ing for a few reasons:

  • It’s small (11.8kb!)
  • Cross browser compatible and
  • Escapes the information received nicely

My tutorial will only cover XML request with Sarissa.
What you need to get started:

  • A web development server (consider Wamp if you’re using Windows)
  • Latest versions of your browser (IE 7 not required, the latest IE 6 is fine)
  • The Sarissa Library
  • Cross Browser X Library javascript functions – Optional, for DOM functions you may use.

At this point I should mention that if you’re reading this article, I assume you’re serious about writing your powerful Web 2.0 applications. If you don’t know your DOM or Javascript language very well, I suggest you take a look at this Sitepoint book. The sample chapters are free and they will help you out quite a bit. Purchase the book if you like it.

So, let’s view the major function for our javascript code, assuming you’ve linked to sarissa.js in your document:

//  getUrl
//  Will initate the http request for data.
function getUrl(url,fn) {
  if (url && fn) {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("GET", url, true);
    xmlhttp.onreadystatechange = function() {
      if (xmlhttp.readyState == 4) {
        fn(xmlhttp.responseXML);
      }
    };
    xmlhttp.send('');
  } else {
    alert('url or function not specified!');
  }
}
 
//  trim functions
//  will trim whitespace from strings
String.prototype.trim=function(){
  return this.replace(/^\\s*|\\s*$/g,'');
}
String.prototype.ltrim=function(){
  return this.replace(/^\\s*/g,'');
}
String.prototype.rtrim=function(){
  return this.replace(/\\s*$/g,'');
}
 
//  CheckResultIsOk
//  Will check the XML data you've return for <error_code>x</error_code>
//  and returns the error to the user if found.
function checkResultIsOk(xml) {
  if (!xml) {
    //xml data was empty. Result was not ok.
    return false;
  }
  if (xml.getElementsByTagName('error_code')[0].firstChild.data &&
    Math.abs(xml.getElementsByTagName('error_code')[0].firstChild.data.trim()) > 0) {
    //error has been supplied
    alert('Error ' + xml.getElementsByTagName('error_code')[0].firstChild.data + ': ' +
      xml.getElementsByTagName('error')[0].firstChild.data.trim());
    return false;
  } else {
    //no errors!
    return true;
  }
}

Download this code: sarissa_tute_1.js

The functions are very simple.

  • getUrl takes an URL, and a function name before opening a http request. The URL should point to the file on your server, from which XML data would be returned. The function name is just the name of a function you’ve already specified. This function gets called once the XML data has been returned. And you’ve probably guessed I like error checking. The alert reponse can be omitted – it’s just there for our testing purposes.
  • trim functions are a few ingenious pieces of code that will save you years of headaches. As some XML documents are formed, whitespace can occur around the data within the tags. These functions can remove this from your strings.
  • checkResultIsOk will check your XML data that you’ve returned for any specified errors. Of course, this only works if your XML document contains a valid error_code tag with an error number in the data, zero being no error. I started using this method of checking so that I could return errors with my back-end system to the user in a friendly manner. Setting an error tag with a description in your XML will also display that to the user.

Believe it or not, but that’s the hard part over. All you need to do now is create your functions to request your data, and additional callback functions to process the data. Here’s an example of a request function:

//  ajaxGetItems
//  Called from clicking a link or button on your page
function ajaxGetItems() {
  //send the request	
  var filetouse = '_ajax.php?mode=getitems';
  getUrl(filetouse,cbGetItems);
}

Download this code: sarissa_tute_2.js

Easy wasn’t it? Notice you can include GET variables in your request. So if your XML document is a dynamic script (as in part two of this tutorial) you can control some aspects of the script. Also notice that when you specify the function name for getUrl, you don’t wrap it in quotes, and you don’t add () to the end of it, otherwise the function would be executed right there at that point in the code.

So let’s assume this is the XML data that has been returned:

<?xml version="1.0" encoding="iso-8859-1"?>
<xmlresponse>
  <item_count> 4 </item_count>
  <item>
    <id> 15 </id>
    <name> Finger Bun </name>
    <price> $0.80 ea </price>
  </item>
  <item>
    <id> 16 </id>
    <name> Donuts </name>
    <price> $0.50 ea </price>
  </item>
  <item>
    <id> 17 </id>
    <name> Apple Pie </name>
    <price> $1.20 slice </price>
  </item>
  <item>
    <id> 18 </id>
    <name> Double Choc Chip Cup Cakes </name>
    <price> $1.00 ea </price>
  </item>
  <error_code> 0 </error_code>
</xmlresponse>

Download this code: sarissa_tute_1.xml

So in our document we have an item_count tag, 4 items tags with sub tags, and our error_code tag. Let’s see how our callback function would handle this:

//  cbGetItems
//  Called when the data from ajaxGetItems has been retrieved.
function cbGetItems(xml) {
  //check result is ok
  if (checkResultIsOk(xml)) {
    //get the item count
    var item_count = Math.abs(xml.getElementsByTagName('item_count')[0].firstChild.data.trim());
 
    //get the items
    var items = xml.getElementsByTagName('items');
    for (i=0;i<items.length;i++) {
    //send an alert of the data received
      alert (i + "  Data recieved:\\n" +
        "id: " + items[i].getElementsByTagName('id')[0].firstChild.data.trim() + "\\n" +
        "name: " + items[i].getElementsByTagName('name')[0].firstChild.data.trim() + "\\n" +
        "price: " + items[i].getElementsByTagName('price')[0].firstChild.data.trim() + "\\n");
    } //end i for		
  } //end check result
} //end function 

Download this code: sarissa_tute_3.js

The first things the function does is check the data for an error with the checkResultIsOk function. If it passes, we extract the data. The item_count tag isn’t being displayed to the user, I’ve only put it in there to show you how to extract a single tag (that doesn’t have an ID). Next we get all the items tags, iterate through them and display the data in alert popups. You can do whatever you like with the data I’ve used in these alerts.

So there you have half of it! Using Sarissa to retrieve XML data and do something with the data, all with cross browser functionality. Now take part two of the tutorial and learn How to dynamically return XML data using PHP

Technorati: javascript, ajax, xml, tutorial, sarissa