Showing posts with label Technology Upgrades. Show all posts
Showing posts with label Technology Upgrades. Show all posts

Friday, May 9, 2008

Adobe Flex

From Wikipedia, the free encyclopedia

Adobe Flex is a collection of technologies released by Adobe Systems for the development and deployment of cross platform, rich Internet applications based on the proprietary Adobe Flash platform. The initial release in March 2004 by Macromedia included a software development kit, an IDE, and a J2EE integration application known as Flex Data Services. Since Adobe acquired Macromedia in 2005, subsequent releases of Flex no longer require a license for Flex Data Services, which has become a separate product rebranded as LiveCycle Data Services.

In February 2008, Adobe released the Flex 3 SDK under the open source Mozilla Public License. Adobe Flash Player, the runtime on which Flex applications are viewed, and Flex Builder, the IDE used to build Flex applications, remain proprietary.

Overview

Traditional application programmers found it challenging to adapt to the animation metaphor upon which the Flash Platform was originally designed. Flex seeks to minimize this problem by providing a workflow and programming model that is familiar to these developers. MXML, an XML-based markup language, offers a way to build and lay out graphic user interfaces. Interactivity is achieved through the use of ActionScript, the core language of Flash Player that is based on the ECMAScript standard.

The Flex SDK comes with a set of user interface components including buttons, list boxes, trees, data grids, several text controls, and various layout containers. Charts and graphs are available as an add-on. Other features like web services, drag and drop, modal dialogs, animation effects, application states, form validation, and other interactions round out the application framework.

In a multi-tiered model, Flex applications serve as the presentation tier. Unlike page-based HTML applications, Flex applications provide a stateful client where significant changes to the view don't require loading a new page. Similarly, Flex and Flash Player provide many useful ways to send and load data to and from server-side components without requiring the client to reload the view. Though this functionality offered advantages over HTML and JavaScript development in the past, the increased support for XMLHttpRequest in major browsers has made asynchronous data loading a common practice in HTML-based development too.

Technologies that are commonly compared to Flex include OpenLaszlo, Ajax, XUL, JavaFX and Windows Presentation Foundation technologies such as Silverlight.

Macromedia Flex Server 1.0 and 1.5

Macromedia targeted the enterprise application development market with its initial releases of Flex 1.0 and 1.5. The company offered the technology at a price around US$15000 per CPU. Required for deployment, the J2EE application server compiled MXML and ActionScript on-the-fly into Flash applications (binary SWF files). Each server license included 5 licenses for the Flex Builder IDE.

Adobe Flex 2

Adobe significantly changed the licensing model for the Flex product line with the release of Flex 2. The core Flex 2 SDK, consisting of the command-line compilers and the complete class library of user interface components and utilities, was made available as a free download. Complete Flex applications can be built and deployed with only the Flex 2 SDK, which contains no limitations or restrictions compared to the same SDK included with the Flex Builder IDE.

Adobe based the new version of Flex Builder on the open source Eclipse platform. The company released two versions of Flex Builder 2, Standard and Professional. The Professional version includes the Flex Charting Components library.

Enterprise-oriented services remain available through Flex Data Services 2. This server component provides data synchronization, data push, publish-subscribe and automated testing. Unlike Flex 1.0 and 1.5, Flex Data Services is not required for the deployment of Flex applications.

Coinciding with the release of Flex 2, Adobe introduced a new version of the ActionScript programming language, known as Actionscript 3, reflecting the latest ECMAScript specification. The use of ActionScript 3 and Flex 2 requires version 9 or later of the Flash Player runtime. Flash Player 9 incorporated a new and more robust virtual machine for running the new ActionScript 3.

Flex was the first Macromedia product to be re-branded under the Adobe name.

Adobe Flex 3

On April 26, 2007 Adobe announced their intent to release the Flex 3 SDK (which excludes the Flex Builder IDE and the LiveCycle Data Services) under the terms of the Mozilla Public License.[1] Adobe released the first beta of Flex 3, codenamed Moxie, in June 2007. Major enhancements include integration with the new versions of Adobe's Creative Suite products, support for AIR (Adobe's new desktop application runtime), and the addition of profiling and refactoring tools to the Flex Builder IDE.

In October 2007, Adobe released the second beta of Flex 3.
On December 12, 2007, Adobe released the third beta of Flex 3.
On February 25, 2008, Adobe released Flex 3 and Adobe AIR 1.0.

Adobe Flex 4

Adobe has announced that Flex 4.0 (code named Gumbo) will be released in 2009. Even though this announcement has been made, the product plan has yet to be completed.

Some themes that have been mentioned by Adobe that will be incorporated into Flex 4 are as follows:

  • Design in Mind: The framework will be designed for continuous collaboration between designers and developers.
  • Accelerated Development: Be able to take application development from conceptual to reality quickly.
  • Horizontal Platform Improvements: Compiler performance, language enhancements, BiDi components, enhanced text. (Speculation derived from Adobe Systems)
  • Broadening Horizons: Finding ways to make a framework lighter, supporting more deployment runtimes, runtime MXML. (Speculation derived from Adobe Systems)

Flex 4 milestones: (Speculation derived form Adobe Systems)

  • Scope determined, April 2008
  • Beta 1, late 2008
  • 4.0 final, 2009

LiveCycle Data Services

LiveCycle Data Services (previously called Flex Data Services) is a server-side complement to the main Flex SDK and Flex Builder IDE and is part of a family of server-based products available from Adobe. Deployed as a Java EE application, LiveCycle Data Services adds the following capabilities to Flex applications:

  • Remoting, which allows Flex client applications to invoke methods on Java server objects directly. Similar to Java remote method invocation (RMI), remoting handles data marshalling automatically and uses a binary data transfer format.
  • Messaging, which provides the "publish" end of the "publish/subscribe" design pattern. The Flash client can publish events to a topic defined on the server, subscribe to events broadcast from the message service. One of the common use cases for this is real-time streaming of data, such as financial data or system status information.
  • Data management services, which provides a programming model for automatically managing data sets that have been downloaded to the Flex client. Once data is loaded from the server, changes are automatically tracked and can be synchronized with the server at the request of the application. Clients are also notified if changes to the data set are made on the server.
  • PDF document generation, providing APIs for generating PDF documents by merging client data or graphics with templates stored on the server.

BlazeDS

Previously available only as part of Adobe LiveCycle Data Services ES, Adobe is announcing its plans to contribute the proven BlazeDS technologies to the community under the LGPL v3. BlazeDS gives the rapidly growing Adobe developer community free access to the powerful remoting and messaging technologies developed by Adobe.

Concurrent with this pre-release of BlazeDS, Adobe is publishing the AMF binary data protocol specification, on which the BlazeDS remoting implementation is based, and is committed to partnering with the community to make this protocol available for every major server platform. The source code will be available for download early 2008.

Flex and ColdFusion

Flex 2 offers special integration with ColdFusion MX 7. The ColdFusion MX 7.0.2 release adds updated Flash Remoting to support ActionScript 3, a Flex Data Services event gateway, and the Flex Data Services assembler. Flex Builder 2 also adds extensions for ColdFusion providing a set of wizards for RAD Flex development. A subset of Flex 1.5 is also embedded into ColdFusion MX 7 middleware platform, for use in the ColdFusion Flash forms feature. It is possible to use this framework to write rich internet applications, although its intended purpose is for rich forms only.

