HTML5 Drag & Drop

In this article, we're gonna see one of the awesome new features of HTML 5 : moving elements in the page and tracking it in javascript.

A demonstration of what we're gonna do is available online.

Why HTML 5 ?

Indeed ! We could very well be using javascript frameworks such as jQuery which already implements drag & drop There are several problems to that however :

  • You become dependant of the jQuery framework.
  • The thing's ergonomy could be discussed whenever you have a bit complex objects (in my case, nested arrays, every element of the array should be moveable from one parent to one of the childs and the opposite).
  • It's quite heavy.
  • It's not accessible at all when you don't have a mouse.

That's why we're gonna look into implementing this drag & drop thing in HTML5.

The HTML tag

We will create, in our page, two simple elements which will be the containers.

<div class="box"></div>
<div class="box></div>

Then, in the first one, we'll add an element which will be moveable to the second.

<div class="box"><div class="element" id="first">Hey !</div></div>

In order to see them better, we'll add a bit of style.

<style type="text/css">
    .box {
        border: 1px solid #CCC;
        width: 150px;
        height: 150px;
        float: left;
        margin: 10px;
    }
    .element {
        width: 50px;
        height: 50px;
        background-color: #CCCCCC;
        margin: 5px;
        padding: 3px
    }
</style>

We know have all the needed elements to make a simple drag & drop in our page. Let's move it.

The events

We have access to several new events which allows us to activate that drag & drop.

Moving the element

Only one event will be needed for now : ondragstart. This event is triggered whenever you start the drag & drop on an object which allows it.

To make an element draggable, we must add it the draggable=true attribute. Then in the box which contains it, we add the appropriate event.

<script type="text/javascript">
    function dragStart(event) {
        event.dataTransfer.effectAllowed = 'move';
        event.dataTransfer.setData("Text", event.target.getAttribute('id'));
    }
</script>

<div class="box" ondragstart="dragStart(event);">
    <div id="first" class="element" draggable="true">Hey !</div>
</div>

Let's analyse that code.

The dataTransfer object

The two methods used are part of the dataTransfer object. It's a new object of HTML5. It allows you to keep track of some datas between events.

So, when in an event, we update a data in dataTransfer, it'll be accessible to all the other events. Like that, we can save datas and get them back in an other event. This will be very useful to move the appropriate object.

effectAllowed allows us to define the type of move that we're allowing. The moved are the following :

  • all - The event can be copied, moved and linked.
  • copy - The event can be copied.
  • copyLink - The event can be copied and linked.
  • copyMove - The event can be copied and moved.
  • link - The event can be linked.
  • linkMove - The event can be moved and linked.
  • move - The event can be moved.
  • none - The event can't be copied, moved nor linked.
  • uninitialized - Default value, which means "move" for editable elements, "link" for anchors and "copy" for anything else.

setData allows us to define a value to our dataTransfer. Here, we define the element's id. But you could define whatever you want and which will allow you to get back that element thereafter.

The "Text" key isn't definable as you wish. It means the format of the string we transmis (here, some text). Some browsers, like Firefox, accepts any value. Chrome, however, will require you to use the appropriate one.

Our object is now moveable in the page. Let's drop it in the second box.

Dropping the element

Just being able to move the elemnt won't bring us very far. In order to drop it, we'll add two events : ondragover and ondrop.

ondragover is executed whenever our mouse goes over an element when dragging. It'll allow us to allow or not dropping the element in the second box.

By default, javascript doesn't accepts that we drop the element. Consequently, we must return false to stop propagating the event and don't have the default behavior.

ondrop is executed when we drop the element in the second box. That's when we effectively move the element in the dom.

Here's what we get.

<script type="text/javascript">
    function dragStart(event) {
        event.dataTransfer.effectAllowed = 'move';
        event.dataTransfer.setData("Text", event.target.getAttribute('id'));
    }

    function dragOver(event) {
        return false;
    }

    function drop(event) {
        var element = event.dataTransfer.getData("Text");
        event.target.appendChild(document.getElementById(element));
        event.stopPropagation();

        return false;
    }
</script>

<div class="box" ondragstart="dragStart(event);" ondragover="return dragOver(event);" ondrop="return drop(event);">
    <div id="first" class="element" draggable="true">Hey !</div>
</div>
<div class="box" ondragstart="dragStart(event);" ondragover="return dragOver(event);" ondrop="return drop(event);">

Try it yourself. You can drag/drop the element from a box to an other ! :-)

You can use the online demonstration to try it.

All the available events

