Wednesday, June 18, 2008

Edujini Labs' Series on OOPS in JavaScript

Edujini Labs' Eduzine has been running a series of articles on "Exploring OOPS in JavaScript". A must read.

  1. Part 1: Encapsulation
  2. Part 2: Inheritance
  3. Part 3: Polymorphism

Tuesday, June 10, 2008

Flex Data Driven Controls - Part 2

Introduction

In Part 2 of the series of articles on "Flex Data Driven Controls", we learn about how to provide custom rendering to a data bound control. And we choose List.

In the previous article, Part 1 of the series, we got ourselves started with data driven controls - ComboBox and DataGrid. In this article, we will lean to cutomize the how the items are finally presented to the end user.

The source code for this article is available in the Downloads area.

Getting Started

We reuse the previous definition of UserProfile. For completeness, the definition below is re-represented below:

package com.edujinilabs.eduzine.tutorials.flex.core
{
  /**
   * Part of the Eduzine (http://eduzine.edujini-labs.com) Articles.
   *
   * Downloads available at http://downloads.edujini-labs.com
   *
   * (C) 2008, Edujini Labs Pvt Ltd
   * http://www.edujini-labs.com
   */
  public class UserProfile
  {
    private var _employeeID : int;
    private var _employeeName: String;
    private var _departmentName: String;

    public function UserProfile(eid: int = 0, name: String = null, deptName: String = null)
    {
      this._employeeID = eid;
      this._employeeName = name;
      this._departmentName = deptName;
    }

    public function get employeeID(): int
    {
      return _employeeID;
    }

    public function set employeeID(eid: int) : void
    {
      this._employeeID = eid;
    }

    public function get employeeName(): String
    {
      return _employeeName;
    }

    public function set employeeName(name: String) : void
    {
      this._employeeName = name;
    }

    public function get departmentName(): String
    {
      return _departmentName;
    }

    public function set departmentName(name: String) : void
    {
      this._departmentName = name;
    }
  }
}

As far the user interface is concerned, we replace the ComboBox with List and remove DataGrid from the previous MXML definition. There would be a need to customize the layout a bit. The final definition looks as follows (important changes have been marked in bold):

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
  height="426" width="400" borderThickness="2" borderStyle="solid"
  backgroundColor="#F0F0F0" cornerRadius="8">

  <mx:Label text="Edujini™ Labs Pvt Ltd" fontSize="14" fontFamily="Georgia"
   fontWeight="bold" fontStyle="normal" color="#F5A83B" left="20" top="20"/>

  <mx:Label x="20" y="64" text="Edujini Team" fontFamily="Verdana" fontSize="10" fontWeight="bold"/>

  <mx:List id='eList' x="20" y="90" dataProvider="{employees}" labelField="employeeName"
   cornerRadius="4" width="344" height="265">
  </mx:List>

  <mx:Label x="20" text="© 2008, Edujini™ Labs Pvt Ltd" fontFamily="Verdana"
   fontSize="10" fontWeight="bold" bottom="20"/>

  <mx:Script>
    <![CDATA[
      import com.edujinilabs.eduzine.tutorials.flex.core.UserProfile;
      import mx.collections.ArrayCollection;

      [Bindable]
      private var employees: ArrayCollection = new ArrayCollection(
      [
        new UserProfile(11, "Shake Sajan", "Product Dev"),
        new UserProfile(24, "Meera", "Training"),
        new UserProfile(23, "Neelam", "Training"),
        new UserProfile(12, "Hari S Nair", "Product Dev"),
        new UserProfile(13, "Abdul Prodhani", "Product Dev"),
        new UserProfile(21, "Ashish Vaish", "Training"),
        new UserProfile(10, "Gaurav Vaish", "Technology"),
        new UserProfile(32, "Jagadish", "Marketing"),
        new UserProfile(33, "Anshu", "Marketing"),
        new UserProfile(22, "Padma Raviee", "Training"),
        new UserProfile(14, "Rajesh", "Technology"),
        new UserProfile(31, "Yashwanth C", "Management"),
        new UserProfile(34, "Ramesh", "Finance")
      ]);
    ]]>
  </mx:Script>
</mx:Application>

With this, the UI that we expect is as follows:

Eduzine - Flex List - Renderer - Initial UI

Flex Item Renderers

This interface is decently fine. Let's get something more out of this. How about change the UI to not only display the employees' names but also their Employee ID and the Department Name. And showing them a little formatted - say, in two lines rather than in a single line.

Adobe Flex data driven controls work internally with the so called item renderers to represent a "list of items". The external presentation may be linear, grid, tree or a combination of these.

To get started, let us define a simple renderer for our List. Modify the List definition to as follows:

  <mx:List id='eList' x="20" y="90" dataProvider="{employees}" labelField="employeeName"
    cornerRadius="4" width="344" height="265">
    <mx:itemRenderer>
      <mx:Component>
        <mx:VBox>
          <mx:Label text="ID: {data.employeeID}" />
          <mx:HBox width="100%">
            <mx:Label text="Name: {data.employeeName}" width="50%" />
            <mx:Label text="Department: {data.departmentName}" width="50%" />
          </mx:HBox>
        </mx:VBox>
      </mx:Component>
    </mx:itemRenderer>
  </mx:List>

The itemRenderer comprises of one VBox with two entries - a Label to display the Employee ID, and a HBox comprising of details for Employee Name and the Department Name.

Note that the itemRenderer element can contain only a definition of the Component which in turn can comprise of only one component. For example, it is not possible to have a Component with two Label elements directly within itself. These Labels must be enclosed in a container layout, like VBox in this case.

Also note that the controls are bount to values of the type {data.*}. data is a special variable in this case - it refers to the item being rendered. For each iteration corresponding to the entry in the dataProvider, data takes up the corresponding value. The type of the value referred to by data is same as that in the dataProvider, which in our case is com.edujinilabs.eduzine.tutorials.flex.core.UserProfile.

The UI expected is as below:

Eduzine - Flex List - Custom Rendered Definition

Flex Item Editors

Let's further fancy the UI and give the HR department an ease to be able to edit the details inline. When the HR personnel clicks on any entry, it should get into the edit mode and display the items as below:

  • Employee ID: Must be shown in a Label.
  • Employee Name: Must be shown in a TextInput, so that it may be updated.
  • Employee ID: Must be shown as a ComboBox, with a list of options available.

Now that we already know how to data-bind the controls, we can directly jump on to looking at the updated List definition in the MXML:

  <mx:List id='eList' x="20" y="90" dataProvider="{employees}" labelField="employeeName"
    cornerRadius="4" width="344" height="265" editable="true" itemEditEnd="event.preventDefault()">
    <mx:itemRenderer>
      <mx:Component>
        <mx:VBox>
          <mx:Label text="ID: {data.employeeID}" />
          <mx:HBox width="100%">
            <mx:Label text="Name: {data.employeeName}" width="50%" />
            <mx:Label text="Department: {data.departmentName}" width="50%" />
          </mx:HBox>
        </mx:VBox>
      </mx:Component>
    </mx:itemRenderer>
    <mx:itemEditor>
      <mx:Component>
        <mx:VBox>
          <mx:Label text="ID: {data.employeeID}" />
          <mx:HBox width="100%">
            <mx:TextInput text="{data.employeeName}" width="50%" />
            <mx:ComboBox width="50%" selectedItem="{data.departmentName}">
              <mx:dataProvider>
                <mx:String>Product Dev</mx:String>
                <mx:String>Training</mx:String>
                <mx:String>Technology</mx:String>
                <mx:String>Finance</mx:String>
                <mx:String>Management</mx:String>
              </mx:dataProvider>
            </mx:ComboBox>
          </mx:HBox>
        </mx:VBox>
      </mx:Component>
    </mx:itemEditor>
  </mx:List>

The updates in the code, now, must be self explanatory. You would also notice alternate form of specifying the dataProvider for the ComboBox. If you select any entry in the list, it must get into the edit-mode. The expected UI is as given below:

Eduzine - Flex List - Custom Item Editor Definition

So, we seem to have got everything... except that the names / department names, if updated, do not effect the original items (the model). We shall explore this in our next article.

Summary

In this article, we learnt to:

  1. Use Flex Item Renderers in data driven controls to create a rich UI to render the business objects.
  2. Use Flex Item Editors to edit the business objects. We have left the task of updating the business objects to the next article.