Flex Application Development Process

Everything below is directly sourced from the help file in version 2.0 Beta 3:

  • Define an application interface using a set of pre-defined components (forms, buttons, and so on)
  • Arrange components into a user interface design
  • Use styles and themes to define the visual design
  • Add dynamic behavior (one part of the application interacting with another, for example)
  • Define and connect to data services as needed
  • Build the source code into an SWF file that runs in the Flash Player

Release history

  • Flex 1.0 - March 2004
  • Flex 1.5 - October 2004
  • Flex 2.0 (Alpha) - October 2005
  • Flex 2.0 Beta 1 - February 2006
  • Flex 2.0 Beta 2 - March 2006
  • Flex 2.0 Beta 3 - May 2006
  • Flex 2.0 Final- June 28, 2006
  • Flex 2.0.1 - January 5, 2007
  • Flex 3.0 Beta 1 - June 11, 2007
  • Flex 3.0 Beta 2 - October 1, 2007
  • Flex 3.0 Beta 3 - December 12, 2007
  • Flex 3.0 - February 25, 2008

Notable sites using Flex

Notable sites using Flex include:

See also

CodeIgniter

CodeIgniter - Open source PHP web application framework

CodeIgniter is an Application Framework

CodeIgniter is a toolkit for people who build web application using PHP. Its goal is to enable you to develop projects much faster than you could if you were writing code from scratch, by providing a rich set of libraries for commonly needed tasks, as well as a simple interface and logical structure to access these libraries. CodeIgniter lets you creatively focus on your project by minimizing the amount of code needed for a given task.

CodeIgniter is Free

CodeIgniter is licensed under an Apache/BSD-style open source license so you can use it however you please. For more information please read the license agreement.

CodeIgniter Runs on PHP 4

CodeIgniter is written to be compatible with PHP 4. Although we would have loved to take advantage of the better object handling in PHP 5 since it would have simplified some things we had to find creative solutions for (looking your way, multiple inheritance), at the time of this writing PHP 5 is not in widespread use, which means we would be alienating most of our potential audience. Major OS vendors like RedHat are moving slowly to support PHP 5, and they are unlikely to do so in the short term, so we felt that it did not serve the best interests of the PHP community to write CodeIgniter in PHP 5.

Note: CodeIgniter will run on PHP 5. It simply does not take advantage of any native features that are only available in that version.

CodeIgniter is Light Weight

Truly light weight. The core system requires only a few very small libraries. This is in stark contrast to many frameworks that require significantly more resources. Additional libraries are loaded dynamically upon request, based on your needs for a given process, so the base system is very lean and quite fast.

CodeIgniter is Fast

Really fast. We challenge you to find a framework that has better performance than CodeIgniter.

CodeIgniter Uses M-V-C

CodeIgniter uses the Model-View-Controller approach, which allows great separation between logic and presentation. This is particularly good for projects in which designers are working with your template files, as the code these file contain will be minimized. We describe MVC in more detail on its own page.

CodeIgniter Generates Clean URLs

The URLs generated by CodeIgniter are clean and search-engine friendly. Rather than using the standard "query string" approach to URLs that is synonymous with dynamic systems, CodeIgniter uses a segment-based approach:

www.your-site.com/news/article/345

Note: By default the index.php file is included in the URL but it can be removed using a simple .htaccess file.

CodeIgniter Packs a Punch

CodeIgniter comes with full-range of libraries that enable the most commonly needed web development tasks, like accessing a database, sending email, validating form data, maintaining sessions, manipulating images, working with XML-RPC data and much more.

CodeIgniter is Extensible

The system can be easily extended through the use of plugins and helper libraries, or through class extensions or system hooks.

CodeIgniter Does Not Require a Template Engine

Although CodeIgniter does come with a simple template parser that can be optionally used, it does not force you to use one. Template engines simply can not match the performance of native PHP, and the syntax that must be learned to use a template engine is usually only marginally easier than learning the basics of PHP. Consider this block of PHP code:

<ul>

<?php foreach ($addressbook as $name):?>

<li><?=$name?></li>

<?php endforeach; ?>

</ul>

Contrast this with the pseudo-code used by a template engine:

<ul>

{foreach from=$addressbook item="name"}

<li>{$name}</li>

{/foreach}

</ul>

Yes, the template engine example is a bit cleaner, but it comes at the price of performance, as the pseudo-code must be converted back into PHP to run. Since one of our goals is maximum performance, we opted to not require the use of a template engine.

CodeIgniter is Thoroughly Documented

Programmers love to code and hate to write documentation. We're no different, of course, but since documentation is as important as the code itself, we are committed to doing it. Our source code is extremely clean and well commented as well.

CodeIgniter has a Friendly Community of Users

Our growing community of users can be seen actively participating in our Community Forums.

click here for the CodeIgniter User Guide

Prototype JavaScript framework

Prototype code sample

Prototype is a JavaScript Framework that aims to ease development of dynamic web applications.

Featuring a unique, easy-to-use toolkit for class-driven development and the nicest Ajax library around, Prototype is quickly becoming the codebase of choice for web application developers everywhere.

How Prototype extends the DOM

The biggest part of the Prototype framework are its DOM extensions. Prototype adds many convenience methods to elements returned by the $() function: for instance, you can write $('comments').addClassName('active').show() to get the element with the ID 'comments', add a class name to it and show it (if it was previously hidden). The 'comments' element didn't have those methods in native JavaScript; how is this possible? This document reveals some clever hacks found in Prototype.

The Element.extend() method

Most of the DOM methods are encapsulated by the Element.Methods object and then copied over to the Element object (for convenience). They all receive the element to operate with as the first parameter:


Element.hide('comments');
var div_height = Element.getHeight(my_div);
Element.addClassName('contactform', 'pending');

These examples are concise and readable, but we can do better. If you have an element to work with, you can pass it through Element.extend() and it will copy all those methods directly to the element. Example, to create an element and manipulate it:


var my_div = document.createElement('div');


Element.extend(my_div);
my_div.addClassName('pending').hide();


// insert it in the document
document.body.appendChild(my_div);

Our method calls just got shorter and more intuitive! As mentioned before, Element.extend() copies all the methods from Element.Methods to our element which automatically becomes the first argument for all those functions. The extend() method is smart enough not to try to operate twice on the same element. What's even better, **the dollar function $() extends every element passed through it** with this mechanism.

In addition, Element.extend() also applies Form.Methods to FORM elements and Form.Element.Methods to INPUT, TEXTAREA and SELECT elements:


var contact_data = $('contactform').serialize();
var search_terms = $('search_input').getValue();

Note that not only the dollar function automatically extends elements! Element.extend() is also called in document.getElementsByClassName, Form.getElements, on elements returned from the $$() function (elements matching a CSS selector) and other places - in the end, chances are you will rarely need to explicitly call Element.extend() at all.

Adding your own methods with Element.addMethods()