We've seen here how to something very simple. However it's possible to make it more complex depending of your needs. Here's all the events you can use.

  • dragstart - Represents the beginning of the move. It's executed whenever you start moving an element.
  • drag - Event executed at regular intervals whenever you're moving (the HTML5 documentation says every 350ms). If it returns false, the move it stopped and canceled.
  • dragenter - Event executed whenever the event you're moving is coming into an other element.
  • dragleave - Event executed whenever the event you're moving leaves an other element.
  • dragover - Event executed whenever you're coming above an other element. If you let it's propagation continue (if you don't return false), it won't be possible to drop the object you're moving in that element.
  • drop - Event executed when you drop the object in an other element.
  • dragend - Event executed when the move ends.

Conclusion

Right now, only Opera doesn't supports drag & drop. All other recent browsers have it. This solution is, of course, to be prefered to any full javascript one which will only simulate something which can be natively managed by the browser.

How and why we've moved from CouchDB to MongoDB

After quite some hesitations and discussions, we've decided to migrate our application from CouchDB to MongoDB.

I'll try, in that article, to explain why and how we've decided to do so.

The why

The image at the left is the search interface for the application on which I'm working.

In that application, we have several records (each one of them representing a borehole). Each record has several attributes such as those displayed here (name; length and date).

The higher part of the image is the filters. We can add as many filters as we want on the attributes. Here, for example, we have two filters : one on the serial of the machine which did the borehole. And an other one on a date interval.

The displayed records are the one which correspond to all the provided filters.

How it works with CouchDB

In order to search for the appropriate record wich CouchDB, we dynamicaly create several views.

For example, the search above is calling the view by_boreholename_creation_date, which returns all the records wich, as key, an array of all the provided attributes. When calling that view, we search with startkey and endkey.

However the way startkey and endkey works is a bit special. It does an equality comparison for all the array elements, except the last one.

So let's guess the following search :

  • An interval of date.
  • The borehole name.

The second elemnt will be appropriately searched. However for the interval, the search will be a ==. Consequently, we won't have the results we want. We will only have the results for which the date is exactly the one we've entered.

At the WebWorkersCamp, when I asked for this, someone suggested I should do one request for every filter.

Knowing that some of our clients have more than 700 records and it's growing exponentially, that wasn't possible.

Let's see MongoDB

So we've decided to migrate to MongoDB. I started to work on that migration the 26th or july and it's been deployed in production this week (30th of august).

MongoDB queries are way easier. Mostly because we don't need to care about javascript views. They're generated automatically by the engine. The operators allows us to manage all of our needs.

We're using mongoid (with rails 2.3). And a simple call to the where method with the appropriate arguments hash is enough to make our search.

We don't have the same problems with the filters order. Our searches are always done on an interval when there's one or on a regular expression when it's a string.

The how

With CouchDB, we were using CouchRest. With MongoDB, we're using Mongoid.

The "how" problem was the data migration. I didn't wish to do too low level.

So I've moved the CouchDB models to the lib/ folder (so they don't get automatically loaded when launching the application in production) and I gave them the following content :

module Couchdb  
    class Record < CouchRest::ExtendedDocument
        def self.to_s
            "Record"
        end
    end
end

So my model gets the datas from the CouchRest namespace "Record" and not "Couchdb::Record"

Than in a rake task, I loop through all the CouchDB records and add them to MongoDB.

Couchdb::Record.all.each do |record|
    record.delete '_rev'
    record.delete '_attachments'
    record.delete 'couchrest-type'
    r = Record.new record     
    puts "Record saved"
  end
  puts "There are now #{Record.count} records in the mongo db"

As CouchRest's models extends from Hashes (which is a quite weird decision), it's much easier to get all the attributes and just remove the internal ones.

You'll note that we don't remove the _id from CouchRest. Like that, our documents keep the same id.

That rake task is manually executed when we've been deploying in production.

Conclusion

Don't give up on CouchDB because of that article ! This engine is really great, even though it didn't fit with our specific search needs. I wouldn't hesitate to recommand it.

Moreover a good news is that, as MongoDB stores it's datas in binary json, accessing them is much faster. We don't have real production statistics yet. But the execution time of our tests has reduced of 20% !

Create your own CarrierWave processors

If you need to manage images in a rails application, I can only recommand CarrierWave.

That library will allow you to easily manage files upload. But also post processing on images, such as changing their sizes.

I use CarrierWave on this blog even though you don't see it yet. Every category and every article has an image. That image has several different versions which have different sizes.

For one of those versions, I which to have rounded corners. You can see the result in the image at the left.

Let's see in details how I got that.

 

Post processing CarrierWave

Let's imagine the following uploader :

class CategoryUploader < CarrierWave::Uploader::Base
    include CarrierWave::RMagick
    version :thumb do
        process :resize_to_fill => [248, 163]
    end
end

We have a category uploader which will create a "thumb" version of the image. That image will have a size of 248 * 163 pixels.

You can find the processor "resize_to_fill" which will change the image's size at lib/carrierwave/processing/rmagick.rb.

In order to create our rounded corners, we'll create our own processor. I've placed it at lib/dmathieu/carrier_wave/round.rb.

unless defined? Magick 
    begin
        require 'rmagick'
    rescue LoadError
        require 'RMagick'
    rescue LoadError
        puts "WARNING: Failed to require rmagick, image processing may fail!"
    end
end

module Dmathieu
    module CarrierWave
        module Round

            module ClassMethods
                def rounded_corner(radius = 10)
                    process :rounded_corner => [radius]
                end
            end

            ##
            # Makes the image's corners round
            #
            #
            # === Parameters
            #
            # [radius (#to_s)] the corner radius
            #
            # === Yields
            #
            # [Magick::Image] additional manipulations to perform
            #
            def rounded_corner(radius = 10)
                #
                # See above for this method's code
                #
            end
        end
    end

Then, in your uploader, you can include that newly created processor.

