script.aculo.us Tutorial

The folks over at Tutorials Point have posted a good tutorial for learning script.aculo.us on their site. The tutorial does well to cover the framework, includes lots of codes examples, and even has a W3C Schools style "try-it-yourself" editor to let you play with the demos. Get started with the tutorial by accessing the sections below:

  1. Short Overview: Gives a brief overview of script.aculo.us.
  2. Major Modules : List out all the modules supported by script.aculo.us.
  3. Visual Effects : Gives complete understanding on creation of visual effects using script.aculo.us.
  4. Drag & Drop: Explains Drag and Drop functionality in detail.
  5. Sorting Elements: Learn how to sort various elements using drag and drop functionality.
  6. Create Sliders: Yes, you can provide a multi purpose slider at your web site
  7. Auto Completion: Explains how to implement Auto Completion
  8. In Place Editing: Click and update in place using script.aculo.us.

If you step through the tutorial, let us know what you think, and if you know of any other good tutorials you'd like to share, send them our way!

jQuery UI 1.5 Beta Released

Tagged:  

The jQuery team has announced the first beta release of their new upcoming UI library - jQuery UI 1.5. This is a complete overhaul of the library, so you can expect to see some big changes. Here are some mentioned in the release notes:

  • A Unified API

    The API has been updated for all UI components. It should now be very easy to use other plugins if you’re familiar with one of them. There is only one exposed method for every plugin - All other methods are called by passing in a String into the exposed method, the initialization of the plugin works by giving on a options hash as first argument. You can now change and get all options at a later point if you want to by using the new data method. Basic example for draggables:


    $(..).draggable({...}); //Initialize the draggable
    $(..).draggable("disable"); //Disable the draggable
    $(..).data("cursor.draggable", "move") //Change the cursor during drag to 'move'

  • Updated Docs
  • Drag & Drop

    Draggables and Droppables have been completely refactored. It might now be the most non-destructive drag & drop implementation ever: The css position’s value will not be changed except for ’static’: That means that elements, that were static or relative, will not be forced into absolute positioning, which often destroyed layouts, especially when dealing with floats.

  • Sliders

    The slider wasn’t refactored, but has been completely rewritten from scratch. While it’s still almost backwards compatible, it’s now very stable and simpler than ever: The moveTo method now only takes two arguments: The value you want to move the handle to and optionally the index of the handle you want to move. Want to retrieve a specific handle value? No problem, just call $(..).slider(”value”, index) .

    Even better, the slider now is completely keyboard accessible: You can now tab and focus each slider handle separately and move its position using the left/right keys. We also improved support for using the mouse: Clicking into a empty area now moves the focused handle to the clicked position, regardless on how many handles you have.

  • Sortables

    Rewritten as well, the sortables now support a wide range of features you already know from draggables: cursor, zIndex, revert, opacity, axis, handles, containment and scrolling. Additional to that, you can now serialize your items to a url hash, and you now have the often requested ability to connect multiple sortables, so you can drag a node from one sortable to another.

  • and more...

Check out the docs and cool demos below:

Mouse Interactions:

Reusable Widgets:

Visit the jQuery Blog to read about this release and download the beta.

Firefox 3 Beta 3 Released

Tagged:  

Today, Mozilla released Beta 3 for Firefox 3. This is a developer preview release and is available for testing purposes only.

From Mozilla:

These beta releases are targeted to Web developers and our testing community to gain feedback before advancing to the next stage in the release process. The final version of Firefox 3 will be released when we qualify the product as fully ready for our users. Users of the latest released version of Firefox should not expect their add-ons to work properly with this beta.
...
Firefox 3 Beta 3 includes approximately 1300 individual changes from the previous beta, including fixes for stability, performance, memory usage, platform enhancements and user interface improvements. Many of these improvements were based on community feedback from the previous beta.

Check out the extensive list of features and enhancements found in Firefox 3 Beta 3, the known issues, and frequently asked questions.

Read the full release notes for Firefox 3 Beta 3

Download it here

Simple AJAX chat in PHP

Tagged:  

Over at the .NET Butchering (and JAVA messes) blog they have posted a very good tutorial on creating a Chat application in PHP using Ajax. In Web 2.0 social applications chat is very often a desired feature.

Below is an excerpt from the tutorial.

The first thing to be done is creating MySQL tables:



CREATE TABLE `db_name`.`chat_rooms` (

`id` int(10) unsigned NOT NULL auto_increment,

`name` varchar(45) NOT NULL,

`description` text NOT NULL,

`table_name` varchar(45) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;



CREATE TABLE `db_name`.`roomX` (

`id` int(10) unsigned NOT NULL auto_increment,

`date` datetime NOT NULL,

`message` text NOT NULL,

`user` varchar(45) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1;

The first table, chat_rooms, contains a list of all available chat rooms, used to know wich table name will be used for each room. The second one, roomX is a template for a "chat room-like" table: it contains the date (date+time) of each message, the message itself and the user that inputed it (actually it should be an integer, that refers to an appropriate users table, but this is simple version of the script without logging features).

The first thing we're gonna do is execute those SQL scripts (we will be using MySQL and PHP native methods) replacing "roomX" with i.e. "friends_table", and after that we're going to populate the first table, to add an available chat room:



INSERT INTO chat_rooms(name,description,table_name)

VALUES("Friends chat","Comment...","friends_table");

The next step is to compose the "web application". Let's see this picture:

We will use a main page, chat.php, a dinamically reloaded page, room.php and a simple iframe with inside the page sender.php with some controls to post a message.

Let's see chat.php, removing all HTML stuff (like header and formatting, that's up to you):



<?php

session_start();

/* probabily login stuff */

$_SESSION['chat_time'] = $date;

?>

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

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

<script language="javascript">

var chatRoomId=<?=$charRoomChoosen?>;

</script>

<body onload="InitializeTimer(); StartTheTimer();">

<div id="chatText" style="overflow:auto;"></div>

<iframe src="sender.php" name="msgFrame"></iframe>

</body>

We'll talk further about the session variable chat_time; I've added 2 javascript scripts: the first one is a simple timer, the second one contains some methods to make HTTP requests.
This is httpRequest.js:



var xmlHttp;



function loadURL()

{

xmlHttp=GetXmlHttpObject()

if (xmlHttp==null)

{

alert ("Browser does not support HTTP Request")

return

}

var url="room.php?chatRoomId="+charRoomId;

xmlHttp.onreadystatechange=stateChanged;

xmlHttp.open("GET",url,true);

xmlHttp.send(null)

}



function stateChanged()

{

if (xmlHttp.readyState==4 xmlHttp.readyState=="complete")

{

/* trim message */

var newlines = xmlHttp.responseText.replace(/^\s+\s+$/g,"");

if(newlines!='')

{

var html = document.getElementById("chatText").innerHTML;

document.getElementById("chatText").innerHTML = html + newlines;

document.getElementById("chatText").scrollTop=20000000;

}



}

}



function GetXmlHttpObject()

{

var xmlHttp=null;

try

{

// Firefox, Opera 8.0+, Safari

xmlHttp=new XMLHttpRequest();

}

catch (e)

{

//Internet Explorer

try

{xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");}

catch (e){xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");}

}

return xmlHttp;

}

This class does an HTTP request (using Firefox, Explorer and other browser Request objects), as I explained in the [Javascript]XML Loading post, and writes the result inside the DIV with id chatText, calling the room.php script (that actually outputs last message sent to the room). The charRoomId used as a parameter of the calling method, is a global variable defined in the chat.php header using a PHP variabile (it should be a $_REQUEST variable).

As we are using asyncronous calls, we need a component that recalls this request periodically. This is the code below (timer.js):



var secs;

var timerID = null;

var timerRunning = false;

var delay = 500;



function InitializeTimer()

{

// Set the length of the timer, in seconds

secs = 1;

StopTheClock();

StartTheTimer();

}



function StopTheClock()

{

if(timerRunning)

clearTimeout(timerID);

timerRunning = false;

}



function StartTheTimer()

{

if (secs==0)

{

StopTheClock();

// Here's where you put something useful that's

// supposed to happen after the allotted time.

// For example, you could display a message:

loadURL();

secs = 1;

timerRunning = true;

timerID = self.setTimeout("StartTheTimer()", delay);

}

else

{

self.status = secs;

secs = secs - 1;

timerRunning = true;

timerID = self.setTimeout("StartTheTimer()", delay);

}

}

This is a timer, called from the chat.php page with onLoad method, that recalls each delay milliseconds the function loadURL() function, defined inside the previous js file.

Now let's see what is inside the chat.php file:



<?php



/* **************** SESSION VARIABLES **************************** */

session_start();



if(!isset($_SESSION['chat_time']))

{

$_SESSION['chat_time'] = date("Y-m-d H:i:s");

$_SESSION['chat_time_delete'] = time();

}





/************** DB connection ********************+*/

$db_user = "root";

$db_password = "root1";

$db_host ="localhost";

$connection = mysql_connect($db_host,$db_user,$db_password);

mysql_select_db("test",$connection);



/********** RETRIEVES THE NAME OF THE CHAT ROOM TABLE NAME **********/

function getChatTableName($connection,$chatRoomId)

{

/* recupera il nome della tabella della chat room */

$query = "SELECT table_name FROM chat_rooms WHERE id = '".$chatRoomId."'";

$result = mysql_query($query, $connection);

$tableName = NULL;

while($row=mysql_fetch_array($result))

{

$tableName = $row['table_name'];

}



if($tableName==NULL)

{

return NULL;

}



return $tableName;

}



/******************* MESSAGE VISUALIZATION ********************************/





$tableName = getChatTableName($connection,$_REQUEST['chatRoomId']);



if($tableName==NULL)

{

echo "Error selection char room.";

exit();

}

$login_date = $_SESSION['chat_time'];



/* load messages */

$query = "SELECT c.message, c.date, c.user FROM ".$tableName." c WHERE c.date > '".$login_date

."' ORDER BY c.date ASC ";

$result = mysql_query($query,$connection);



$last = "";

while($row=mysql_fetch_array($result))

{

$message = html_entity_decode($row['message']);

echo "[".$row['user']."][".$row['date']."] ".$message." <br/>";

$_SESSION['chat_time'] = $row['date'];

}



/* delete messages older that 60 seconds*/

if((time()-$_SESSION['chat_time_delete'])>60 )

{

$query = "DELETE FROM ".$tableName." WHERE (NOW()-date)>60";

mysql_query($query,$connection);

$_SESSION['chat_time_delete']=time();

}



mysql_close($connection);

?>

We can see session variables initialization: chat_time is the time in which you entered the chat room or of the last message received, while chat_time_delete is the time in which you last deleted a message.
The scripts work this way:

  • connect to the database
  • retrieve the chat room table name using the chatRoomId request variable and the getChatTableName() function
  • query the DB searching for messages not yet received (basing unpon the time of last message received, and at the end of the loop we have a new value for chat_time, that is the last received message time
  • (because) once received messages are useless (a user after connection never received messages of the past), the script delete messages older than 60 seconds

Of course you can format as you like the message board.

At the end we find the sender.php page, that is wrapped in an HTML iframe (because every submission must not cause the entire page reload):



<?php



/***************+ DB variables *****************+*/

$db_user = "root";

$db_password = "root1";

$db_host ="localhost";

$connection = mysql_connect($db_host,$db_user,$db_password);

mysql_select_db("test",$connection);



/********************* NOME TABDELLA CHAT ROOM **************************+*/

function getChatTableName($connection,$chatRoomId)

{

$query = "SELECT table_name FROM chat_rooms WHERE id = '".$chatRoomId."'";

$result = mysql_query($query, $connection);

$tableName = NULL;

while($row=mysql_fetch_array($result))

{

$tableName = $row['table_name'];

}



if($tableName==NULL)

{

return NULL;

}



return $tableName;

}





if($_POST['action']=="send")

if($_SESSION['userid']!="")

{

$tableName = getChatTableName($connection,$_REQUEST['chatRoomId']);



if($tableName==NULL)

{

echo "Error selecting chat room.";

exit();

}



$query = "INSERT INTO ".$tableName."(user,message,date) VALUES(\""

.$_POST['userid']."\",\""

.htmlentities(htmlspecialchars($_POST['message']))."\",NOW())";



mysql_query($query,$connection);



}

?>



<body onload="document.msgForm.message.focus();">



<form name="msgForm" action="sender.php" method="post">

<input type="hidden" value="send" name="action"/>

<input type="hidden" value="1" name="chatRoomId"/>

<input type="text" name="userid" value="<?=($_POST['userid']=="")?"guest":$_POST['userid']?>" size="10" />

<input type="text" name="message" style="width:400px" maxlength="1500"/>

<input type="submit" value="invia"/>

</form>

</body>



<?php

mysql_close($connection);

?>

This page simply prints out a web form (in which users insert their nick name -in this version without a check- and the message) and -consequently to the submission- insert the message in the DB, that will be outputted by the timer.js routine.

This will be your final result:

You can read the full tutorial here.

Hopefully this tutorial will be useful to you.

Cross-Window Messaging

Tagged:  

Over at John Resig's blog, he has posted an interesting article about cross-window messaging. The method is part of the HTML 5 Specifications and is available with Firefox 3.

The new method allows you to access all windows, including iFrames, Frames, Popups and the Current Window. The new call would create a DOM event, in the other window, which allows for messaging between the two windows.

Below is an excerpt from the post.

Obviously communicating in a cross-domain fashion is prone to abuse so there's additional information passed along that can be used to verify the integrity of the message. The full list of properties include:

* .data - A string holding the message passed from the other window.
* .domain - The domain name of the window that sent the message.
* .uri - The full URI for the window that sent the message.
* .source - A reference to the window object of the window that sent the message.

The last property is especially important as it allows for two-way communication to occur between these windows.

Simple Demo>

I've constructed a simple demo that you can try (requires a nightly of Firefox 3) in which you can send a message - through an iframe - to another domain, having the results be received and rendered by it. Thus, this demos consists of two pages: One acting as the sender (on ejohn.org), one acting as the receiver (on dev.jquery.com).

This first page is the sender - it's calling postMessage (sending the textual message) and also holds the iframe within which the receiving window is held.

<iframe src="http://dev.jquery.com/~john/message/" id="iframe"></iframe>
<form id="form">
  <input type="text" id="msg" value="Message to send"/>
  <input type="submit"/>
</form>
<script>
window.onload = function(){
        var win = document.getElementById("iframe").contentWindow;
        document.getElementById("form").onsubmit = function(e){
                win.postMessage( document.getElementById("msg").value );
                e.preventDefault();
        };
};
</script>

The follow page is the receiver - it has an event listener bound which watches for messages being passed to it and injects them in to the DOM.

<b>This iframe is located on dev.jquery.com</b>
<div id="test">Send me a message!</div>
<script>
document.addEventListener("message", function(e){
        document.getElementById("test").textContent =
                e.domain + " said: " + e.data;
}, false);
</script>

You can read the full post here.

This new method could make for some interesting applications. I could see your del.icio.us account sending messages back and forth from your Digg account in two different windows all on the client side. That is of course if the cross domain settings can be worked out.

Will the Web be OpenID Compatible by 2009?

Tagged:  

We all would love for all websites to be OpenID compatible. This is looking like a real possibility as more and more companies have announced their support for the standard. Big companies supporting the standard include Google, Microsoft, Yahoo and IBM.

With the support of these large companies we should start seeing more and more OpenID support this year and, if things go right, we may see the majority of big sites going to the standard by the end of 2009.

Over at profy.com they have posted a very good article about Heavy Hitters Jumping on the OpenID Bandwagon. Below is an excerpt from the post.

OpenID technology is a viable way to make handling your online identities easier and more secure. It has been slowly gaining momentum, helped recently by beleaguered company Yahoo's adoption of an OpenID style log in for its many web properties. OpenID got another boost recently when a slew of heavy hitters finally decided to jump on the OpenID bandwagon.

In addition to Yahoo, the OpenID Foundation's board can now count Microsoft, Google, IBM and VerisSign among its board members and supporters. That's fantastic news for the web user like myself who is confounded by far too many log in identities and passwords. OpenID simplifies the task of not only remembering your log in for a site, but for keeping the log in(s) secure as well.

You can read the full post here.

I personally can't wait to see OpenID implemented on more major sites (I'm still waiting for Digg to add support). Since we at Ajaxonomy think that OpenID is a very important thing we have included it in our open blogging and commenting systems. So, hopefully by 2009 everyone will be using OpenID!

Hack the Day Away with Google

Tagged:  

If you are in the Mountain View area you can attend a "Hackathon" with Google on Friday, February 29th from 2pm - 10pm (there are two sessions one from
2pm - 5:30pm and another from 6pm - 10pm). This "Hackathon" is centered around Ajax development and is a great time to learn the below API's from the experts.

Google Gears [http://code.google.com/apis/gears/]
Google AJAX Search/Feeds [http://code.google.com/apis/ajaxsearch/]
Google Gadgets [http://code.google.com/apis/gadgets/]
Google Maps [http://code.google.com/apis/maps/index.html]

There will be a quick over view of the API's before the "Hackathon" starts. A few other things that all of we developers like is that there will be free food, prizes and schwag! Also, make sure to bring your laptop as laptops will not be provided.

You can read more about the event here.

To RSVP your spot click here.

jQuery 1.2.3 Released

Tagged:  

This is primarily a bug fix release for jQuery 1.2. Check out the bug tracker to see what was fixed.

This release is now compatible with Adobe AIR, and will be included in Drupal 6, and will be the base for jQuery UI 1.5. A couple minor features, for plugin developers, were included in this release.

Check out the release notes for new features and important additions included in this version and for more information about the alpha release of jQuery UI 1.5 and jQuery Enchant 1.0.

Download jQuery 1.2.3:

Yahoo! Live and It's API

Tagged:  

Amidst all the news swirling around about a hostile Yahoo! takeover, and the battle of the titans (Microsoft & Google), Yahoo! has released a new service - Yahoo! Live - a personal live streaming video service. [read more about Yahoo! Live at their blog]

Yahoo released an API [a set of Web Services and a couple of embeddable Flash objects] along with this new service. With this API, you can:

  • Find out who's broadcasting right now
  • Get data about past broadcasts
  • See snapshots of past broadcasts
  • Embed live video in your blog or web page

Do keep in mind that the service is currently in limited beta and is not always available.
You may get a message stating "Whoa! Yahoo! Live is an experimental release - we can tell you like the experiment! We're tuning now. Refresh, wait a few seconds, or click here to try again."

Read more about the Yahoo! Live API at the Yahoo! Developer Network and be sure to check out the Yahoo! Live Randomizer demo using REST/JavaScript.

Accessing JSON Web Services with the Google Web Toolkit

Over at GWT Site they have written a good post about using the Google Web Toolkit with JSON Web Services. Since JSON is fast becoming a standard for web services that are cross domain and GWT is a heavily used development tool this is a useful post.

below is an excerpt from the post.

The main difficulty when trying to talk to some web service on another server is getting past your web browser’s Same-Origin Policy. This basically says that you may only make calls to the same domain as the page you are on. This is good for security reasons, but inconvenient for you as a developer as it eliminates the use of GWT’s HTTP library functions to achieve what we want to do. One way to get around this is to call a web service through a javascript <script> tag which bypasses this problem. In his book, Google Web Toolkit Applications, Ryan Dewsbury actually explains this technique in more detail and provides a class called JSONRequest which handles all the hard work for us. JSON is one of the more popular data formats, so most web services support it. Lets leverage Ryan’s code and take a quick look at how it works.

public class JSONRequest {
  public static void get(String url, JSONRequestHandler handler) {
    String callbackName = "JSONCallback"+handler.hashCode();
    get( url+callbackName, callbackName, handler );
  }	
  public static void get(String url, String callbackName, JSONRequestHandler handler ) {
    createCallbackFunction( handler, callbackName );
    addScript(url);
  }
  public static native void addScript(String url) /*-{
    var scr = document.createElement("script");
    scr.setAttribute("language", "JavaScript");
    scr.setAttribute("src", url);
    document.getElementsByTagName("body")[0].appendChild(scr);
  }-*/;
  private native static void createCallbackFunction( JSONRequestHandler obj, String callbackName)/*-{
    tmpcallback = function(j) {
      obj.@com.gwtsite.client.util.JSONRequestHandler::onRequestComplete(Lcom/google/gwt/core/client/JavaScriptObject;)(j);
    };
    eval( "window." + callbackName + "=tmpcallback" );
  }-*/;
}

To make our request we call the get method with the web service url, and an implementation of the JSONRequestHandler interface. This interface has one method called onRequestComplete(String json). This is where you’ll handle the JSON formatted data once it comes back from the server. When calling a service from within a script tag, we need to specify the name of a callback function in the request. Most services let you specify the name yourself, so the first get method generates a callback name for you. The createCallback method is a JSNI method that simply calls your JSONRequestHandler implementation when the call returns via the callback name. Note, if you use this class, to make sure and change the package name for the JSONRequestHandler call to the correct location. Finally, the get method will call the addScript function which is responsible for embedding the <script> tag on your page and setting its src attribute to the web service url.

You can read the full post here.

Since I am a fan of both JSON and GWT I enjoy seeing good posts about using these two technologies. I recommend this post for any Java developer that wants to make Ajax applications using Web Services.

Syndicate content