If you have some DOM methods of your own that you'd like to add to those of Prototype, no problem! Prototype provides a mechanism for this, too. Suppose you have a bunch of functions encapsulated in an object, just pass the object over to Element.addMethods():


var MyUtils = {
    truncate: function(element, length){
        element = $(element);
        return element.update(element.innerHTML.truncate(length));
    },
    updateAndMark: function(element, html){
        return $(element).update(html).addClassName('updated');
    }
}


Element.addMethods(MyUtils);


// now you can:
$('explanation').truncate(100);

The only thing to watch out here is to make sure the first argument of these methods is the element itself. In your methods, you can also return the element in the end to allow for chainability (or, as practiced in the example, any method which itself returns the element).

Native extensions

There is a secret behind all this.

In browsers that support adding methods to prototype of native objects such as HTMLElement all DOM extensions on the element are available by default without ever having to call Element.extend(), dollar function or anything! This will then work in those browsers:


var my_div = document.createElement('div');
my_div.addClassName('pending').hide();
document.body.appendChild(my_div);

Because the prototype of the native browser object is extended, all DOM elements have Prototype extension methods built-in. This, however, isn't true for IE which doesn't let anyone touch HTMLElement.prototype. To make the previous example work in IE you would have to extend the element with Element.extend(). Don't worry, the method is smart enough not to extend an element more than once.

Because of browsers that don't support this you must take care to use DOM extensions only on elements that have been extended. For instance, the example above works in Firefox and Opera, but add Element.extend(my_div) after creating the element to make the script really solid. You can use the dollar function as a shortcut like in the following example:


// this will error out in IE:
$('someElement').parentNode.hide()
// to make it cross-browser:
$($('someElement').parentNode).hide()

Don't forget about this! Always test in all the browsers you plan to support.

Defining classes and inheritance

In the early versions of Prototype, the framework came with basic support for class creation: the Class.create() method. Until now the only feature of classes defined this way was that the constructor called a method called initialize automatically. Prototype 1.6.0 now comes with inheritance support through the Class module, which has taken several steps further since the last version; you can make richer classes in your code with more ease than before.

The cornerstone of class creation in Prototype is still the Class.create() method. With the new version of the framework, your class-based code will continue to work as before; only now you don't have to work with object prototypes directly or use Object.extend() to copy properties around.

Example

Let's compare the old way and a new way of defining classes and inheritance in Prototype:

/** obsolete syntax **/ 


var Person = Class.create();
Person.prototype = {
  initialize: function(name) {
    this.name = name;
  },
  say: function(message) {
    return this.name + ': ' + message;
  }
};


var guy = new Person('Miro');
guy.say('hi');
// -> "Miro: hi"

var Pirate = Class.create();
// inherit from Person class:
Pirate.prototype = Object.extend(new Person(), {
  // redefine the speak method
say: function(message) {
    return this.name + ': ' + message + ', yarr!';
  }
});


var john = new Pirate('Long John');
john.say('ahoy matey');
// -> "Long John: ahoy matey, yarr!"

Observe the direct interaction with class prototypes and the clumsy inheritance technique using Object.extend. Also, with Pirate redefining the say() method of Person, there is no way of calling the overridden method like you can do in programming languages that support class-based inheritance.

This has changed for the better. Compare the above with:

/** new, preferred syntax **/ 


// properties are directly passed to `create` method
var Person = Class.create({
  initialize: function(name) {
    this.name = name;
  },
  say: function(message) {
    return this.name + ': ' + message;
  }
});


// when subclassing, specify the class you want to inherit from
var Pirate = Class.create(Person, {
  // redefine the speak method
say: function($super, message) {
    return $super(message) + ', yarr!';
  }
});


var john = new Pirate('Long John');
john.say('ahoy matey');
// -> "Long John: ahoy matey, yarr!"

You can see how both class and subclass definitions are shorter because you don't need to hack their prototypes directly anymore. We have also demonstrated another new feature: the "supercall", or calling the overridden method (done with special keyword super in the Ruby language) in Pirate#say.

How to mix-in modules

So far you have seen the general way of calling Class.create.

var Pirate = Class.create(Person, { /* instance methods */ }); 

But in fact, Class.create takes in an arbitrary number of arguments. The first—if it is another class—defines that the new class should inherit from it. All other arguments are added as instance methods; internally they are subsequent calls to addMethods (see below). This can conveniently be used for mixing in modules:

// define a module 
var Vulnerable = {
  wound: function(hp) {
    this.health -= hp;
    if (this.health < 0) this.kill();
  },
  kill: function() {
    this.dead = true;
  }
};


// the first argument isn't a class object, so there is no inheritance ...
// simply mix in all the arguments as methods:
var Person = Class.create(Vulnerable, {
  initialize: function() {
    this.health = 100;
    this.dead = false;
  }
});


var bruce = new Person;
bruce.wound(55);
bruce.health; //-> 45

The $super argument in method definitions

When you override a method in a subclass, but still want to be able to call the original method, you will need a reference to it. You can obtain that reference by defining those methods with an extra argument in the front: $super. Prototype will detect this and make the overridden method available to you through that argument. But, from outside world the Pirate#say method still expects a single argument; this implementation detail doesn't affect how your code interacts with the objects.

Types of inheritance in programming languages

Generally we distinguish between class-based and prototypal inheritance, the latter being specific to JavaScript. While upcoming JavaScript 2.0 will support true class definitions, current versions of the JavaScript language implemented in modern browsers are restricted to prototypal inheritance.

Prototypal inheritance, of course, is a very useful feature of the language, but is often too verbose when you are actually creating your objects. This is why we are emulating class-based inheritance (like in the Ruby language) through prototypal inheritance internally. This has certain implications. For instance, in PHP you can define the inital values for instance variables:

class Logger {    
public $log = array();
function write($message) {
$this->log[] = $message;
}
}
$logger = new Logger;
$logger->write('foo');
$logger->write('bar');
$logger->log; // -> ['foo', 'bar']

We can try to do the same in Prototype:

var Logger = Class.create({ 
  initialize: function() { },
  log: [],
  write: function(message) {
    this.log.push(message);
  }
});


var logger = new Logger;
logger.log; // -> []
logger.write('foo');
logger.write('bar');
logger.log; // -> ['foo', 'bar']

It works. But what if we make another instance of Logger?

var logger2 = new Logger; 
logger2.log; // -> ['foo', 'bar']

// ... hey, the log should have been empty!

You can see that, although some of you expected an empty array in the new instance, we have the same array as the previous logger. In fact, all logger objects will share the same array object because it is copied by reference, not by value. The correct way is to initialize your instances to default values:

var Logger = Class.create({ 
  initialize: function() {
    // this is the right way to do it:
this.log = [];
  },
  write: function(message) {
    this.log.push(message);
  }
});

Defining class methods

There is no special support for class methods in Prototype 1.6.0. Simply define them on your existing classes:

Pirate.allHandsOnDeck = function(n) { 
  var voices = [];
  n.times(function(i) {
    voices.push(new Pirate('Sea dog').say(i + 1));
  });
  return voices;
}


Pirate.allHandsOnDeck(3);
// -> ["Sea dog: 1, yarr!", "Sea dog: 2, yarr!", "Sea dog: 3, yarr!"]