class CategoryUploader < CarrierWave::Uploader::Base
    include CarrierWave::RMagick
    include Dmathieu::CarrierWave::Round

    version :thumb do
        process :resize_to_fill => [248, 163]
        process :rounded_corner
    end
end

You can see that, in our module, we create a method rounded_corner which will do the job of adding the rounded corners in our image. That action will be automatically called by CarrierWave when generating that version of the image.

Rounding up the corners

In order to manipulate our image, we use rmagick.

We're gonna do the following :

  • Create a new image of the same size than the previous which will contain a rectangle with rounded corners.
  • Put that image above the previous one.

Quite easy no ? ;-)

def rounded_corner(radius = 10)
    manipulate! do |img|
        masq = ::Magick::Image.new(img.columns, img.rows).matte_floodfill(1, 1)         
        ::Magick::Draw.new.
            fill('transparent').
            stroke('black').
            stroke_width(1).
            roundrectangle(0, 0, img.columns - 1, img.rows - 1, radius, radius).
            draw(masq)

        img.composite!(masq, 0, 0, Magick::LightenCompositeOp)
        img = yield(img) if block_given?
        img
    end
end

We've just defined the rounded_corner method, which is located in the module provided earlier.

The manipulate! method is located in the rmagick.rb processor and gives us the image, allowing us to update it and to transmit it back to the next processor.

masq = ::Magick::Image.new(img.columns, img.rows).matte_floodfill(1, 1)

We create here a new image of the same size than the previous. But which contains nothing.

::Magick::Draw.new.
        fill('transparent').
        stroke('black').
        stroke_width(1).
        roundrectangle(0, 0, img.columns - 1, img.rows - 1, radius, radius).
        draw(masq)

We draw in the image we've just created.

fill('transparent').

The rectangle we'll create will have a transparent background.

stroke('black').
stroke_width(1).

That rectangle will have a black border of 1 pixel.

roundrectangle(0, 0, img.columns - 1, img.rows - 1, radius, radius).
draw(masq)

We create here the rectangle and add it to the previously create image.

img.composite!(masq, 0, 0, Magick::LightenCompositeOp)

Finally we add that rectangle image on top of the one which already exists, giving the effet we want.

img = yield(img) if block_given?
img

CarrierWave's processors are nested. Each one of them is executed one after the other. With yield, we give the image to the next processor. It'll then just have to execute it's own modifications.

Finally we return the image which will be saved.

Conclusion

As you can see, CarrierWave allows us to create generic processors so you can get your images exactly as you want them.

I'm actually quite surprise to see there's not a lot of open source processors running wild.

Deploy an Android Application

This article follows Getting started in Android programming. We're gonna take back the application we've programmed previously, build it, test it in the SDK and deploy it on a real phone.

If you haven't followed the previous article, you can always use it from the github repository. However it's not the best way to do it ;-)

Sign our applications

Android requires us to sign every application we wish to install, whether it's on the SDK or on a real phone. That system uses a signature in order to check who's the author of the application and establish trust links between all of your applications.

The signature isn't used to check which applications the user can install. It's useless to have a signature certified by an authorized entity. It's perfectly allowed and not atypical for applications to use auto signed certificats.

Some features of the signatures can influence the strategy you'll adopt. Mainly if you plan to deploy several appplciations. The recommanded strategy is one signature for all your applications, for the following reasons :

  • Updates - All versions of one application should be signed with the same certificate. Otherwise, the system won't update the application.
  • Modularity - The system allows us to share the same process between several applications with the same signature, so they would be considered as the same one. With this, you can have several modules for one applications, allowing the user to install one or an other.

One other important thing when you create your signature is the validity period of this one. Indeed when we hit the key's expiration date, your users won't be able to update their applications to newer versions.

Moreover if you plan to publish your application on the Android Market, the key will have to expire after octobre 2033 the 22st.

Development deployment and execution in the SDK

If you've built your project the "standard" way, using the android create project command then you have a local.properties file at the top of it. If you've checked out an other project then you must create it.

This file must contain the path to the Android SDK on your disk. On my current machine this content is the following :

sdk.dir=/home/damien/android-sdk-linux

If it does not exists yet, create it with the appropriate folder.

Then we will build the application's package. For that we'll use ant. This project, is a tool allowing you to build java packages.

For a dev build, enter this in your console :

ant debug

The console display should end with the following :

(master) damien@pcdamien ~/projects/translator $ ant debug

BUILD SUCCESSFUL
Total time: 3 seconds

If you have the BUILD SUCCESSFUL message it means your project has been successfully built.

Now let's execute the virtual machine and install the application on the cellphone. In our previous article, we've seen how to install the Android SDK. Now, let's create a virtual phone.

android create avd -n translator -t android-7

We'll create a new virtual machine which we'll name "translator" and which will have the android-7 target (which is Android 2.1).

Let's execute that virtual machine.

emulator -avd translator &

Now you should see a window with a cellphone starting. Let it start, it can take a few minutes. Once that's done, unlock it. Your new virtual machine is started !

It's virtually linked in USB to your machine. So you can access it distantly. That's what we're gonna do to install the application.

adb install bin/translator-debug.apk

This command will connect us to the cellphone and install the application on it. The console display should be the following :

2216 KB/s (34777 bytes in 0.015s)
    pkg: /data/local/tmp/translator-debug.apk
