goog.i18n.NumberFormat: Formatting numbers to localized strings

By using Closure’s NumberFormat class (located under goog.i18n package) is relatively easy to format numbers and print readable strings. All we have to import is goog.i18n.NumberFormat:

    goog.require('goog.i18n.NumberFormat');

Then, we have to create an instance of that class and specify the type of format to apply, by choosing among: CURRENCY, DECIMAL, SCIENTIFIC and PERCENT. Assuming we have to display a budget, we will write a similar statement:

// create a new formatter
var formatter = new goog.i18n.NumberFormat(goog.i18n.NumberFormat.Format.CURRENCY);

// test the output
console.log(formatter.format(15650.579));

The code above, by using the default locale, will print: $15,650.58. Is possible to localize the output by assigning a different symbols set to goog.i18n.NumberFormatSymbols. The code below will set an italian format:

// symbols setting
goog.i18n.NumberFormatSymbols = goog.i18n.NumberFormatSymbols_it_IT; 

// redefine formatter (in order to use new symbols set)
formatter = new goog.i18n.NumberFormat(goog.i18n.NumberFormat.Format.CURRENCY);

// see the differences
console.log(formatter.format(15650.579));

This time the output will be: € 15.650,58.

Automatically compile JavaScript applications using Google Closure and Ant

As I said on insideRIA, the power of Google Closure is represented by the additional tools provided by Google: the Java compiler (which compress and optimize your javascript files) and the python script (which calculates dependencies). This tools however are not so user friendly, because you have to rely on the terminal and invoke them through command lines, a pretty annoying procedure that can scare people which usually rely only on visual tools.
Fortunately is relatively easy to automatize this compilation, by using Ant (a Java-based build tool). Ant is included by default in Eclipse standard platform (anyway some stand alone Eclipse-based ide such Aptana don’t include it… it’s time to use such programs as Eclipse plugins!) and can be configured and used by simply writing an xml file formally named “build.xml“. A build file contains one root node “project” and at least one “target” node containing tasks to execute, tasks are a series of different operations that can be executed by Ant, such create/delete files and folders, zip/unzip a file, running scripts and more. To automatize the deployment of our JavaScript application, we will invoke the calcdeps.py and the compiler.jar from Ant in a single statement, and we will print the result to a specific file.
To invoke a script, we have to use the exec tag and specify at least the param “executable“, which indicates the location of the script to execute, then by setting the parameter “output” the result returned from the script will be redirect to the specified file. Finally, to avoid undesired output in the file, such debug information and errors, we have to specify also a file which will receive this type of data by using the “error” parameter.
Since, paths to scripts and other files can be very long, we can create custom variables to hold these information and then reusing them in our script invocations. This is as simple as use the “property” tag and specify a “name” and a “value” attributes.
The following is an example of how a build.xml will looks like:

<?xml version="1.0" encoding="utf-8"?>
<project 
	name="Google Closure Ant Test" 
	basedir="."
>
	
	<!-- Full path of the current project -->
	<property name="projectPath" value="/Users/davidezanotti/Documents/workspace/GoogleClosure" />
	
	<!-- Full path to Closure library -->
	<property name="closurePath" value="${projectPath}/closure" />
	
	<!-- List of javascript files to compile -->
	<property name="filesToCompile" value="${projectPath}/my-closure-app.js" />
	
	<!-- Full path to the compiler jar -->
	<property name="compilerPath" value="/Users/davidezanotti/Documents/closure-compiler/compiler.jar" />
	
	<!-- Full path to the compiled file (created if not defined) -->
	<property name="outputPath" value="${projectPath}/ant-generation.js" />
	
	<!-- Full path to the file which will contains debug output and errors -->
	<property name="logPath" value="${projectPath}/closure-compiler.log" />
	
	<!-- Compilation level -->
	<property name="compilation" value="WHITESPACE_ONLY" />
	
	<target name="JavaScript Compilation">
		
		<exec error="${logPath}" output="${outputPath}" executable="${closurePath}/bin/calcdeps.py">
			<arg line="-i ${filesToCompile} -p ${closurePath} -o compiled -c ${compilerPath} -f '--compilation_level=${compilation}'" />
		</exec>
		
	</target>
	
</project>

The build.xml above will first gathering all the necessary Closure files (dependencies) and then will compile the resulting js using a WHITESPACE_ONLY compilation. The result will be printed to the file “ant-generation.js” and the debug to “closure-compiler.log”.
To run the Ant process: right click on the build.xml and choose Run as Ant Build. This procedure can be also configured in order to execute all the task each time a file in the project is saved, but it’s not a great idea because the process can takes several seconds to complete.
If you want to learn more about Ant (I have to learn a lot too, since I never used it before :P), check the reference here: http://ant.apache.org