If you need to define several at once, simply use Object.extend as before:

Object.extend(Pirate, { 
  song: function(pirates) { ... },
  sail: function(crew) { ... },
  booze: ['grog', 'rum']
});

When you inherit from Pirate, the class methods are not inherited. This feature may be added in future versions of Prototype. Until then, copy the methods manually, but not like this:

var Captain = Class.create(Pirate, {}); 
// this is wrong!
Object.extend(Captain, Pirate);

Class constructors are Function objects and it will mess them up if you just copy everything from one to another. In the best case you will still end up overriding subclasses and superclass properties on Captain, which is not good.

Special class properties

Prototype 1.6.0 defines two special class properties: subclasses and superclass. Their names are self-descriptive: they hold references to subclasses or superclass of the current class, respectively.

Person.superclass 
// -> null
Person.subclasses.length
// -> 1
Person.subclasses.first() == Pirate
// -> true
Pirate.superclass == Person
// -> true
Captain.superclass == Pirate
// -> true
Captain.superclass == Person
// -> false

These properties are here for easy class introspection.

Adding methods on-the-fly with Class#addMethods()

Class#addMethods was named Class.extend in Prototype 1.6 RC0.
Please update your code accordingly.

Imagine you have an already defined class you want to add extra methods to. Naturally, you want those methods to be instantly available on subclasses and every existing instance in the memory! This is accomplished by injecting a property in the prototype chain, and the safest way to do it with Prototype is to use Class#addMethods:

var john = new Pirate('Long John'); 
john.sleep();
// -> ERROR: sleep is not a method

// every person should be able to sleep, not just pirates!
Person.addMethods({
  sleep: function() {
    return this.say('ZzZ');
  }
});


john.sleep();
// -> "Long John: ZzZ, yarr!"

The sleep method was instantly available not only on new Person instances, but on its subclasses and existing instances currently in memory.

Introduction to Ajax

Introduction to Ajax

Last updated on February 24th, 2007

Prototype framework enables you to deal with Ajax calls in a very easy and fun way that is also safe (cross-browser). Besides simple requests, this module also deals in a smart way with JavaScript code returned from a server and provides helper classes for polling.

Ajax functionality is contained in the global Ajax object. The transport for Ajax requests is xmlHttpRequest, with browser differences safely abstracted from the user. Actual requests are made by creating instances of the Ajax.Request object.

new Ajax.Request('/some_url', { method:'get' });

The first parameter is the URL of the request; the second is the options hash. The method option refers to the HTTP method to be used; default method is POST.

Remember that for security reasons (that is preventing cross-site scripting attacks) Ajax requests can only be made to URLs of the same protocol, host and port of the page containing the Ajax request. Some browsers might allow arbitrary URLs, but you shouldn't rely on support for this.

Ajax response callbacks

Ajax requests are by default asynchronous, which means you must have callbacks that will handle the data from a response. Callback methods are passed in the options hash when making a request:


new Ajax.Request('/some_url',
  {
    method:'get',
    onSuccess: function(transport){
      var response = transport.responseText || "no response text";
      alert("Success! \n\n" + response);
    },
    onFailure: function(){ alert('Something went wrong...') }
  });

Here, two callbacks are passed in the hash that alert of either success or failure; onSuccess and onFailure are called accordingly based on the status of the response. The first parameter passed to both is the native xmlHttpRequest object from which you can use its responseText and responseXML properties, respectively.

You can specify both callbacks, one or none - it's up to you. Other available callbacks are:

  • onUninitialized,
  • onLoading,
  • onLoaded,
  • onInteractive,
  • onComplete and
  • onException.

They all match a certain state of the xmlHttpRequest transport, except for onException which fires when there was an exception while dispatching other callbacks.

Also available are onXXX callbacks, where XXX is the HTTP response status like 200 or 404. Be aware that, when using those, your onSuccess and onFailure won't fire because onXXX takes precedence, therefore using these means you know what you're doing.

The onUninitialized, onLoading, onLoaded, and onInteractive callbacks are not implemented consistently by all browsers. In general, it's best to avoid using these.

Parameters and the HTTP method

You can pass the parameters for the request as the parameters property in options:


new Ajax.Request('/some_url', {
  method: 'get',
  parameters: {company: 'example', limit: 12}
  });

Parameters are passed in as a hash (preferred) or a string of key-value pairs separated by ampersands (like company=example&limit=12).

You can use parameters with both GET and POST requests. Keep in mind, however, that GET requests to your application should never cause data to be changed. Also, browsers are less likely to cache a response to a POST request, but more likely to do so with GET.

One of the primary applications for the parameters property is sending the contents of a FORM with an Ajax request, and Prototype gives you a helper method for this, called Form.serialize:


new Ajax.Request('/some_url', {
  parameters: $('id_of_form_element').serialize(true)
  });

If you need to push custom HTTP request headers, you can do so with the requestHeaders option. Just pass name-value pairs as a hash or in a flattened array, like: ['X-Custom-1', 'value', 'X-Custom-2', 'other value'].

If, for some reason, you have to POST a request with a custom post body (not parameters from the parameters option), there is a postBody option exactly for that. Be aware that when using postBody, parameters passed will never be posted because postBody takes precedence as a body - using the option means you know what you're doing.

Evaluating a JavaScript response

Sometimes the application is designed to send JavaScript code as a response. If the content type of the response matches the MIME type of JavaScript then this is true and Prototype will automatically eval() returned code. You don't need to handle the response explicitly if you don't need to.

Alternatively, if the response holds a X-JSON header, its content will be parsed, saved as an object and sent to the callbacks as the second argument:


new Ajax.Request('/some_url', { method:'get',
  onSuccess: function(transport, json){
      alert(json ? Object.inspect(json) : "no JSON object");
    }
  });

Use this functionality when you want to fetch non-trivial data with Ajax but want to avoid the overhead of parsing XML responses. JSON is much faster (and lighter) than XML.

Global responders

There is an object that is informed about every Ajax request: Ajax.Responders. With it, you can register callbacks that will fire on a certain state of any Ajax.Request issued:


Ajax.Responders.register({
  onCreate: function(){
    alert('a request has been initialized!');
  },
  onComplete: function(){
    alert('a request completed');
  }
});

Every callback matching an xmlHttpRequest transport state is allowed here, with an addition of onCreate. Globally tracking requests like this can be useful in many ways: you can log them for debugging purposes using a JavaScript logger of your choice or make a global exception handler that informs the users of a possible connection problem.

Updating your page dynamically with Ajax.Updater

Developers often want to make Ajax requests to receive HTML fragments that update parts of the document. With Ajax.Request with an onComplete callback this is fairly easy, but with Ajax.Updater it's even easier!

Suppose you have this code in your HTML document:


<h2>Our fantastic products</h2>
<div id="products">(fetching product list ...)</div>

The 'products' container is empty and you want to fill it with HTML returned from an Ajax response. No problem:

new Ajax.Updater('products', '/some_url', { method: 'get' });

That's all, no more work. The arguments are the same of Ajax.Request, except there is the receiver element in the first place. Prototype will automagically update the container with the response using the Element.update() method.

