Thursday, June 23, 2011

Managing Grid CRUD In ExtJS 4

I read a discussion on Sencha forum (here). Obviously, ExtJS 4 make user to be frustrating because of the lack of well organized document and lack of well commented sample code. Probably, it is just because ExtJS 4 is too new that developers have not catch up. However, since ExtJS is partially commercial product instead of a pure open source project, its quality should be well controlled before it announce final release. Here is a little bit experiece on how to make a CRUD grid with ExtJS 4.

To successfully use Grid, auto sync store, and rowediting plugin in ExtJS 4, there are several points need to be highlighted. I listed them as below,


  1. In your Model class, you have to either define a hardcoded 'id' property or use 'idProperty' to specify one column as 'id'.
  2. You server side code need to return processed records back to browser. I tried only send back "id" in "data" part. But, it is not successful.
  3. Be aware that the format of record in the "data" has JSON format.
  4. Be sure to implemented at least one Validator in your Model class because, in ExtJS source code AbstractStore.js, you can find the following code, which may always return true for a new created record in RowEditing plugin when the store is set as autoSync = true

/**
     * @private
     * Filter function for new records.
     */
    filterNew: function(item) {
        // only want phantom records that are valid
        return item.phantom === true && item.isValid();
    },

Most likely, we wont use auto sync store in real product. But, this example could be a good start.

Sunday, June 12, 2011

Web application i18n programming

How to do i18n programming is a big topic. I do not think I should try to describe it in a short blog post. I post this because I was asked with this question.

In my recent project, I created a JavaScript function as shown below,
/*
 * Translates $text
 */
function __i18n($text)
{
    //extend to each module has its own language file.
    // If we don't have the language set.
    if (undefined === Module.namespace.UI.lang) {
        return $text;
    }
    // If we don't have a translation for the $text.
    if (undefined === Module.namespace.UI.lang[$text]) {
        return $text;
    }
    return Module.namespace.UI.lang[$text];
}
The above simple JavaScript code is used to translate text into another UTF-8 encoded text, which is most likely written in another language. BTW, one thing I want to emphasize is that UTF-8 and unicode are different stuff. I often heard people just use them as if they were exchangeable.

Above sample is just small part in the whole i18n enabled system. We can use a traditional three-tie Web application as sample (traditional desktop app has different concern, I believe). Let's assume that we have just one centralized Web server. That is, we do not consider the situation in which we have distributed Web server located in different host server and those server have different system locale settings. We will have concern about i18 in each layers including presentation layer, business logical layer, and database layer. Let's have a brief review on each layer as below,

  1. Presentation layer. First of all, let's know what is involved in this layer. Obviously, JavaScript, HTML is involved in this layer. But, we should not forgot that Web browser and Web server are included as well.
    In HTML, we can specify language info not only in HTML page wide, but also in each FORM scope.
    In JavaScript, as we see in the sample code, a language resource file can be well designed and used.
    In CSS, we probably need to create seperated CSS files for different locale as different language may have different text width.
    About Web browser and Web server, some people just ignore this part. But, in fact, in HTTP header specification, some field like Accept-Encoding, Accept-Language has been defined for your convenience. But, using this feature also cause potential problem if end user happens to change their browser settings.
  2. Business layer. Most of talking about resource bundle, locale object happens in this layer. According to my experience in Java, we only need to keep in mind that the internal encode used in JVM is UTF-8. That is, we need a base line. Then, from there, we convert to any encoded schema if the specific language is installed on the system.In terms of programming, coder need to be carefully to avoid use functions which only support ASCII characters. In language like PHP, C/C++, you can always find there are two set of string functions, one is only for ASCII characters. The other is used for "wider" unicode characters.
  3. Persistent storage layer. Using MySQL RDBMS as an example, database designer can specify storage schema and transmission schema for database or table. I always use UTF-8 so far. Of course, you can still support multilingual if you treat all string as just binary array.

A well designed i18n architecture is very important to a world wide used software as it may cause painful redesign and recoding effort later if it is not well designed at the very beginning. Also, it will be helpful to understand i18n programming by starting to learn i18n from a specific language. For example, IBM instead of Sun Microsystem contributes i18n into Core Java from the beginning. It will be good to use Java language to learn i18n.

Wednesday, June 8, 2011

how to convert TIMESTAMP format to different date format

It is very often that we need to get specific format of date from TIMESTAMP column. We can certainly get timestamp as string and do some string operation on it to compose a new string with desired formated. However, it will be just nice to be able to get what I want directly from SQL query output. Here is a brief conclusion on how to get formated Date string from TIMESTAMP.

Basically, two DB2 functions are used. DATE scalar function and CHAR scalar function. In CHAR function, we can specify five different format: iso, usa, eur, jis, local.

Below is sample output for different format,

SELECT CURRENT_TIMESTAMP, char(date(CURRENT_TIMESTAMP), eur) 
  FROM SYSIBM.SYSDUMMY1; 
Output EUR format: 
2011-05-28 15:36:12.178455 28.05.2011

SELECT CURRENT_TIMESTAMP, char(date(CURRENT_TIMESTAMP), usa) 
  FROM SYSIBM.SYSDUMMY1; 
Output USA format: 
2011-05-28 15:38:57.487165 05/28/2011

SELECT CURRENT_TIMESTAMP, char(date(CURRENT_TIMESTAMP), jis) 
  FROM SYSIBM.SYSDUMMY1; 
Output JIS format: 
2011-05-28 15:40:00.455681 2011-05-28

SELECT CURRENT_TIMESTAMP, char(date(CURRENT_TIMESTAMP), iso) 
  FROM SYSIBM.SYSDUMMY1; 
Output ISO format: 
2011-05-28 15:41:12.159374 2011-05-28


SELECT CURRENT_TIMESTAMP, 
char(date (CURRENT_TIMESTAMP), local)
  FROM SYSIBM.SYSDUMMY1; 
Output LOCAL format: 
2011-05-28 15:42:41.802835 05/28/11