Success

If, however, you have the following message :

error: device offline

Try to manipulate the cellphone (open the menu for example). It hasn't been detected as active.

Your application has now been installed. Go to the phone's menu, you'll see it's icon.

Production build and installation on a real cellphone

In order to release our application on the market, we must create a signature like we talked in the first part. For that, java offers us a command line tool to manage our keys. It's keytool.

This is how I've generated my own key :

keytool -genkey -v -keystore dmathieu.keystore -alias dmathieu -keyalg RSA -validity 10000

The parameters are the following :

  • -genkey - Tells that we must generate a pair of keys (private and public).
  • -v - Activated the full console render when generating the key.
  • -keystore dmathieu.keystore - The path to the keystore file which will be generated.
  • -storepass - The keystore's password. Don't transmit it that way. If you don't put anything here, it'll be asked when generating the key.
  • -alias dmathieu - An alias for the key. Only the first 8 characters will be taken into account.
  • -keyalg RSA - The key encryption algorithme. The available algorithms are RSA and DSA.
  • -dname - A name describing who has created the key.
  • -validity 10000 - The number of days the key will be valid.
  • -keypass - Your key's password. Don't put it here. It'll be asked.

When executing that command, a file dmathieu.keystore is created. It contains your key. Save it in a place where you're sure it won't be lost but it'll remain safe (I've personnaly stored it in my Google Docs account).

Now, open the file build.properties. In that file, we have to provide the path to your keystore and your key's alias.

key.store=/home/damien.projects/dmathieu.keystore
key.alias=dmathieu

We can now build our application for a release with the key we've just created. In the commande line, let's use to do to.

ant release

This does several things :

  • You application is built, like when doing an ant debug.
  • Your keystore is added to the application in order to authenticate it.
  • The package is optimized in order to speed it's installation.

Your project is now built and ready to be installed on your cellphone. It's available at the path bin/translator-release.apk. You only have to clip your cellphone in USB and install the application on it. You can also, of course, publish it on the Android Market.

Try it by yourself : go to the Android Market, search for the Translator application and install it. That's the application we've been programming in those two articles.

Conclusion

We have, in those two articles on Android, seen how to develop an application, test and install it on a phone. However we're very far from having seen everything in Android app development. We could, for example, add a widget. And many other things !

It's your turn to play now. What applications have you programmed after reading this article ?

Getting started in Android programming

For some weeks now, I've been having fun with java on android. In this article, we're gonna see the basics of android application programming with a sample test application : translator.

What this application does if very simple. You enter the input language, the output and the string you wish to translate. Using Google Translate, the application will translate that string.

Installing the SDK

In order to be able to easily test our application, we're gonna use the Android SDK, allowing us to simulate a cellphone on our computer.

You can download the SDK from the android's official documentation depending of your operating system.

Generate the project

Because we don't use Eclipse, we lose a lot of shortcuts provided by the IDE. But not using it is a choice. You can use the editor of your choice !

We're first gonna start a new project. Android offers a console command for this : android create project

android create project \
    -t <target_ID> \
    -n <your_project_name> \
    -p /path/to/your/project \
    -a <your_activity_name> \
    -k <your_package_namespace>

Several options are required.

  • -t target : It is the version of the android platform we're going to use (here, Android 2.1). To get a list of all the available platformes, you can use android list targets.
  • -name : The name you wish to give to your project.
  • -p path : The directory in which your project will be created.
  • -a activity : The name of the default window which will be opened when we'll launch the application.
  • -k package : The name of the package which will be created. It must follow the naming convention for packages in java.

Let's create our new project which we well name "Translator".

android create project \
    -t 1 \
    -n Main \
    -p ~/projects/translator \
    -a Translator \
    -k com.android.translator

Pure Java : translate a string with Google Translate

For this application, we're going to use an open source library allowing us to make calls to Google Translate : Google API Translate Java. You must include this library in the project we've just created. Download it on Google Code (the .jar file) and put in the folder /libs of your project.

 

We're gonna write an abstraction class for this library right now.

package com.android.translator;
import com.google.api.translate.Language;
import com.google.api.translate.Translate;

public class Translator {
    /*
     * Takes the string to translate and does the work
     */
    public static String translate(String text, Language lang_from, Language lang_to) throws Exception {
        Translate.setHttpReferrer("http//www.dmathieu.com");
        String translatedText = Translate.execute(text, lang_from, lang_to);
        return translatedText;
    }
}

What are we doing ?

package com.android.translator;
import com.google.api.translate.Language;
import com.google.api.translate.Translate;

We define the name of the current package and include the library previously downloaded, which will make the liaison with Google Translate.

Translate.setHttpReferrer("http//www.dmathieu.com");

The Google Translate API requires us to provide a referer, for statistic reasons. You can provide any uri you want here.

String translatedText = Translate.execute(text, lang_from, lang_to);

We get the translated string and we return it.

Then we call Translator.translate in order to translate one string from one language to an other.

Translator.translate("Hello World", Language.ENGLISH,  Language.FRENCH);

Create a Translator.java file in the folder src/com/android/translator and put this code in it.

And ... That's all for now. We're now going to see how to create the application's interface.

Create the Android interface