If your HTML comes with inline scripts, they will be stripped by default. You'll have to pass true as the evalScripts option in order to see your scripts being executed.

But what if an error occurs, and the server returns an error message instead of HTML? Often you don't want insert errors in places where users expected content. Fortunately, Prototype provides a convenient solution: instead of the actual container as the first argument you can pass in a hash of 2 different containers in this form: { success:'products', failure:'errors' }. Content will be injected in the success container if all went well, but errors will be written to the failure container. By using this feature your interfaces can become much more user-friendly.

You might also choose not to overwrite the current container contents, but insert new HTML on top or bottom like you would do with Insertion.Top or Insertion.Bottom. Well, you can. Just pass the insertion object as the insertion parameter to Ajax:


new Ajax.Updater('products', '/some_url', {
  method: 'get',
  insertion: Insertion.Top
  });

Ajax.Updater will use the given object to make the insertion of returned HTML in the container ('products') element. Nifty.

Automate requests with the Ajax.PeriodicalUpdater

You find the Ajax.Updater cool, but want to run it in periodical intervals to repeatedly fetch content from the server? Prototype framework has that, too - it's called Ajax.PeriodicalUpdater, and basically it's running Ajax.Updater at regular intervals.


new Ajax.PeriodicalUpdater('products', '/some_url',
  {
    method: 'get',
    insertion: Insertion.Top,
    frequency: 1,
    decay: 2
  });

Two new options here are frequency and decay. Frequency is the interval in seconds at which the requests are to be made. Here, it's 1 second, which means we have an Ajax request every second. The default frequency is 2 seconds. Our users might be happy because the responsiveness of the application, but our servers might be taking quite a load if enough people leave their browsers open on the page for quite some time. That's why we have the decay option - it is the factor by which the frequency is multiplied every time when current response body is the same as previous one. First Ajax request will then be made in 1 second, second in 2, third in 4 seconds, fourth in 8 and so on. Of course, if the server always returns different content, decay will never take effect; this factor only makes sense when your content doesn't change so rapidly and your application tends to return the same content over and over.

Having frequency falloff can take the load off the servers considerably because the overall number of requests is reduced. You can experiment with this factor while monitoring server load, or you can turn it off completely by passing 1 (which is default) or simply omitting it.

Move along

Learn more about Ajax.Request, Ajax.Updater and Ajax options.

script.aculo.us

script.aculo.us Web 2.0 JavaScript

script.aculo.us is a set of JavaScript libraries to enhance the user interface of web sites. It provides an visual effects engine, a drag and drop library (including sortable lists), a couple of controls (Ajax-based autocompletion, in-place editing, sliders) and more. Be sure to have a look at the demos!

Help port the old, dead wiki to github and earn BIG BROWNIE POINTS! You can find a copy of the old wiki contents at http://script.aculo.us/docs. See some helpful hints for porting, and please follow the style guide!

API Documentation and Reference

This wiki details Version 1.8.1 of the library, which is the most current version of the 1.x trunk of script.aculo.us.

Core Effects: Effect.Highlight, Effect.Morph, Effect.Move, Effect.Opacity, Effect.Scale, Effect.Parallel

Combination Effects: Effect.Appear, Effect.BlindDown, Effect.BlindUp, Effect.DropOut, Effect.Fade, Effect.Fold, Effect.Grow, Effect.Puff, Effect.Pulsate, Effect.Shake, Effect.Shrink, Effect.SlideDown, Effect.SlideUp, Effect.Squish, Effect.SwitchOff

Effect helpers: Effect.Transitions, Effect.Methods?, Effect.tagifyText?, Effect.multiple?, Effect.toggle
Behaviours: Draggable, Droppables, Sortable, Form.Element.DelayedObserver?
Controls: Ajax.InPlaceEditor?, Ajax.InPlaceCollectionEditor?, Ajax.Autocompleter?, Autocompleter.Local?, Slider?
Miscellaneous: Builder, Sound?, Unit Testing

script.aculo.us is open source. Read up on how to contribute by finding bugs, making bug reports and helping fixing them.

Quick start

1. Download & install

Using script.aculo.us is easy! First, go to the script.aculo.us downloads page to grab yourself the latest version in a convenient package. Follow the instructions there, then return here.

Next, put prototype.js, scriptaculous.js, builder.js, effects.js, dragdrop.js, slider.js and controls.js in a directory of your website, e.g. /javascripts.

Third, load script.aculo.us in your web page. This is done by linking to the scripts in the head of your document.

  <script src="javascripts/prototype.js" type="text/javascript"></script>
<script src="javascripts/scriptaculous.js" type="text/javascript"></script>

The scriptaculous.js loader script will automatically load in the other libraries.

2. Use it!

To call upon the functions, use HTML script tags. The best way is to define them like this:

  <script type="text/javascript" language="javascript">
// <![CDATA[
$('element_id').appear();
// ]]>
</script>

This way, you won’t have to worry about using characters like < and > in your Java Script code.

You can also use effects inside event handlers:

  <div onclick="$(this).switchOff()">
Click here if you've seen enough.
</div>

If you want to get tricky with it, you can pass extra options to the effect like duration, fps (frames per second), and delay.

  <div onclick="$(this).blindUp({ duration: 16 })">
Click here if you want this to go slooooow.
</div>

jQuery is a new type of JavaScript library

jQuery is a new type of JavaScript library.


jQuery is a fast, concise, JavaScript Library that simplifies how you traverse HTML documents, handle events, perform animations, and add Ajax interactions to your web pages. jQuery is designed to change the way that you write JavaScript.

"You start with 10 lines of jQuery that would have been 20 lines of tedious DOM JavaScript. By the time you are done it's down to two or three lines and it couldn't get any shorter unless it read your mind." - Dave Methvin

What does jQuery code look like? The quick and dirty:

$("p.surprise").addClass("ohmy").show("slow");

Congratulations! You just ran a snippet of jQuery code. Wasn't that easy? There's lots of example code throughout the documentation on this site. Be sure to give all the code a test run, to see what happens.
The above code snippet looks for all paragraphs that have a class of 'surprise', adds the class 'ohmy' to them, then slowly reveals them. Click the 'Run' button to see it in action!

From Wikipedia, the free encyclopedia

jQuery is a lightweight JavaScript library that emphasizes interaction between JavaScript and HTML. It was released January 2006 at BarCamp NYC by John Resig.
Dual licensed under the MIT License and the GNU General Public License, jQuery is free and open source software.

Features

jQuery contains the following features:

  • DOM element selections
  • DOM traversal and modification, (including support for CSS 1-3 and basic XPath)
  • Events
  • CSS manipulation
  • Effects and animations
  • Ajax
  • Extensibility
  • Utilities - such as browser version and the each function.
  • JavaScript Plugins

Use

jQuery exists as a single JavaScript file, containing all the common DOM, Event, Effects, and Ajax functions. It can be included within any web page by using the following code:

<script type="text/javascript" src="path/to/jQuery.js"></script>

jQuery has two styles of interaction:

  • via the $ function, which is a factory method for the jQuery object. These functions are chainable; they each return the jQuery object
  • via $.-prefixed functions. These are functions which do not work in the jQuery object per se.

