Archive for the 'HTML_AJAX' Category

HTML_AJAX 0.3.0 Released and new Website

Thursday, November 17th, 2005

HTML_AJAX 0.3.0 is huge leap forward from the previous versions, although it still remains mostly backward compatible with earlier releases. Currently the only change in API occurs in Main.js - some event handlers were colliding so name changes were made. The effected methods are onOpen -> Open, onLoad -> Load, onProgress -> Progress, onSend -> Send. This shouldn’t affect too much code.

One of the most important and exciting changes with HTML_AJAX 0.3.0 is the addition of three new developers who have been putting a lot of time into the project. They totally eradicated every item on the original todo list, and the feature roadmap has jumped ahead.

There are considerable improvements in the behind the scenes code. Using the new HTTP client pooling reuses XMLHttpRequest? clients, giving you a speed up when making lots of requests. This is especially useful for IE, where activex object creation can really slow things down. The new priority queue allows you to make many requests and tag the ones that are more important to be sure they are executed first. HTML_AJAX_Util received several bugfixes and new methods to make debugging javascript a little easier, including a varDump() and getType(). As the code base grows, both in javascript files and in php files, some minor rearranging has been done as well.

On the user end, there are several new serializers to use - you don’t have to be limited to just JSON, Error or NULL. Now you can use php based serialization, url encoding serialization, or HTML_AJAX_Action - which eliminates the need to write client side javascript to handle the data returned from ajax callbacks. There were several bugs fixed - most importantly was a huge bug in Opera and the way it handles unknown Content-Types - it seems to translate them to binary so a workaround was needed.

The examples directory has some great new code to show the power and flexibility that HTML_AJAX can provide in applications. There’s still a lot to do, just take a look at the roadmap, but with this release a huge amount has been accomplished.

As always were still looking for new people to help out. People willing to put time in testing and supply bug fixes for there browser of choice would be especially helpful. It doesn’t take a lot of time unless your favorite browser is horribly broken, but the through testing makes a huge quality difference.

You can upgrade your install as always using the pear installer. If your looking for a full changelog you’ll want to check out our new wiki.

The couple pages of docs I’ve had here on my blog are moving there. Were using yawiki from Paul M Jones, and aside from a couple minor points its been great to work with.

HTML_AJAX 0.2.5 released

Tuesday, November 1st, 2005

This is a minor bug fix release, the big fixes updating serverl url handling and some fixes allowing you to specify a class name with case when exporting it.

The server url handling allows you to add parameters like a session id to your url.

The case changes allow you to register a class like:

$server->registerClass($instance,’NameWithCase’);

and have it work right on php4 and php5.

The second change was made while updating the UploadProgressMeter to php5. I don’t have a tarball release of that yet, but its in svn (web) now if you want a version that doesn’t rely on JPSpan.

Introduction to HTML_AJAX slides available

Wednesday, October 26th, 2005

I gave a presentation at yesterdays azPHP Meeting.

The slides from this are now available.

Also there should be another HTML_AJAX release today fixing and annoying bug.

HTML_AJAX 0.2.3 Released

Monday, October 24th, 2005

This release is a mix of bug fixes and new features.

There shouldn’t be any reference bugs left so those of you running on php 4.4 or 5.1 should be fine now.

The only item that should cause you problems is that php 4 exports method and class names to JavaScript lowercase while php5 does it in the specified case. So if you want php4 and 5 compatability you’ll need to specify the methods to export. A lowercase all option is on the list of things to do.

Changes:
There is now a append util function on HTML_AJAX
New HTML_AJAX_Debug and HTML_AJAX_Helper classes, look at the examples to see there basic use
HTML_AJAX_Server::registerJSLibrary added to allow you to use the same server class to export you own js libs
multiple client libs can be combined into a single request server.php?client=main,httpclient,customlibname (see helper_usage.php in examples for details)

The default loading implementation has been moved to its own javascript file. If you don’t want the default implementation just don’t include this lib. The implementation has also had a half second timer added so it only shows on slower calls, so if your using it on intranets, you won’t see if for your really fast calls.

Start on a serializer built on php’s serialize call. Be aware this hasn’t had much testing and that it has security issues in older versions of php (bug in unserialize call) and may never work correctly with multibyte characters until php6, but it may be faster and like any serializer its optional.

I’m sure there was some other stuff too. Also like any OpenSource project were looking for more help, including people willing to work on docs, do core development, and auxilary classes for items like template or framework integration. Some widgets may also find there way into HTML_AJAX as optional components so if your interested in writing any let me know.