We're now going to create our application's interface, which will have two select boxes, one text field, one button and our translated string. Any application's interface is to be programmed in XML.

Here's what we have for the screen above, located in the file res/layout/main.xml

<?xml version="1.0" encoding="utf-8">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1">

    <Spinner 
        android:id="@+id/languages_from"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:prompt="@string/from_languages_prompt" />

    <Spinner 
        android:id="@+id/languages_to"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:prompt="@string/to_languages_prompt" />

    <EditText
        android:id="@+id/text_to_translate"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@android:drawable/editbox_background"
        android:prompt="@string/text_to_translate" />

    <Button
        android:id="@+id/translate_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:text="@string/translate_button" />

    <TextView
        android:id="@+id/translated_text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

What happens here ?

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1">
</LinearLayout>

We define the current window. LinearLayout allows us to define a window with all the elements which will be placed ones after the other.

There are several layout types allowing you to dispose the elements as you wich :

  • AbsoluteLayout : Allows you to place the elements by specifying their x/y coordinates.
  • FrameLayout : Allows you to place one and only one element. If there are several ones, only the last one will be displayed.
  • RelativeLayout : A layout in which everl elements are located one after the other.
  • TableLayout : A layout allowing you to place it's childs in lines or columns.

Then inside this layout, we have several elements.

<Spinner
    android:id="@+id/languages_from"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:prompt="@string/from_languages_prompt" />

The Spinner elements allows you to define a select box. Here, we have two ones. One for the input language and one for the output.

<EditText
    android:id="@+id/text_to_translate"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@android:drawable/editbox_background"
    android:prompt="@string/text_to_translate" />

The EditText element is a text field to be filled by the user.

<Button
    android:id="@+id/translate_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:text="@string/translate_button" />

In order to tell the application that we've finished typing the phrase and that we're ready to get it's translation, we add here a button.

<TextView
    android:id="@+id/translated_text"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />

Finally, we add a non editable text field which will contain the translated string.

Translation strings

When, later, we will execute the application we're currently programming, you'll be able to click on the spinner and select a language.

Then you'll the screenshot on the left. As you can see, we have a small phrase telling "pick a language to translate from".

This string is the attribute android:prompt of the spinner.

 
android:prompt="@string/from_languages_prompt"

We call here the I18n translations strings. Let's open res/values/strings.xml

Our file looks like this :

<?xml version="1.0" encoding="utf-8">
<resources>
    <string name="app_name">Translator</string>
    <string name="from_languages_prompt">Choose a language to translate from</string>
    <string name="to_languages_prompt">Choose a language to translate to</string>
    <string name="text_to_translate">The text you wish to translate</string>
    <string name="translate_button">Translate!</string>
</resources>

We put here all our strings and this will be their default translation (usually, english).

You can see than in main.xml, we're making calls to @strings/xxx. As you might have understood, @strings is the name of the file. You can create as many translation files as you wish.

If we wish to add a french translation to our application, we'll have to create res/values-fr/strings.xml Which will contain :

<?xml version="1.0" encoding="utf-8">
<resources>
    <string name="app_name">Translator</string>
    <string name="from_languages_prompt">Langue d'origine</string>
    <string name="to_languages_prompt">Langue de destination</string>
    <string name="text_to_translate">Texte à traduire</string>
    <string name="translate_button">Traduire !</string>
</resources>

It'll automatically get the appropriate translation depending of the phone's parameters.

Filling the spinners

Our spinner's content will be the list of all languages that Google Translate can translate from and to.

We will dynamically fill those spinners. The list is available in the library we're using.

Remember, when you've created your project, you've defined the name of an "Activity" class which is the default window. If you've followed this article to the letter, this activity should be named Main. So let's open src/com/android/translator/Main.java.

It contains an empty activity, allowing only to load the window.

package com.android.translator;
import android.app.Activity;
import android.os.Bundle;

public class HelloAndroid extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

The onCreate method is what we're interested in. It's called with a parameter savedInstanceState, which is the current state of the application. We start by calling this onCreate method in the parent class, allowing us to load the require environment by Android for the application.

setContentView(R.layout.main);

R.layout.main is an integer. Every element of your interface (the XML elements defined previously) are defined by Java as integers. You can find each of them with it. And as a constant with this integer is defined every time, you can find it even more easily. Here, R.layout.main is the layout/main.xml file. You can define which interface will be displayed by your activity.

As we'll have to add some content inside our two spinners, we must get their content. They're identified by integers too. In our spinner, we've defined an android:id attribute.

android:id="@+id/languages_from"

So we can get the id of our spinner in the constant R.id.languages_from.

Spinner language_from = (Spinner) findViewById(R.id.languages_from)
Spinner language_to = (Spinner) findViewById(R.id.languages_to)

Ok. Now, let's fill them.

In order to do that, we'll have to create an ArrayAdapter, which will be an array with strings. Every element will be an entry of the select box.

ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

We've created that adapter. Let's add our datas to it.

To add a new element to an adapter, we just need to use the add method.

adapter.add("Ma Valeur");

Here, all our values are located in the Google Translate library. We have to loop through all of them and add them.

for (Language l : Language.values()) {
    adapter.add(l.name());
}

Great ! One last thing however. Our adapter has been created but hasn't been assigned anywhere. We must assign it's values to our two spinners.