A typical workflow for manipulation of multiple DOM nodes begins with $ function being called with a CSS selector string, with results in the jQuery object referencing zero or more elements in the HTML page. This node set can be manipulated by applying instance methods to the jQuery object, or the nodes themselves can be manipulated. For example:

$("div.test").add("p.quote").addClass("blue").slideDown("slow");

…finds the union of all div tags with class attribute test and all p tags with class attribute quote, adds the class attribute blue to each matched element, and then slides them down with an animation. The $ and add functions affect the matched set, while the addClass and slideDown affect the referenced nodes.
The methods prefixed with $. are convenience methods or affect global properties and behaviour. For example:

$.each([1,2,3], function() {  
document.write(this + 1);
});

…writes 234 to the document.
It is possible to perform Ajax routines using the $.ajax and associated methods to load and manipulate remote data.

$.ajax({  
type: "POST",  
url: "some.php",  
data: "name=John&location=Boston",  
success: function(msg){    
alert( "Data Saved: " + msg );  
}
});

…will request some.php with parameters name=John and location=Boston and when the request is finished successfully, the response will be alerted.

See also

References

Further reading

Thursday, May 8, 2008

JavaScript Object Notation

JavaScript is a general purpose programming language that was introduced as the page scripting language for Netscape Navigator. It is widely believed to be a subset of Java, but it is not. It is a Scheme-like language with C-like syntax and soft objects. JavaScript was standardized in the ECMAScript Language Specification, Third Edition.

JSON is a subset of the object literal notation of JavaScript. Since JSON is a subset of JavaScript, it can be used in the language with no muss or fuss.

var myJSONObject = {"bindings": [ {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}, {"ircEvent": "PRIVMSG", "method": "deleteURI", "regex": "^delete.*"}, {"ircEvent": "PRIVMSG", "method": "randomURI", "regex": "^random.*"} ] };

In this example, an object is created containing a single member "bindings", which contains an array containing three objects, each containing "ircEvent", "method", and "regex" members.

Members can be retrieved using dot or subscript operators.

myJSONObject.bindings[0].method // "newURI"

To convert a JSON text into an object, use the eval() function. eval() invokes the JavaScript compiler. Since JSON is a proper subset of JavaScript, the compiler will correctly parse the text and produce an object structure.

var myObject = eval('(' + myJSONtext + ')');

The eval function is very fast. However, it can compile and execute any JavaScript program, so there can be security issues. The use of eval is indicated when the source is trusted and competent. This is commonly the case in web applications when a web server is providing both the base page and the JSON data. There are cases where the source is not trusted. In particular, clients should never be trusted.

When security is a concern it is better to use a JSON parser. A JSON parser will recognize only JSON text and so is much safer:

var myObject = JSON.parse(myJSONtext, filter);

The optional filter parameter is a function that will be called for every key and value at every level of the final result. Each value will be replaced by the result of the filter function. This can be used to reform generic objects into instances of classes, or to transform date strings into Date objects.

myData = JSON.parse(text, function (key, value) {
return key.indexOf('date') >= 0 ? new Date(value) : value;
});

A JSON stringifier goes in the opposite direction, converting JavaScript data structures into JSON text. JSON does not support cyclic data structures, so be careful to not give cyclical structures to the JSON stringifier.

var myJSONText = JSON.stringify(myObject);

If the stringify method sees an object that contains a toJSON method, it calls the method, and stringifies the value returned. This allows an object to determine its own JSON representation.

The stringifier method can take an optional array of strings. These strings are used to select the properties that will be included in the JSON text. Otherwise, all of the properties of the object will be included. In any case, values that do not have a representation in JSON (such as functions and undefined) are excluded.


JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.

JSON is built on two structures:

  • A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
  • An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.

These are universal data structures. Virtually all modern programming languages support them in one form or another. It makes sense that a data format that is interchangable with programming languages also be based on these structures.

In JSON, they take on these forms:

An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).

An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.

A string is a collection of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string.

A number is very much like a C or Java number, except that the octal and hexadecimal formats are not used.

Whitespace can be inserted between any pair of tokens. Excepting a few encoding details, that completely describes the language.

object
{}
{ members }
members
pair
pair , members
pair
string : value
array
[]
[ elements ]
elements
value
value , elements
value
string
number
object
array
true
false
null

string
""
" chars "
chars
char
char chars
char
any-Unicode-character-
except-"-or-\-or-
control-character
\"
\\
\/
\b
\f
\n
\r
\t
\u four-hex-digits
number
int
int frac
int exp
int frac exp
int
digit
digit1-9 digits
- digit
- digit1-9 digits
frac
. digits
exp
e digits
digits
digit
digit digits
e
e
e+
e-
E
E+
E-

Introduction to JSON

Introduction to JSON

Last updated on May 1st, 2007

JSON (JavaScript Object Notation) is a lightweight data-interchange format (if you are new to JSON, you can read more about it on the JSON website). It is notably used by APIs all over the web and is a fast alternative to XML in Ajax requests. Prototype 1.5.1 finally features JSON encoding and parsing support.

Prototype’s JSON implementation is largely based on the work of Douglas Crockford which will most likely be natively included in future versions of the main browsers. Crockford’s implementation is unfortunately unsuitable for use with Prototype because of the way it extends Object.prototype. (Note that this will no longer be an issue once it is natively implemented.)

Encoding

Prototype’s JSON encoding slightly differs from Crockford’s implementation as it does not extend Object.prototype. The following methods are available: Number#toJSON, String#toJSON, Array#toJSON, Hash#toJSON, Date#toJSON and Object.toJSON.

If you are unsure of what type the data you need to encode is, your best bet is to use Object.toJSON like so:


var data = {name: 'Violet', occupation: 'character', age: 25 };
Object.toJSON(data);
//-> '{"name": "Violet", "occupation": "character", "age": 25}'

In other cases (i.e. if you know that your data is not an instance of Object), you can invoke the toJSON method instead:


$H({name: 'Violet', occupation: 'character', age: 25 }).toJSON();
//-> '{"name": "Violet", "occupation": "character", "age": 25}'

Furthermore, if you are using custom objects, you can set your own toJSON method which will be used by Object.toJSON. For example:


var Person = Class.create();
Person.prototype = {
  initialize: function(name, age) {
    this.name = name;
    this.age = age;
  },
  toJSON: function() {
    return ('My name is ' + this.name +
      ' and I am ' + this.age + ' years old.').toJSON();
  }
};
var john = new Person('John', 49);
Object.toJSON(john);
//-> '"My name is John and I am 49 years old."'

Finally, using Element.addMethods you can create custom toJSON methods targeted at specific elements.


<input id="firstname" name="firstname" value="john" />

Element.addMethods('input', {
  toJSON: function(element) {
    element = $(element);
    return element.name.toJSON() + ": " + element.getValue().toJSON();
  }
})


Object.toJSON($('firstname'));
//-> '"firstname": "john"'

Parsing JSON

In JavaScript, parsing JSON is typically done by evaluating the content of a JSON string. Prototype introduces String#evalJSON to deal with this:


var data = '{ "name": "Violet", "occupation": "character" }'.evalJSON();
data.name;
//-> "Violet"