Monday, June 9, 2008

Flex Data Driven Controls - Part 1

Introduction

Data driven controls are key to any UI toolkit, and Flex is no different.

In this article, we explore some data driven controls in Flex and look at their basic functionalities, especially the data binding and custom rendering.

In case you need a professional support on RIA, Web 2.0 and/or Flex, feel free to mail

Downloads are available in the Downloads section.

The Scenario

Let's take a fictitious but practical scenario. The HR department at Edujini Labs to be given a dashboard to:

  • Display employee names
  • Dispaly employee details
Other complexities like capabilities to edit the employee details, paginate the listing if the list is long et al can be added later on.

Getting Started...

To get started, let's freeze on the following UI:

  • For the employee list, we use a simple ComboBox to get started with. Later we'd explore other options
  • For the details, we use DataGrid.

flex - datagrid/combobox - Edujini Labs HR Department UI

The above UI can be generated using the following application definition:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
  height="280" width="600" borderThickness="2" borderStyle="solid"
  backgroundColor="#F0F0F0" cornerRadius="8">

  <mx:Label text="Edujini™ Labs Pvt Ltd" fontSize="14"
      fontFamily="Georgia" fontWeight="bold" fontStyle="normal"
      color="#F5A83B" left="20" top="20"/>

  <mx:Label x="21" y="64" text="Edujini Team" fontFamily="Verdana"
      fontSize="10" fontWeight="bold"/>

  <mx:ComboBox x="21" y="90"></mx:ComboBox>

  <mx:DataGrid x="218" y="92" width="368">
    <mx:columns>
      <mx:DataGridColumn headerText="Employee ID" dataField="employeeID"/>
      <mx:DataGridColumn headerText="Employee Name" dataField="employeeName"/>
      <mx:DataGridColumn headerText="Department" dataField="departmentName"/>
    </mx:columns>
  </mx:DataGrid>

  <mx:Label x="21" y="248" text="© 2008, Edujini™ Labs Pvt Ltd"
      ontFamily="Verdana" fontSize="10" fontWeight="bold"/>

</mx:Application>

Note the definition of the DataGrid. It contains a bunch of DataGridColumn definitions. Each DataGridColumn has been specified a headerText - header of the column, and dataField - the property of the object whose value is to be displayed.

To model our data, let's create a class UserProfile in package, say, com.edujinilabs.eduzine.tutorials.flex.core. It comprises of the Employee ID, Employee Name and the Department Name.

package com.edujinilabs.eduzine.tutorials.flex.core
{
  /**
   * Part of the Eduzine (http://eduzine.edujini-labs.com) Articles.
   * Downloads available at http://downloads.edujini-labs.com
   *
   * (C) 2008, Edujini Labs Pvt Ltd
   * http://www.edujini-labs.com
   */
  public class UserProfile
  {
    private var _employeeID : int;
    private var _employeeName: String;
    private var _departmentName: String;

    public function UserProfile(eid: int = 0,
                           name: String = null, deptName: String = null)
    {
      this._employeeID = eid;
      this._employeeName = name;
      this._departmentName = deptName;
    }

    public function get employeeID(): int
    {
      return _employeeID;
    }

    public function set employeeID(eid: int) : void
    {
      this._employeeID = eid;
    }

    public function get employeeName(): String
    {
      return _employeeName;
    }

    public function set employeeName(name: String) : void
    {
      this._employeeName = name;
    }

    public function get departmentName(): String
    {
      return _departmentName;
    }

    public function set departmentName(name: String) : void
    {
      this._departmentName = name;
    }
  }
}

Notice that the property names have been purposely chosen to match the values of dataField of the DataGridColumn's defined earlier.

Data Model