languages_from.setAdapter(adapter);
languages_to.setAdapter(adapter);

Which gives us, in fine, to get the content of our two spinners :

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    Spinner language_from = (Spinner) findViewById(R.id.languages_from)
    Spinner language_to = (Spinner) findViewById(R.id.languages_to)

    ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

    for (Language l : Language.values()) {
        adapter.add(l.name());
    }

    languages_from.setAdapter(adapter);
    languages_to.setAdapter(adapter);
}

Not too lost ? ;-)

The entire project for this application is available on github

Events : click on the button

Our application is starting to look well. However it's not usable yet. In order to do that, we must be able to click on the button.

We must create a listener on the button click. A function which will be executed at every click.

After the previous code, let's add our listener :

findViewById(R.id.translate_button).setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        String text = ((EditText) findViewById(R.id.text_to_translate)).getText().toString();

        try {
            Language lang_from = Translator.getLanguageString((Spinner) findViewById(R.id.languages_from));
            Language lang_to = Translator.getLanguageString((Spinner) findViewById(R.id.languages_to));

            String translatedText = Translator.translate(text, lang_from, lang_to);
            ((TextView) findViewById(R.id.translated_text)).setText(translatedText);
        } catch(Exception e) {
            ((TextView) findViewById(R.id.translated_text)).setText(e.toString());
        }
    }
});

What are we doing here ?

findViewById(R.id.translate_button)

We get the button element. Then we call, on this element, the setOnclickListener element. This method takes one OnClickListener element. It's a function which will be executed at every click on the button.

String text = ((EditText) findViewById(R.id.text_to_translate)).getText().toString();

Here, we get the text to translate.

try {
    // ****
} catch(Exception e) {
    ((TextView) findViewById(R.id.translated_text)).setText(e.toString());
}

If, for any reason, an error occured when trying to translate the content, we wish to display an error by ourselves and not see the application die.

So, if the internet connection isn't available, it's not possible to translate the string. An exception would be raised. With the try/catch, we intercept this exception and display it's content in the text field.

Language lang_from = Translator.getLanguageString((Spinner) findViewById(R.id.languages_from));
Language lang_to = Translator.getLanguageString((Spinner) findViewById(R.id.languages_to));

We get here the two selected languages. The Translator.getLanguageString must be defined in src/com/android/translator. It contains the following code :

public static Language getLanguageString(Spinner spinner) throws Exception {
    String lang = spinner.getSelectedItem().toString();

    for (Language l : Language.values()) {
        if (l.name() == lang) {
            return l;
        }
    }
    throw new Exception("Unknown language provided : " + lang);
}

With the getSelectedItem method, we get the selected language in the spinner. However the Google Translate library requires that we provide it a Language object. Not a string like we have in the spinner.

So we loop through all the available languages until find the one and return it. If no language is found, we raise an exception (which will be then managed by the try/catch seen earlier).

Let's continue in our action to click on the button.

String translatedText = Translator.translate(text, lang_from, lang_to);

Here, we call the Google Translate library to get the translated string.

((TextView) findViewById(R.id.translated_text)).setText(translatedText);

And finally, we put that string in the appropriate text field.

Conclusion

Sorry for the (too) long article. Our application is now developed. We just have to install it on the SDK to try it. Then on our telephone to use it. That is described in the article Deploy an Android Application

Build a real application with Node.js

We've seen in a previous article an introduction to node.js. However if you've read that article, you probably thought "what the heck will I do that ? My code won't be readable".

And I agree. That's not readable and it'll quickly become impossible to maintain on big applications.

Let's see how we can begin to solve that with connect and express.

Npm, rubygems but in javascript

In order to use the required libraries, we'll one of the node's packages managers, npm.

Installation is rather simple :

curl http://npmjs.org/install.sh | sudo sh
Depending of your installation of node (sudo or not), you might not need the sudo here.

Connect, rack but in javascript

Connect is the equivalent of rack for node. Applications can go around it as middlewares, allowing us to manipulate the application at any level.

Install Connect

Let's install Connect ! For that, we'll use npm.

npm install connect

And let's roll !

Use Connect

The standard Hello World of Connect, based from the documentation is the following :

var Connect = require('connect');
var server = Connect.createServer(function(req, res) {
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello World');
});

server.listen(3000);

We don't even manage the current uri (we'd need for that, to do a if. I don't advise for it). But we can quite easily sent text content. We've just created our first middleware.

Express, sinatra but in javascript

With ruby, Sinatra allows us to create small and lightweight applications easily. Express does just the same.

Install Express

Let's continue with npm.

npm install express

Who said computers are complicated ? ;)

Use Express

Right here, node becomes really interesting. With Express, we will finally start to create maintanables applications. Here's our Hello World with Express :

var app = express.createServer();
app.get('/', function(req, res){
    res.send('Hello World');
});
app.listen(3000);

We define a route on the / uri, which will give us the content "Hello World". Any other URI will give us a 404.

Of course we can define as many URIs as we want with the get/post/put/delete methods.

Template files

One problem remains : we define the content directly in the javascript. That's not cool and we'd want to have some templating.

By default, Express uses haml to manage the views. We'll create a views folder with two files :

layout.haml

That file will be automatically included as our application's layout. Add it your design.