HTML_AJAX 0.2.1 Released

Friday, September 30th, 2005

I just released HTML_AJAX 0.2.1, if your running 0.2.0 you’ll want to upgrade immediatly since this fixes a bunch of bugs I added in that version.

The main changes are:
Bugs:
Remove debug message when throwing an exception
Fix problems with async calls
Fix broken content-type detection
Stop trying to run an init method when the init flag isn’t set
PHP required version moved to 4.1.0 which is what it should need

Features:
A basic debug class has been added, allowing you to write PHP errors to a file
HTML_AJAX.replace now works async

Also there is now a mailing list for HTML_AJAX.

HTML_AJAX 0.2.0 Release

Tuesday, September 27th, 2005

HTML_AJAX 0.2.0 is out. There were a number of changes most of them on the JavaScript side.

The code is now released on the lgpl so thoses of you with GPL apps should feel comfortable using it now.

I don’t have time to write another tutorial showing off the new changes but if your looking a good place to start is with the new HTML_AJAX_Request class in JavaScript. All AJAX requests happen by creating an instance of this class and then running it through HTML_AJAX.makeRequest. If your looking to integrate your own complex widget this is the place to start.

The changelog has some more information.

Also im hoping to get the PHP side fully stabilized soon so we can move to a beta. If anyone has time I would appreciate an API review, mainly on HTML_AJAX and HTML_AJAX_Server.

Finally i’d like to drop the PHP dependency to something lower then 4.3.0, if you’ve used HTML_AJAX on 4.2.x or something else let me know. Once i’ve had confirmation it works i’ll lower it.

The roadmap has also been updated

AJAX - PHP presenter in Boston

Thursday, August 25th, 2005

I was contacted by the Mark Withingon, founder of the Boston PHP Users group today, there looking for someone who could do a presentation about HTML_AJAX for them in November. Now I would love to fly there and help them out, but its not going to happen, so the best I can do try to find someone else.

If your interested let me know and I’ll and get your in touch with Mark. I’ll be doing a similar presentation for my local PHP users group that same month so we should be able to share slides and preparation effort.

AJAX Article in php|arch

Wednesday, August 24th, 2005

A new article in php|architect is out, and an article I wrote about AJAX is in it.

The article gives a good introduction to AJAX as a concept and then moves into practical use.

The issue looks like a good with an article about PEAR 1.4 channels as well.

The PHP License

Tuesday, August 23rd, 2005

As you might have noticed HTML_AJAX is licensed under the PHP license. It is mainly because it borrows some JavaScript for JPSpan that was released under this license. It has been brought to my attention that there are a number of conditions in the license make its distribution problematic.

The problematic items (at least from a Debian packaging prospective are)

3. The name “PHP” must not be used to endorse or promote products
derived from this software without prior written permission. For
written permission, please contact group@php.net.”

4. Products derived from this software may not be called “PHP”, nor
may “PHP” appear in their name, without prior written permission from
group@php.net. You may indicate that your software works in
conjunction with PHP by saying “Foo for PHP” instead of calling it
“PHP Foo” or “phpfoo”

6. Redistributions of any form whatsoever must retain the following
acknowledgment: “This product includes PHP, freely available from
http ://www.php.net/”.

Generally these terms don’t apply well to stuff that isn’t PHP.

Anyhow how have other people approached this problem. For phpDocumentor im looking towards just doing a dual license with PHP and BSD, just because its been PHP licensed for so long. If I can get Harry to relicense the code I used I might just release HTML_AJAX on the BSD license for the next release, otherwise I guess im stuck unless I finish up all the JS refactoring I have planned.

Update:
Charles Fry wrote up Debian’s concerns and sent them to pear-dev if you want more details on why the license is a problem.

Website Usage Visuationzation and AJAX Tricks

Thursday, August 18th, 2005

I’ve been working on a small website stats project, mainly because webalizer et al don’t meet my needs. The actual implementation is mod_log_sql + a bunch of php/sql script to transform that to a star schema and then some php scripts for visualization.

Things are finally getting to the point of being useful, I have enough of the dw built out that I can answer basic questions about my site with a little sql fun, plus I have one good report. Now this report is where the AJAX tricks come into play, its a trick because were loading in data asyncronously, but its a trick because its done by changing the src of imges instead of using XMLHttpRequest. There is also a lot of neat JavaScript fun happen which I use to put up a loading screen while the images are being generated.

A look at the Report