String#evalJSON takes an optional sanitize parameter, which, if set to true, checks the string for possible malicious attempts and prevents the evaluation and throws a SyntaxError if one is detected.


var data = 'grabUserPassword()'.evalJSON(true)
//-> SyntaxError: Badly formated JSON string: 'grabUserPassword()'

You should always set the sanitize parameter to true and an appropriate content-type header (application/json) for data coming from untrusted sources (external or user-created content) to prevent XSS attacks.

String#evalJSON internally calls String#unfilterJSON and automatically removes optional security comment delimiters (defined in Prototype.JSONFilter).


person = '/*-secure-\n{"name": "Violet", "occupation": "character"}\n*/'.evalJSON()
person.name;
//-> "Violet"

You should always set security comment delimiters (/*-secure-\n...*/) around sensitive JSON or JavaScript data to prevent Hijacking. (See this PDF document for more details.)

Using JSON with Ajax

Using JSON with Ajax is very straightforward, simply invoke String#evalJSON on the transport’s responseText property:


new Ajax.Request('/some_url', {
  method:'get',
  onSuccess: function(transport){
     var json = transport.responseText.evalJSON();
   }
});

If your data comes from an untrusted source, be sure to sanitize it:


new Ajax.Request('/some_url', {
  method:'get',
  requestHeaders: {Accept: 'application/json'},
  onSuccess: function(transport){
    var json = transport.responseText.evalJSON(true);
  }
});

Spry framework for Ajax

Ajax for Everyone

Spry is a JavaScript-based framework that enables the rapid development of Ajax-powered web pages. Not a JavaScript guru? No problem. Spry was designed to feel like an extension of HTML and CSS, so anyone with basic web-production skills can create next-generation web experiences by adding the power of Ajax to their pages.

Spry can be used with any server-side technology (ColdFusion, PHP, ASP.Net etc.). By building the front-end of your web application with Spry you enable a more efficient designer-developer workflow by keeping UI separated from back-end application logic.

Spry 1.6.1—Ensuring Adobe AIR compatibiity

With Spry 1.6.1, the latest release of Spry, you'll get features, samples and documentation that enable you to add Ajax goodness to your pages without having to sacrifice adherence to web standards or best-practices. We have also made changes to the framework to ensure that we work well in the Adobe AIR space.

Spry in a Nutshell

  • Spry is implemented as a set of JavaScript libraries. To use Spry on a page, simply include the JavaScript library that contains the Spry features you need, use those features on your page, and then deploy that JavaScript file to your site along with your page.
  • Spry has three parts: Spry Data, Spry Widgets and Spry Effects. They can be used together or independently of one another.
  • No browser plug-ins or server-side modules are required for Spry to work.
  • Dreamweaver CS3 has features that ease the development of Spry pages but Spry itself is completely tool-agnostic. Any code editor can be used to develop Spry pages.

Widgets

  • Spry widgets are advanced web components expressed in basic HTML markup, CSS and a little JavaScript.
  • Customization and styling is easily done using your existing HTML & CSS skills.
  • Spry widgets are accessible. They respond to keyboard navigation and degrade gracefully when JavaScript its turned off.

Check out the Spry Widget samples

Data

  • The Spry Data set transforms complex data sources into a familiar row/column format that can be placed anywhere within your page.
  • Supported data sources include XML, JSON and HTML
  • Easily add Dynamic Regions to your page that control retrieval and placement of data without writing any JavaScript.

Check out the Data set and Dynamic Region samples

Effects

  • Spry effects allow you to add smooth and graceful transitions to almost any element on your page
  • A single line of JavaScript is used to add an effect to your page.
  • Effects can highlight information, create animated transitions, or visually alter a page element for a certain period of time

Check out the Spry Effects samples

Spry Primer

Spry is an easy-to-use Ajax toolkit, made for designers and developers both. While it is simple to get started, there are a few concepts that, once familiar with, will make building Spry page easy.

This document will outline the high level concepts of Spry and link to more detailed information and samples.

Goals of Spry

Spry was started because most other Ajax frameworks out there can be quite complex; hard to get started, many dependent files and markup injection, making it hard to style and edit. We thought there was an easier way.

Spry leverages what you already know: HTML and CSS and some javascript, and uses custom attributes or small constructor scripts, to activate the functionality. The framework does most of the heavy lifting.

We try make sure that it is easy to customize. We provide simple CSS with clear class name as hooks for customization. If you want to set the size of the accordion, just set the width on the class, as you would normally set the width, or any other property, of an element.

An important idea for Spry is to not inject markup. This means that all the HTML code that is needed is actually on the page, not buried within a <script> tag. This makes it easy to figure out the generated code and it makes the HTML easy to edit and style.

The 3 Parts of Spry

Spry consists of 3 main parts:

  • Data - Using XML, JSON or HTML data to populate the page.
  • Widgets - Advanced page functionality using simple markup. Accordion and Sliding Panels are examples of widgets.
  • Effects - Add polish to the page by moving, showing and hiding elements on the page. Slide and Fade are examples of Effects.

Data

Spry Data was the first piece of Spry to be released and it is probably the most powerful part of the framework. It has two main concepts:

  1. Retreiving the data.
  2. Using the data on the page.

Pulling in the Data

First, to use Spry Data, you need to attach the core Spry javascript files to your page. The exact files you will need depend on the data source type, but all data sets use SpryData.js. These files are in the 'includes' folder in the Spry zip.

Spry has the concept of a 'data set'. This is data pulled in from XML, JSON or HTML files and converted into a table (a javascript object), with rows and columns, like a database table. The end result of the data set is the same, no matter what the data type is.

To this data set, you can specify some attributes or behaviors. By default, Spry downloads the data file, XML for instance, once and uses that to build the data set. We cache that data: If you want to get new data from the server directly, you can turn off the cache and tell Spry to get new data every 5 seconds, for example. These can be set as options in the constructor. The constructor is the script where the data set is defined.

A basic data set constructor looks like

<script>
var ds1 = new Spry.Data.XMLDataSet("folder/products.xml","products/product");
</script>

where the first value is simply the path to the XML source. The second value is the XPath into the XML file. This defines where you want to start pulling in data. XPath is explained well here.

The var name 'ds1' is the data set name and it is used in many places within a standard Spry page.

Any of our Data samples will have a data set defined.

You can have multiple data sets on a page. These data sets can depend on other data sets. Data set types can be mixed: you can have one XML data set and one JSON data set, for example.

If your are using XML as your data source, this can come from a XML file, or any file that generates XML. This can be Coldfusion, PHP or anything else that generates valid XML; Spry doesn't care where the data comes from.

Once the data set is created, it can be used on the page.

Spry Regions

The second half of the Spry data concept are Spry regions. Spry regions are elements on the page where Spry processing happens. These elements are denoted by custom attributes applied to elements on the page.

A basic Spry region looks like <div spry:region="datasetname"></div>. Spry regions can be used with most HTML tags.

This custom attribute tells Spry to look within this <div> for things to process. There are 2 things to process:

  1. Other spry attributes
  2. Data references.

There are Spry attributes for logical processing, things like 'spry:if' and 'spry:when'. There are also Spry attributes for behavioral things like 'spry:hover' which applies a CSS class to the element when the user mouses over the element.