goog.net.XhrIo: make simple ajax calls with Google Closure

Closure has a consistent package called goog.net, which contains a lot of classes to work with ajax and remote http requests. In this post I want to show how to create a basic xhr object to make get/post calls, listen for related ajax events and send data to server. Once imported the main js file (base.js), we will require the following:

goog.require('goog.dom');
goog.require('goog.net.XhrIo');
goog.require('goog.structs.Map');
goog.require('goog.Uri.QueryData');

The most important import is goog.net.XhrIo, which represents the object wrapping the XmlHttpRequest and allows us to retrieve and send information to/from the server. This class is a pretty low level api, which means that several tasks are not as simple and automatic as they would in jQuery or such libraries, but on the other hand this offers us more control and consciousness of what we are going to do.
The first step is instantiate an object of type goog.net.XhrIo and take a reference to it:

var request = new goog.net.XhrIo();

Then we will be able to listen for events:

goog.events.listen(request, 'complete', ajaxCallBack);

In this case we will listen to a “complete” event, which is an event always dispatched by goog.net.XhrIo even if the call fails. We can however listen to a “success”, an “error”, an “abort” or a “readystatechange” event, but in most cases listen only to “complete” is the best and easy choice. If we decide to listen to “complete” event, we will handle the result and ask to goog.net.XhrIo if the ajax call has been successful or not:

goog.events.listen(request, 'complete', function(){
					
    if (request.isSuccess()) {
			
        // do something cool			
						
    } else {
		
        // display an apologize message				
					
    }
					
});

To start the request we will use the send() method, which accepts the following parameters: the url to call (the only mandatory argument), the method to use (usually “GET” or “POST”), a query string containing the parameters to send and a map (key-value object) representing custom headers to send.
Before starting the ajax call, let’s see how to create an object that will holds data to send to the server by using the class goog.Uri.QueryData:

var data = goog.Uri.QueryData.createFromMap(new goog.structs.Map({
    title: 'Test ajax data',
    content: 'foo',
    param1: 2500
}));

As I can see from Closure reference, the approach above is the faster way to create a “data container” in order to send data with ajax. We can use the static method createFromMap() of goog.Uri.QueryData and pass an anonymous map (which has no reference) to it. A map is one of the several objects coming from the Java world that has been introduced in Closure by Google under the package goog.structs, it is essentially an object containing a certain number of keys holding a determinate value. Once we have our data stored into a goog.Uri.QueryData we will use the toString() method to send it through ajax, send() method in fact expects a string representation of the data (param1=value&param2=value…) not an object:

request.send('ajax-test.jsp', 'POST', data.toString());

The complete example’s code is the following:

goog.require('goog.dom');
goog.require('goog.net.XhrIo');
goog.require('goog.structs.Map');
goog.require('goog.Uri.QueryData');
			
function doRequest() {
				
    // create the xhr object
    var request = new goog.net.XhrIo();
				
    // create a QueryData object by initializing it with a simple Map
    var data = goog.Uri.QueryData.createFromMap(new goog.structs.Map({
        title: 'Test ajax data',
        content: 'foo',
        param1: 2500
    }));
				
    // listen to complete event
    goog.events.listen(request, 'complete', function(){
					
        if (request.isSuccess()) {
						
            // inject response into the dom
            goog.dom.$('response').innerHTML = request.getResponseText();
						
            // print confirm to the console
            console.log('Satus code: ', request.getStatus(), ' - ', request.getStatusText());
						
        } else {
						
            // print error info to the console
            console.log(
                'Something went wrong in the ajax call. Error code: ', request.getLastErrorCode(),
                ' - message: ', request.getLastError()
            );
						
        }
					
    });
				
    // start the request by setting POST method and passing
    // the data object converted to a queryString
    request.send('ajax-test.jsp', 'POST', data.toString());
				
}

goog.ui.TabPane: Create tabs with Google Closure

Hi everyone,
by starting with this post I would like to begin a series of posts dedicated to the new javascript library released by Google: Closure!
Today I will focus my attention on tabs creation, since this is maybe the most common user interface component in a web application.
In order to create Closure tabs, we need to import the base js file (/goog/base.js) and then require the class goog.ui.TabPane. Inside our head (or body) we will get the following:




Continue reading

Installing Eclipse + Aptana + Subclipse SVN

Recently I’ve updated my Eclipse version and I installed certain plugin which has created some kind of conflict and confusion in my workspace. What I was trying to do was installing an SVN plugin in order to work on a google code SVN repository, but I had several errors and I lost several hours trying to figure out what was wrong. So I decided to do a fresh and clean installation, once understood the problem. So, I would like to write a sort of tutorial which will explain how to get a sound and working installation of Eclipse, Aptana and Subclipse (which as far I read, is actually the best plugin available for SVN on Eclipse).

Continue reading