Anyhow lets get a look actual report so you can see whats going on (normally I would post a link but 500 hits on this report would kill my server the main query takes 5-10 second, which can be optomized but i haven’t bothered). The image below is the starting page of the report, it has a list of my top blog articles this month with the date they were actually posted (well showed up in my logs) and there total hits. There are also 4 blank graphs with a default placeholder graphic.
Report Screenshot at start

Now if you click on one of the links in the table the 4 graphs will be updated with drilldown information about that page. The Images are generated with a query and then some processing with Image_Graph so they take anywhere from half a second to 2 to update, they also update at different times. To make things more user friendly I added a loading div that covers each image while its loading. This is shown in the screenshot below.
Report Screenshot during Load

After a second or two, the graphs finish loading and the loading screens disapear. This leaves you with a nicely updated report. Another nice effect (at least in firefox) is that the graphs stay cached as you click around between the different drilldown screens, but will update after a reload of the page. This makes for a snappy experience if you want to go back to something you’ve already seen.
Report Screenshot load finished

Making it Work

I’m not going to go into the details of the actual sql and Image_Graph code (contact me if you want to talk about it) but I will cover the JavaScript code that does the loading.

The way it works is:
You have a hidden javascript div that is a template for the 4 loading divs, it can contain anything you want (I’m lazy so mine just says loading).

On page load a setup function finds all the graph images (there are all in a div with the id of graphHolder) loops over the images and creates a loading div by cloneing the template. The new clones are then added to the same container as the images and absolutely positioned so they cover them. Since the template has display:none you don’t see the loading divs yet.

When we click on a link where actually using a javascript: url to call the updateGraph function, this function sets all the loading divs to a display of block so they cover the images and then it sets there new src.

And finally the Images have onload handlers hard coded on them that call loadingDone passing in this. Loading done then sets display back to none.

Something to play around with

So below is a real quick example so you can see if for yourself.

Code of Example:

Code of php script for making the color blocks with a nice delay.

<?php

require_once 'Image/Color.php';

sleep(2);

$im = imagecreatetruecolor(300,300);
$color = Image_Color::namedColor2RGB($_GET['color']);

$bg = imagecolorallocate($im,$color[0],$color[1],$color[2]);
imagefill($im,0,0,$bg);

header('Content-type: image/png');
imagepng($im);

?>

Wrapping it up

The great thing about AJAX is its more AJ then anything. If you have JavaScript there is no shortage of ways to load new data. Oh and on an unrelated note I’m writing an AJAX book, it should be some time in Jan, and I should have been writing a chapter of that instead of messing around with this :-). I’ll blog with some more details about that some time this weekend.

AJAX Hello World with HTML_AJAX

Wednesday, August 17th, 2005

This is a continuation of my AJAX Hello World series, in my earlier posts I covered sajax and JPSpan. In this article i’ll cover how to get a basic AJAX appliction up and running with HTML_AJAX. If you haven’t figured it out yet im one of the author’s of HTML_AJAX. The application in question is the same simple app as the other examples, it has an input box for adding random strings and an button to add a random one to a div.

When your using HTML_AJAX you have more choices then with either JPSpan or sajax. But to keeps things simple were going to use a setup similar to how we used JPSpan, an external server page that generates a JavaScript proxy which is included by our html page that does the actual action. HTML_AJAX could also be used sajax style with the proxy and server code generated inline, but I don’t recommend this usage since it remove your ability to cache the generated JavaScript.

Installing HTML_AJAX

This is nice and simple its simply:
pear install HTML_AJAX-alpha
If you don’t have pear setup on your server just follow the installation instructions in the PEAR Manual.

Setting up the Server Component

An HTML_AJAX server page is generally very simple, it creates an HTML_AJAX_Server instance, registers all the classes you want exported and handles incoming requests. The incoming requests can be three different types:

  • Client library request: query string includes ?client=all (can also be each of the seperate component parts)
  • Generated stub requests: query strings includes ?stub=classname (all keyword can also be used)
  • AJAX Requests: query string includes ?c=classname&m=methodname

Client and Stub requests can be combined into the same one, but remember there is a tradeoff when doing that. You’ll have less roundtrips to the server but generated stubs are more likely to change so they can hurt your cacheability. You also want to be careful about using stub=all since the stub for 10 different classes can be quite large. The next release will also allow for combining multiple classes in a stub request by seperating them with a comma like so: stub=test,test2. Finally a note on class names, in php4 they will be lower case since thats what PHP returns, if you would like to have case or need to guarantee php4/5 compatability you’ll want to use some optional paramaters to registerClass, the first is the name to register the class in JavaScript as, the second is an array of methods to export.
A basic server is shown below.