Employee list would be represented using the variable employees of type mx.collections.ArrayCollection. Ensure that it is Bindable. Finally, let's popupate it with some data, as given below. Add the code directly into the MXML Application created.

  <mx:Script>
    <![CDATA[
      import com.edujinilabs.eduzine.tutorials.flex.core.UserProfile;
      import mx.collections.ArrayCollection;

      [Bindable]
      private var employees: ArrayCollection = new ArrayCollection(
      [
        new UserProfile(11, "Shake Sajan", "Product Dev"),
        new UserProfile(24, "Meera", "Training"),
        new UserProfile(23, "Neelam", "Training"),
        new UserProfile(12, "Hari S Nair", "Product Dev"),
        new UserProfile(13, "Abdul Prodhani", "Product Dev"),
        new UserProfile(21, "Ashish Vaish", "Training"),
        new UserProfile(10, "Gaurav Vaish", "Technology"),
        new UserProfile(32, "Jagadish", "Marketing"),
        new UserProfile(33, "Anshu", "Marketing"),
        new UserProfile(22, "Padma Raviee", "Training"),
        new UserProfile(14, "Rajesh", "Technology"),
        new UserProfile(31, "Yashwanth C", "Management"),
        new UserProfile(34, "Ramesh", "Finance")
      ]);
    ]]>
  </mx:Script>

Data Binding

The next step is to bind the employee list to ComboBox and the DataGrid. Update the definition to as following:

<mx:ComboBox x="21" y="90" dataProvider="{employees}"></mx:ComboBox>
<mx:DataGrid x="230" y="92" width="302" dataProvider="{employees}">

Note the special syntax - the variable employees has been enclosed in the curly-braces {}. This the data-binding syntax. It is a two step process:

  1. Declare a variable with the attribute Bindable.
  2. In MXML, use it within the curly braces.

After binding, the UI should appear as given below:

Eduzine - Edujini Labs Employees - Data Binding Flex - UI

ComboBox Configuration

Everything looks fine except for that the ComboBox does not exactly display what we require. It displays the String representation of the UserProfile using the toString() method.

All we need to configure is the labelField of the ComboBox to tell it that it must pickup the text to be displayed to the UI from the corresponding property / field of the individual object of the collection. The default value of labelField is label.

Update the definition of the ComboBox used to as follows:

  <mx:ComboBox x="21" y="90" dataProvider="{employees}"
       labelField="employeeName">
  </mx:ComboBox>

Voila! The UI is exactly as what we want:

Flex ComboBox Data Binding with custom LabelField

Summary

In this article, we learnt to:

  1. Use data binding.
  2. Bind data to ComboBox and DataGrid.
  3. Display custom objects in a ComboBox.
  4. Display custom objects in a DataGrid in multiple columns.

Sunday, June 1, 2008

DWT on Google Web Toolkit

Edujini Labs announces integration of Dojo on Google Web Toolkit.

I think it's a great idea. I happened to have come across two projects on Google Code - Tatami and GWT-Dojo.

  • GWT-Dojo: A project that seems to never have started.
  • Tatami: Seems that quite some amount of work has been done but again, not much work seems to be done in recent past and also the progress does not seem to be on track.
    My query on Roadmap of Tatami is unanswered yet. So, I am not quite sure if they're really wanting the project to take off.

Here's the video of the "Hello, World!".

Since I am personally involved in the DWT (Dojo on Google Web Toolkit), I would be happy to report its progress so far. Besides a simple "Hello, World" application, a lot of background work has been done to talk to the native Dojo API calls.

Besides, I today outlined the life-cycle of Widget (dijit._Widget) and templated widgets (dijit._Templated).

The next steps, that I would be working on during next week (require more time because we have higher priority schedule already chalked in), is to outline the life-cycle of Container and Contained widgets.

Subsequently, we need to chalk out clear strategy on what would be written in Java and what would be passed on natively.

That's the update so far...

Thursday, May 22, 2008

Windows Image Acquisition and Windows Portable Devices

I had been working with WIA (for Windows XP) and WIA 2.0 (for Windows Vista) to design an application to capture images.

WIA for Windows XP works perfectly fine. And WIA 2.0 is supposed to do the same on Vista.

And then, I hit a hurdle - WIA 2.0 always gives me "0 devices" while using EnumDevices method. Finally, I hit yet another set of documents - Windows Portable Devices (WPD) here.

What the heck! Do I need to rewrite the entire application for Windows Vista? What does Microsoft want? Spend all time and money only to rewrite entire code every time a new version is released from their side?

At times, I really hate to develop any application on Windows.

The only good thing, at least at moment as it seems, is .Net Framework. At least, there I need to do minimal work. I wish it was the same case elsewhere also.