!!!
%html
  %head
    %title Bonjour tout le monde (that's hello world in French)
  %body
    = body

index.haml

That's our index page's file.

%h1
  Hello World !

Then in our javascript file, let's replace the get method to display our index file.

app.get('/', function(req, res){
    res.render('index.haml');
});

Restart your server, reload the page and admire your beautiful template parsed in html and displayed !

Static files

Now we can display our templates as we wich, we only need to add a bit of style to the page. For that, we'll add a static CSS file.

Express manages them natively. Any file located in the directory we'll specify and which doesn't correspond to an already defined route will then be displayed. Let's configure it. Before the app.listen(300). aadd the following line :

app.use(express.staticProvider(__dirname + '/public'));

Then we tell Express to use the /public folder to display the static files. Create the file /public/style.css and include it in our layout :

%head
  %title Testing
  %link{rel: 'stylesheet', href: '/style.css' }

You just have to add some style to your CSS.

Conclusion

Because of it's relatively youth, node still evolves quite quickly. And Express is a proof of that. Several month ago, build a big application only with node was something we couldn't even think of.

Today, even if Express offers only a quite low layer, it already allows to program way better applications than with a raw node.

Node still has a lot of surprises for us. The three coming years will be very exciting there.

Getting started with Node

Unless you've been living in a cave for more than one year, you've probably heard about node.js. Node is a tool allowing you, in command line, to execute javascript applications. The applications will run with V8, the chrome engine.

So nod allows to build javascript applications. It's not a revolution which will make us stop programming in Ruby, Python or any other. It's only one technology more with it's advantages and problems.

Install Node

Node is only a command line tool. However some libraries are available. Let's start by downloading the project on github. Then open a command line and go to the node's folder.

./configure && make && make install

You now have node installed on your machine. You can execute any script with the following command :

node <filename.js>
Node isn't available on windows. You'll have to install a virtual machine and execute it in it.

How does it works ?

Let's write a simple application which will read and write a file.

var fs = require('fs');
var sys = require('sys');

fs.readFile('todolist.txt', function(list) {
    sys.puts("What I have to do today: " + list);
});

fs.writeFile('todolist.txt', "Write the introduction to ndoe.js");

Our script does two things. First it reads the file "todolist.txt" and displays it's content. Then it updates the file, giving it a task as content.

And on the web ?

If you've already heard about node until now, it's probably because of what it offers to program asynchronus applications, notably with WebSockets.

Let's take right now a very basic application :

var sys = require('sys');
var net = require('net');

Array.prototype.remove = function(e) {
    for (var i = 0; i < this.length; i++) {
        if (e == this[i]) { return this.splice(i, 1); }
    }
};

var clients = [];

function Client(socket) {
    this.socket = socket;
}


var server = net.createServer(function (socket) {
    var client = new Client(socket);
    clients.push(client);

    socket.addListener("connect", function () {
        clients.forEach(function(c) {
            c.socket.write("One people more ! We are now " + clients.length + " connected.\r\n");
        });
    });

    socket.addListener("data", function(data) {
       socket.write(data);
    });


    socket.addListener("end", function () {
        clients.remove(client);
        clients.forEach(function(c) {
            c.socket.write("We now are one less\n");
        });
        socket.end();
    });
});
server.listen(7000, "localhost");

What this application does is very simple. For every client which connects himself, it transmits a message to all the ones who already are and tells them there's a newcomer. It also tells how many persons there's now. And every time someone disconnects himself, it removes himself from the list.

You can try it yourself locally by opening the page in chrome and in firefox. Let's analyze this code in detail.

var sys = require('sys');
var net = require('net');

Here, we include the two libraries we'll use in our application. The sys library is the node core. You'll probably need it in all of your applications.

The net library allows us to start a server.

You can see the list of all the native libraries in the node's lib folder.

Array.prototype.remove = function(e) {
    for (var i = 0; i < this.length; i++) {
        if (e == this[i]) { return this.splice(i, 1); }
    }
};

Natively, javascript doesn't have any method to delete an element from an array unless we know it's position. So we add a javascript method to do that. We'll use it later.

var clients = [];

This is the node magic. It's single thread and it's not a bug ! So the clients array which we declare here will be available for all the persons using our application at the same time. Consequently, when we add an element in this array, this element is available for everybody.

This will allow to know, permanently, how many persons are connected to your application and to communicate with them.

function Client(socket) {
    this.socket = socket;
}

Every element in your array will be an instance of this Client object. The socket var is a pointer to the user's socket. So we will be able to transmit a new message to the user at any moment.

var server = net.createServer(function (socket) {
    ...
}
server.listen(7000, "localhost");

We are now at the server part by itself. We create here a server object which we will execute to listen on the port 7000 on localhost.

When a client connects himself, the anonymus function we create here will be called and the socket parameter will correspond to the pointer to the client's socket. Like that we can really interact with the users by detecting when he connects, disconnects and even when he transmits a message.

Here, we voluntarily use the "net" library because we don't specifically build an HTTP service. However there's an [http](http://nodejs.org/api.html#http-149) library which would be better for a website.
var client = new Client(socket);
clients.push(client);

The list of all the connected clients won't update itself automatically. Consequently we must update it when the user loads the application.

socket.addListener("connect", function () {
    clients.forEach(function(c) {
        c.socket.write("One people more ! We are now " + clients.length + " connected.\r\n");
    });
});

A client's socket can receive several listeners. It's a method which will be executed when a precise event happend. Here, it's the "connect" event.

In this event, we will loop through the clients array. And to every one of them we will send the message saying a new user just connected himself and how many we are now.

socket.addListener("data", function(data) {
   socket.write(data);
});

The user can transmis messages to the server. Here, we just display to that same client the messages he sends to us. So when you load the application, you'll be able to see on the page all the headers transmitted to the server.

socket.addListener("end", function () {
    clients.remove(client);
    clients.forEach(function(c) {
        c.socket.write("We now are one less\n");
    });
    socket.end();
});

Finally we add one last event : when the user closes his connection with the server (or because he times out), we delete that client from the array (we're using the "remove" method defined in javascript arrays previously).

Finally we inform all the remaining users that we are now one person less. And we close the socket in order to avoid any memory leak.

Conclusion

We've seen in that article a quick introduction to node.js. Many other features are however available. I highly invite you to take a look to the project's documentation for more informations.

Understand Ruby Symbols

You've probably already found some Ruby symbols, often used as hash keys. Example :

{:foo => 'bar'}

:foo is a symbol. 'bar' is a string. But we could do :

{'foo' => 'bar'}

So why use symbols ? Let's suppose the following case :

x = :sym
y = :sym
(x.__id__ == y.__id__ ) && ( :sym.__id__ == x.__id__)

This comparison will return true. One same symbol will always be the same object in memory in your whole application. But that's not a problem as symbols are not mutable.

And the same with strings :

x = "string"
y = "string"</p>

<p>(x.__id__ == y.__id__ ) || ( "string".__id__ == x.__id__)

Here, x, y and "string" are three different objects with different __id__. So 3 objects have been initialized in memory.

Now let's take again our first hash with the comparison string/symbol. With the symbols version :

{:foo => 'bar'}
{:foo => 'doe'}

We create 5 objects in memory : two hashes, a symbol and two strings.

With the strings version :

{'foo' => 'bar'}
{'foo' => 'doe'}

Here, we create 6 objects in memory : two hashes and 4 strings.

In an example case like this one it won't change anything. But in a real application context, if you replace all your symboles by strings, you'll need to increase the memory needed to run your application So whenever it's appropriate, stop using strings ans use symbols :)

Ruby console : ask for a password

When you get user information in console, you might, sometimes, need to get sensible information. Password for example. Which can't be displayed on the screen for security reasons. The library Ruby Password allows you to do that quite easily. However it implies you depend on this library. And that's something I don't wish. Particularly for something so simple.

The solution I'm suggesting here uses the linux features (not tested on windows. But who's still using it today ? :mrgreen: ).

begin
    print "Username: "
    username = $stdin.gets.chomp

    print "Password: "
    # We hide the entered characters before to ask for the password
    system "stty -echo"
    password = $stdin.gets.chomp
    system "stty echo"
rescue NoMethodError, Interrupt
    # When the process is exited, we display the characters again
    # And we exit
    system "stty echo"
    exit
end

What are we doing ? We start by asking the user's nickname.

print "Username: "
username = $stdin.gets.chomp
This is not a sensible data and can be displayed. Nothing specific to do.

Then we ask for a password. Here we must hide it.

print "Password: "
system "stty -echo"
password = $stdin.gets.chomp
system "stty echo"

The "stty -echo" will hide every character that should be displayed on the console. The "stty echo" displays them again.

Until there is works. Cool ! But somehowe we have a boring user, whom decides at the last moment to enter Ctrl-C to quit the program and finds himself in console with the -echo mode and doesn't see what he enters in. We've just lost a friend.

Fortunately we have exceptions notifications and we already detect an Interrupt to exit the program cleanly. Then we just have to display the characters again when there's this interrupt :)

begin
    # ...
rescue NoMethodError, Interrupt
    system "stty echo"
    exit
end

Hop ! :) And the project that uses this is glynn :)

Do you fetch or pull ?

I'm used to, when I want to update my local git repository with the distant one, to use git pull. It works well. Until ...

A few days ago, I wanted to release the version 1.0.0 of jesus. And to do so, I wanted to update the documentation. The principle is simple. I use GitHub Pages. So I need a branch "gh-pages", which content is what's online at GitHub for my documentation. Whenever I commit on that branch, the online page is updated.

However my two branches master and gh-pages doesn't have the same index. So they can't be merged ! So I did

git pull origin gh-pages:gh-pages
Thinking "I get the content of my documentation branch". And I see a dozen of conflict errors ! WTF as we should say.

And I should have done

git fetch origin gh-pages:gh-pages

The difference between those two commands apparently similar is huge. Git fetch only gets the datas. Git pull gets them and merges them with the current branch ... So when merging my two branches, as they don't have the same base, it's not cool.

Morality : you can git fetch when you want to update your local copy with the last distant commits. The branch on which you do the fetch will have the last commits. But your working branch won't be modified. If you do a pull, not only the branch where you do the fetch will have the last distant commits. But your working branch will also be merged with those last commits.

After a second thought, fetch seems highly more recommandable that pull, which can break a repository pretty easily.