<?php

session_start();

require_once 'HTML/AJAX/Server.php';
require_once 'HelloWorld.class.php';

$server = new HTML_AJAX_Server();

$hello = new HelloWorld();
$server->registerClass($hello);

$server->handleRequest();

?>

A server like this works fine for small scale projects, but it might not be a good choice for something larger since you could be creating 20 class instances just to serve a request on one of them. Any custom setup also has to be done for each class. HTML_AJAX provides a way to manage this by extending the server class and adding an init method for each class. A server that does this for the same HelloWorld class is shown below.

<?php

session_start();

require_once 'HTML/AJAX/Server.php';

class AutoServer extends HTML_AJAX_Server {
        // this flag must be set for your init methods to be used
        var $initMethods = true;

        // init method for my hello world class
        function initHelloWorld() {
                require_once 'HelloWorld.class.php';
                $hello = new HelloWorld();
                $this->registerClass($hello);
        }

}

$server = new AutoServer();
$server->handleRequest();

?>

PHP Application Code

In the server examples above you’ll notice were including a Hello World class. This hasn’t changed from the JPSpan example. The only thing of note is that makes heavy use of session, many AJAX apps will share this same heavy use, so make sure your server setups can handle that.

<?php

// our hello world class
class HelloWorld {

        function HelloWorld() {
                if (!isset($_SESSION['strings'])) {
                        $_SESSION['strings'] = array('Hello','World','Hello World');
                }
        }

        function addString($string) {
                $_SESSION['strings'][] = $string;
                return $this->stringCount();
        }

        function randomString() {
                $index = rand(0,count($_SESSION['strings'])-1);
                return $_SESSION['strings'][$index];
        }

        function stringCount() {
                return count($_SESSION['strings']);
        }
}

?>

The HTML that ties it all together

To finish up our app we need to create the HTML that ties it all together. This is going to have two main parts, the main JavaScript logic, callback function for our async requests and a fake form. The call the form fake, because there is no form tags, were just powering everything off onclick event handlers on buttons. At some point in the future HTML_AJAX will support taking a normal form and magically turning it into an AJAX one but for now that thought is just in my head.

The page starts with normal HTML boiler plate and an include of our client library and the stub hello world class. They are done all in a single class since that makes sense for this example, if I had 10 classes it wouldn’t.

Next we build the callback hash, it has a method for each method in PHP, they will be called from the results from an async AJAX call. In this example each call back is really simple it either updates an element using innerHTML or appends to one. You could also use a normal JavaScript class instead of a hash, but thats only useful if you need multiple instances.

The next step is to create an instance of our helloworld class and create a helper function. When we create an instance of our proxy class we pass in our callback, if we didn’t the instance would work in a sync manner, which can be useful, but in this case would make for a choppy ui. The helper function do_addString isn’t anything exciting, it just clears out the textbox after we’ve submited its current value.

Finally we have the html body of the page, it contains our buttons with onclick event handlers that call remote functions. It also contains our output divs.

Trying out the sample

If you got this far you’ll want to try out the Hello World app were building. If you compare it against the JPSpan or sajax version you won’t notice many differences. The only visual one that should show up is loading notice in the top right corner. Since providing user feedback is such an important part of making a usable AJAX application HTML_AJAX includes this basic loading symbol out of the box. If you just want to customize its looks you just need to create an element with the id of HTML_AJAX_LOADING. Its shown by setting its display style to block, and hidden by setting display to none everything else is left up to you so make sure to take care of any positioning and setting its display to none so its hidden by default. If you want to do somthing more complex you can override HTML_AJAX.onOpen and HTML_AJAX.onLoad check out the current methods to see hows its done.

Finally you might notice some JavaScript errors if you try to make a lot of quick requests, like JPSpan HTML_AJAX only provides for one concurrent request at a time. This will change in the future giving you a number of different options but for now you can either keep those from happening at the application level, or just add a error handling function to HTML_AJAX.onError and ignore the call in progress ones.

You can also download the project and try it out on your own server, its available as a tar.gz or a zip.

Where to go from here

Now that you’ve had a look at HTML_AJAX you might be wondering how to learn more about it. For the moment your options are pretty limited. You can check out the examples dir (in the docs dir in pear or online) or you can ask questions on this post. You might also find the source to be useful, for now the newest version lives on my svn server.