Data references are used to add the data set data to the page. These are placeholders for the real data. A data reference is the data node name, wrapped in curly braces {}. For example, with this XML as a data set:

<products>
<product id="1">
<name>Photoshop</name>
<category>Digital Imaging</category>
</product>
</products>

Our data references are the node names wrapped in curly braces, therefore, we would have Spry code that looks like:

There is a spry:region because all Spry processing happens within a spry:region. Then we have the data references within the region. When the page is loaded in the browser, the output would be the first values in the XML file: Photoshop 1 Digital Imaging

So the most basic Spry data page would look like:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Spry Page</title>
<script src="SpryAssets/xpath.js" type="text/javascript"></script>
<script src="SpryAssets/SpryData.js" type="text/javascript"></script>
<script type="text/javascript">
var ds1 = new Spry.Data.XMLDataSet("data/adobe_products.xml", "products/product");
</script>
</head>
<body>
<div spry:region="ds1"> {ds1::name}</div>
</body>
</html>

A note here about data references. Notice in the example above, it is written {ds1::name}. This is the formal way of writing data references. In a scenario where you have multiple data sets, there might be more than one {name} column. Prepending the node name with the data set name and 2 colons is used to specify the data set it comes from.

If you want to use multiple data sets in one region, simply add the data set names to the spry:region attribute, separated by a space. The Master Detail sample uses 2 data sets.

<div spry:region="ds1 ds2">
{name}{ds2::name}
</div>

In this case, 'ds1' is listed first. That means you can use either the short or the formal data references for that data set. Any other data sets listed in the region must use the formal data reference form.

We mentioned above that you can have data sets from XML, JSON or HTML. The region part of the page does not care where that data comes from. The data references are all written the same way, regardless of the data source. All the spry:attributes work the same way, no matter what the data set is.

There are other Spry attribute for controlling the look and the flow of the page. For instance, a common Spry attribute is 'spry:if'. This is used to determine whether to show a part of the page, depending on a condition. A sample:

<div spry:region="ds1 ds2">
<span spry:if="{name} == 'Photoshop'">{name}{ds2::name}</span>
</div>

The value of the spry:if attribute is a javascript expression that equals 0 or 1 (true or false). Above, we are checking to see if the value of the {name} data rerefence is 'Photoshop'. If it is, that <span> would be printed on the page. If it is not equal, that <span> would not be displayed.

There are also attributes like 'spry:hover'. This applies the specified class name to the element when the mouse is over the element.

<style>
.redBG{background-color:red;}
</style>
...
<div spry:region="ds1 ds2">
<span spry:hover="redBG">{name}</span>
</div>

When the mouse is over the <span> tag, the 'redBG' class will be applied and turn the background color to red. When the mouse leaves the <span> the class will be removed.

With a combination of Spry attributes and data references, a high degree of control can be used on the page with a small amount of markup.

Learn more about Spry Data

The Data Set Overview describes in detail the flattening/XPath idea, advanced data set options and region concepts. A good read for learning Spry concepts.

The Dynamic Table document goes over building a basic Spry table.

See the Data/Region samples.

Read the XML Primer. This describes the basic concepts of XML.

Read the JSON Primer. The JSON data set overview.

The HTML data set overview. Describes how to use HTML tables as data sets.

The Data API describes all the features of the data capabilities.

Spry Widgets

Spry widgets are pieces of advanced page functionality encapsulated in regular HTML markup. Many are familiar with Accordions and Tabbed Panels. Spry also has widget like Sliding Panels and Collapsible Panels.

We refer to these as 'disclosure widgets', because content is hidden and 'disclosed' as users click into other panels. We also have form validation widgets like Checkbox and Text Field validation.

Widget Philosophy

The idea behind Spry widgets is that the widget structure is defined in HTML on the page. Then a small constructor script is used to convert that markup into the functioning widget.

For instance, the Collapsible Panel markup is the most basic:

<div id="CollapsiblePanel1" class="CollapsiblePanel">
<div class="CollapsiblePanelTab" tabindex="0">Tab</div>
<div class="CollapsiblePanelContent">Content</div>
</div>
<script type="text/javascript">
var CP1 = new Spry.Widget.CollapsiblePanel("CollapsiblePanel1");
</script>

Widgets have a container tag around them which defines for Spry where the widget begins and ends. These container tags have an ID defined that Spry uses to identify the widget markup.

For the Collapsible Panel, there is a tag for the tab and a tag for the content panel. Within these structure tags, you can put in any HTML you wish. Spry just needs to have that main structure correct.

The constructor script comes after the widget markup. This is because that markup needs to exist before Spry executes the script to create the widget.

The constructor defines a variable for the widget name ("CP1"). We then pass the ID of the widget container to the constructor ("CollapsiblePanel1").

We can set options for the widget (for Data, Widgets and Effects) by adding the options to the constructor. The syntax is ,{option:value, option:value}. For instance, instead of having the Collapsible Panel smoothly open and close, we can turn off the animation by passing an option in the constructor.

<script type="text/javascript">
var CP1 = new Spry.Widget.CollapsiblePanel("CollapsiblePanel1",{enableAnimation:false});
</script>

Most widgets have behaviors defined that allow control of the widget from other parts of the page. For instance, we can create a text link that will open or close a Collapsible Panel.

<a href="#" onclick="CP1.open();">Open the Panel</a>
<a href="#" onclick="CP1.close();">Close the Panel</a>

Most widgets will have a number of functions for these sorts of operations, depending on the complexity of the widget.

Learn More about Widgets

The Widget Model document describes in more detail the widget ideas presented here.

Each widget has an overview document. See them here.

Effects

Effects are combinations of javascript and CSS that cause page elements to change appearance, size or position. See the Effects demo for a sample of each Effect.

All the effects are contained within the SpryEffects.js file. This file should be included on your page if you want to use the effects.

Effects work by first defining the effect as a javascript object. Then add functions to your page to start or stop the effect. A simple effect looks like:

<div id="fadeMe">Fading...</div>
<a href="#" onclick="myEffect.start();">Fade it</a>

<script>
var myEffect = new Spry.Effect.Fade("fadeMe",{from:100, to:0, duration:1000, toggle:true});
</script>

Note that again, the constructor scripts come after the markup.
Here we define an Effect called 'myEffect'. This is the name we use to control the effect. In the constructor, we specify the ID of the element we will fade: "fadeMe". We then list the options:

  • from: the starting opacity
  • to: the final opacity
  • duration: how long to complete the effect, in milliseconds.
  • toggle: Tells the effect to reverse when clicking the link again.

In the <a> we call the 'start' method that starts the effect: onclick="myEffect.start();".

The effects list contains base effects and combination effects. Base effects are simple animators: Move, Size, Opacity or Color. All other effects, like Puff, are combinations of these base effects.

For more advanced effects, there are Cluster effects. Users can take our base effects and combine them into groups. These groups can be run in parallel or in sequence. The demo has 2 examples.

Learn More about Effects

The Effects Coding document describes each effect and all their options.

Advanced Spry

Spry can do more than what is described here.

We have functions for:

and more...