Feed back is appreciated as I’ll use that to decide what features to add to HTML_AJAX and what to fully document next, feel free to post comments or trackbacks even if you have a lot to say.

Update:
This example won’t work correctly in PHP5 since the methods will be exported with CASE, take a look at the generated JavaScript if you don’t understand what i mean (auto_server.php?clalss=helloworld). See Comment #40 for your options to fix things.

Say Hello to HTML_AJAX

Thursday, August 11th, 2005

HTML_AJAX had its first PEAR release today. Its the same version as was voted on so there is no new code but you can use the PEAR installer to get it.

Once you have it installed you’ll find the examples in the docs dir to be quite helpful, on my server thats /usr/share/pear/docs/HTML_AJAX/examples. These examples are also available online: run, view code.

I’ve started a basic website for the project, it includes a development roadmap, so if you want to help out, or just want to know whats happening next thats a great place to start.

HTML_AJAX has two different main use cases, standalone and proxy.

Now in proxyless/standalone mode you can use just the JavaScript library making requests to pages and working with its results however you want.

To accomplish this basic usage you either need to create a instance of a server class that will server the JavaScript libraries, or copy them into your web root. These js files are located in your pear data directory, on my server thats: /usr/share/pear/data/HTML_AJAX/js.

Setting up a server that will handle client requests is easy, a basic one is shown below:

<?php

include 'HTML/AJAX/Server.php';

$server = new HTML_AJAX_Server();
$server->handleRequest();

?>

If you save that as server.php you can include the needed JavaScript libraries like below:

Once you have the libaries pulled in you easily make various AJAX calls, the main usage for proxyless operation is to pull down some new content and put it into your page using innerHTML. Any asyncronous example of this is shown below:

A sync version of grab is also available, just don’t pass it a callback function. This is even easier to use but has the disadvantage of blocking while the download happens. In some circumstances this can useful since your already in a callback, but you have to be careful when using it. Besides the grab method there is also a replace method it takes an id and replaces its innerHTML with the results. Finishing up the standalone api there is a call method which allows you to call methods on classes registered with the server. Registering classes is shown in the proxy section. A sample async call is shown below:

Call can also be used to do sync calls just pass false in instead of a callback function.

Moving on from the basic standalone api HTML_AJAX offers generated proxy classes. You start this usage by registering a class with the server. The class will be introspected and public methods will be exported (methods starting with _ are considered private).

<?php

include 'HTML/AJAX/Server.php';

class test {
  function rot13($string) {
    return str_rot13($string);
  }
}
$test = new test();

$server = new HTML_AJAX_Server();
$server->registerClass($test);
$server->handleRequest();

?>

After that you need to include the generated proxy class. After that you can create an instance of that, when you do it you pass in a callback class. An example of this calling the rot13 method is shown below.

There is some other optional functionality around as well, the examples show documentation of pretty much everything. I’ll write more formal documentation as I have time. If you have any questions feel free to ask them on this post, and i’ll either reply in the comments or in a new post if there is enough of them.

Frankfurt PHP Users Group AJAX Presentation Wrapup

Thursday, August 11th, 2005

I just finished a short presentation for the the Frankfurt PHP users group . I’m not sure thats its the best presentation i’ve ever given since I tried to do mainly a overview of the tech as well as a bit of talk on how it relates to flash.

Might have been easier just to go the normal route and show a bunch of code :-). Anyhow the technology worked pretty well for the slides but showing web pages didn’t work right at all.

I have the slides online, if your more interested in getting started playing around with AJAX one of these AJAX tutorials might be a better fit.

Also HTML_AJAX is approved and the first release has been made, i’ll be getting more docs up shortly.

HTML_AJAX Call for votes

Thursday, August 4th, 2005

I called for votes on the HTML_AJAX proposal on tuesday, it has 13 +1’s already so it looks like it will pass.

The voting period ends on the 10th so there is still plenty of time for you to review the code and vote on it if your a PEAR developer.

Moving forward on development im looking for feedback (prototype implementation would be great too :-)) on the big features im planing to add.
They are:
Call Queuing and ordering of Async calls
Call combining (if you have 10 items in your queue send them all at once) for both sync and async calls
Some sort of widget api.

I’m really not really sure what the widget api will look like, one though is to define a set of events and implement PHP and JavaScript base classes for each of them. I guess both sides will also need an api that allows you to dispatch those events as needed. Anyhow if anyhow ideas on how this should work let me know.

There is also some boring work to do:
The request JavaScript class seems a bit pointless so it would be good to slim it down even more or hopefully just replace it
Move the HTTPClient init out of each dispatcher class on onto the HTML_AJAX static class, that way it will be easier to add an object pool and put other rules about how many clients we have sitting around.

Javascript Goodness

Tuesday, August 2nd, 2005

Clay over at Pearified has been packaging popular JavaScript libraries an making them available over a pear 1.4 channel.

To install them you need to run:

pear channel-discover pearified.com

Then install the packages like

pear install pearified/JavaScript_Behaviour

Unless you have your data_dir set to something in your webroot you still need to expose the javascript file somehow. Your options are, writing a PHP script that will readfile the files (useful if you want extra control over caching, want to combine multiple libs together in an app specific way, or want to add gzip compression). If your on a Unix system you can symlink the files to your webroot, or you can use an Apache alias (or your webservers equivalent).

AJAX Resource Updates

Thursday, July 21st, 2005

I finally started clearing out my incoming bookmarks folder, still a long ways to go but a lot of whats left are reference links i’ll need when I do the writeup about my embedded mozilla project (thing pdf generation).

Anyhow here is the summary of todays updates.

library

Ajax.NET - The free library for .NET (C#)
Full Featured C# ajax lib
DWR - Direct Web Remoting
AJAX library for Java
Accesskey Underlining Library
Easy way to add access keys to any html page without changing the actual html
script.aculo.us - web 2.0 javascript
Effect and Drag n Drop library built on top of prototype
SACK - Simple AJAX Code Kit
JavaScript library for performing AJAX
youngpup.net - DOM-Drag
Lightweight JS Drag n Drop lib

article

adaptive path » ajax: a new approach to web applications
Original article that Created the AJAX name
The Man in Blue > This is not another XMLHttpRequest article
Article discussion the decision of JavaScript for “the extras” or for primary features, focuses on Gmail and Google maps
Using the XML HTTP Request object
Article covering the ins and outs of using XMLHttpRequest on various browsers, various requests such as GET POST HEAD are covered

oss

Monket Calendar
GPL AJAX online Calendar written in PHP and JavaScript

HTML_AJAX

Friday, July 15th, 2005

If your on the pear-dev mailing list you should have already seen the post but i’ll blog about it here as well hoping to get some feedback.

A proposal was made on pepr for an HTML_AJAX library in PEAR. I was less then happy with the implementation and since once a package is in PEAR its hard to replace I thought i’d step up and provide a package that I think is ready for widespread use. I wasn’t really considering doing this before this came up, since its a lot of work, and JPSpan has been working fine for me (thats not to say I wouldn’t do some things differently). So here is an alpha release of my HTML_AJAX library.

Anyhow im actively looking for someone to come aboard as a co-maintainer of this package, if your interested let me know.

Its goal is to over OO javascript proxy and proxyless operation. Sync and Async AJAX calls, with an optional JS library offering things like a content replacement api. It should be usable in a server style setup (JPSpan) or directly in a page (Sajax). Its curently doing all communication using JSON, but that might change if someone sees a good reason.

The current feature set is:

  • Ability to register multiple classes on one page
  • JSON is used for communication in both directions (I made add JPSpan xml from JavaScript to server as well)
  • Class are exposed to Javascript as classes
  • POST is used for sending requests
  • Decent JavaScript error handling (right now there is an alert catch on the errors, but we might just leave the exceptions alone at some point)

Next Steps are:
In the Javascript code:

  • Decide if JavaScript JSON implementation has a license that is ok (json.js)
  • At least switch to a smushed json.js (3k instead of 10k)
  • Clean up HTML_AJAX.js, I pull in a bunch of classes from JPSpan and I think they can be made smaller through refactoring
  • Expose onLoad etc events
  • Complete Async Callback support
  • Create an addon api that allows for, proxyless operation, direct content replacement from results

In the PHP Code:

  • Pearify JSON.php (this currently has a pepr proposal in the draft state, the author said he will try to move it forward, but who knows if he will have time)
  • Complete the api so it that is supports inpage operation like test.php, or out of pager operation (including the javascript proxy files)
  • Write code to deliver the js files through php with the proper caching headers, so you don’t have to copy the js files around unless you want too
  • Write a cache for javascript proxy files (I did this for JPSpan today so it should be too hard)

AJAX Resource List updates

Thursday, June 16th, 2005

I finally got through my incoming bookmark category and read up on all the AJAX stuff that looked useful. I also updated my resource browser code to allow you to browse by any tag.

I also had a couple other non AJAX related sites that look interesting.
First is Yahoo’s Term Extraction webservice, im not sure if its a good thing or not since the beauty of tags is that they are human created metadata, but I can see it being quite useful to add tags like to a large set of documents to make them more usable. I also ran into TinyMCE, one of those javascript rich text editors, the plugins support looks great for easy customization, which is something I always find I need when im trying to shoehorn one of these things in a current app.

Finally here are the new items in the resource library, If you click on a category you can read the extended description, and see the extra information i’ve got tags to the items.

library

CPAINT: Cross-Platform Asynchronous INterface Toolkit
PHP & ASP AJAX toolkit gpl and lgpl license
AjaxAC - Open-source PHP framework for creating AJAX / JavaScript applications
AJAX library for php with a focus on doing all the coding php side

tutorial

particletree · Degradable Ajax Form Validation
Tutorial showing howto use AJAX to validate a form, backend code in asp and php
phpRiot() :: Cloning Google Suggest with AjaxAC :: PHP articles, PHP tutorials, MySQL tutorials, PostgreSQL tutorials
Huge tutorial explaining ever step in building an application (google suggest clone) with AjaxAC
PHPBuilder.com: XMLHttpRequest and AJAX for PHP programmers, Part 2
Extension of an earlier tutorial showing basic text replacement
ONLamp.com: Ajax on Rails
Tutorial covering how to use Rails built in AJAX features

article

Silicon Valley Watcher: Where can you find Flickr and Apple in the same room? At the AJAX Summit of course. An insider report from the press-free zone where the future of webdev is being mapped out.
Article giving an overview of AJAX and a quick review of the O’Reilly/Adaptive Path AJAX Summit
Making Magic Happen: Predicting User Behavior in AJAX applications
Essay covering using AJAX to prefetch data for a user to improve there overall experience

blog

Joel Webber’s Blog -as simple as possible, but no simpler
Author of Drip, IE Leak detector as well as general AJAX commentary

AJAX File upload Progress

Sunday, May 1st, 2005

Example of how to use the newest version is available in another post.
Update
There is a new version of this code that follows the same approach but uses HTML_AJAX instead of JPspan.
You can view the new demo, and view the code in websvn.

Also note that the server isn’t setup to accept files larger then 8meg, so anything bigger will fail.

Also I’m looking for someone to help me improve the error handling, if your interested in getting involved and making some regular releases of the new code let me know.

Original Post below

A couple days ago I found an interesting ruby on rails project. It uses AJAX to update a progress bar as the file uploads. The trick is a patch to rails for getting upload status and doing the upload in an iframe so that the main page is still active.

So to replicate this I just had to find a patch that provides upload status in PHP and then implment my little iframe upload widget.

I found the PHP with a little work from google: Upload Progress Meter

First you need to install the patch and the extension, the included instructions are easy to follow. The only problem I found is that: upload_progress_meter.store_method = “file” had to be set in my php.ini before thing would work.

I also ran into a JPSpan problem, if your having network problems the status call might take longer then 1 second, and you’ll get Call in Progres error alert. This can be fixed with the current version of JPSpan but i’d like to see some api added to help. The proxied objects need some type of inProgress call to make this an easy fix.

One item of note is that the extension only provides information in a way to provide 1 progress bar per form no matter how many files. The javascript code is setup so multiple forms could be on a page at once and both uploading, but this hasn’t been tested.

Here is the demo you’ve been waiting for, for most connections a 250k file will be enough to see something besides connecting and complete.

Also if anyone has the time and skills to review the php patch and see what it would take to get integrated, please let me know. I haven’t heard from its author so I don’t know why its not integrated but it just seems crazy to have a 3K patch that is this useful only available to those who are willing to patch.

Code walk through

So the basic flow happens like this.

Display a page with a form:
this page has a hidden iframe, a hidden progress div, and some extra javascript code

Select the file to upload and submit the form:
The form has a target of the hidden iframe so even though the throbber starts the main page view won’t be getting new content when the upload is done.

The form onclick handler fires a setup function:
The function finds the progress div and shows it, it also registers a function to update the status ever second.

The update function fires every second:
This functions checks a counter to see if there are any more divs to update, if the counter is 0 it stops the update function from firing again
The function creates a remote proxy object to the php class UploadProgressMeterStatus if it hasn’t already been created
The function calls the get_status method on the proxy object with a list of all the progress divs and UPLOAD_IDENTIFIER’s that we need status for.
The function exits

The get_status method on the php class is called
The method calls upload_progress_meter_get_info() for each passed in identifier, the information is formated to a percent and a message which is returned

The callback function for get_status is called when the PHP class returns data
The callback updates the progress div
If were at 100% the we decrement our progress div counter and remove us from the list of divs to be updated

The iframe can also load a page once the file upload is done, it doesn’t currently do anything.

Example Code

This is really the only interestin php code in the project, and its not that interesting. When you have the Upload Progress Meter extension installedany form that is doing a file upload and has a hidden var called UPLOAD_IDENTIFIER can be tracked. The identifier has to be passed into the upload_progress_meter_get_info function so you have to keep track of it on the javascript side. Here we just pass those ids in, do a bunch of formating on the resulting array, and return the results. Note the returned array isn’t documented anywhere so this code and the code in the example php code provided with the extension is the best place to start if you want to do something else with it.

<?php

       /**
         * Get the status of all uploads passed in
         */
        function get_status($ids) {
                $ret = array();
                foreach($ids as $id => $upId) {
                        $ret[$id] =  new stdClass();

                        $tmp = upload_progress_meter_get_info($upId);
                        if (!is_array($tmp)) {
                                $ret[$id]->message = "Complete";
                                $ret[$id]->percent = "100";
                                break;
                        }

                        if ($tmp['bytes_total'] < 1) {
                                $percent = 100;
                        }
                        else {
                                $percent = round($tmp['bytes_uploaded'] / $tmp['bytes_total'] * 100, 2);
                        }

                        if ($percent == 100) {
                                $ret[$id]->message = "Complete";
                        }

                        $eta            = sprintf("%02d:%02d", $tmp['est_sec'] / 60, $tmp['est_sec'] % 60 );
                        $speed          = $this->_formatBytes($tmp['speed_average']);
                        $current        = $this->_formatBytes($tmp['bytes_uploaded']);
                        $total          = $this->_formatBytes($tmp['bytes_total']);

                        $ret[$id]->message = "$eta left (at $speed/sec) $current/$total($percent%)";
                        $ret[$id]->percent = $percent;
                }
                return $ret;
        }

?>

On the javascript side there is a bit more code, but none of its all that complex. This code is used to show the progress bar and give it some initial values. The main things to notice are that were add an update method to the div, this is a nice trick since it allows for runtime extension of objects in the DOM, and it will make updating things nice and easy in the other functions. Were also adding a getFirstDivByClass method to the div, I’m doing this so I don’t have to have so many divs to track, the classes only have to be unique inside the progress bar for this to work and thats much easier to achieve.

The code below calls the remote proxy and creates the callback function to handle the results. The is one area where improvements could be made. First there should be a check if there is currently a call in progress. Then it might also be smart to call the server less (especially on large files) and just generate the stats from the current download rate. This would add some complexity but would allow the progress bar to update smoothly and would allow the server calls to get down to once every 5 or 10 seconds.

If you don’t do a lot of javscript programming its worth nothing the use of for(var prop in result) and delete UploadProgressMeter_active[prop];

for(var prop in result) is how you loop through the properties on an object, this allow you to use them as associative arrays (just watch for methods on the objects since you’ll loop through them too).

delete UploadProgressMeter_active[prop] is the equivalent of unset($array['key']);


Code List

Updates

You may have noticed that the demo has stopped working a couple times. This was related to 2 things and there things you might want t think about if your going to use the patch. First it writes tmp files and fails silently if the directly no longer exists (darn /tmp cleaning scripts). Second its on my php5 server which has some users who are pushing the envelope which required me to upgrade to the php 5.1 beta and I forgot to repatch. Repatching wasn’t a big deal though I did have to move where a function was declared to get the extension to compile in gcc 4 (I upgraded to fedora core 4 as well).

Anyhow the demo is working and it should stay working as long as I remember to repatch with each upgrade.

New Version

This code has been updated to work with HTML_AJAX and to handle error conditions better. I haven’t done a formal release but you can grab it from svn.

Check it out from: http://svn.bluga.net/HTML_AJAX/UploadProgressMeter/trunk/

Or use websvn to get a tarball: http://websvn.bluga.net/wsvn/HTML_AJAX/UploadProgressMeter/trunk/?rev=0&sc=0

Also if your interested in helping out with the Upload Progress Meter let me know

This circle expands additional navigation
You should really buy my AJAX book.
You'll learn not only the technology you need for implementation but also an understanding that will help you get the most from AJAX.
You'll also have my eternal thanks :-)