Migrating web applications from Ext JS 3.0 to 3.3

Ext JS is a good framework to build complex web UIs in JavaScript, because it provides many useful widgets. There’s always a dark side, anyway: in our case, when we started writing PhpReport 2.0, we had to rely on some undocumented features taken out from examples to get some things done.

Unfortunately, as new versions are released, some of these ‘features’ change their behaviour, or just disappear; maybe because they actually were side effects, or they were WIP. And moving to a newer version of the framework became an unexpected problem.

We started PhpReport 2.0 using Ext JS version 3.0, upgrading util 3.0.3. Then we found out that the jump to the next major version required more than downloading a new tgz, so we left it on hold, until some weeks ago, when I decided to get the latest Ext JS (3.3.1 right now) and put some effort debugging the problems caused by the migration. I share here with you the challenges I found.

XmlWriter and tpl attribute

This attribute is used to specify the conversion between the Store object with the data and the XML that has to be output, for example, to a REST service. To iterate over the fields of a record, we used this template: <tpl for="fields">. Now, that element isn’t called ‘fields’ anymore, and you should use <tpl for="."> to iterate over the fields of a record.

Null values on records

In Ext 3.0.3, Ext.data.Field objects didn’t have the useNull configuration option. It was introduced later, and its default value is false. This caused that some non compulsory fields stored a 0 when the user wanted them to be empty. The solution is simple: adding useNull: true to those fields when defining the corresponding Record.

Columns with empty ids on grids

When you used a empty string as the id of a column in 3.0.3, the grid showed a column with an empty label, and those records of the Store with an empty field name were rendered in that column. But that no longer works in 3.3.1, where every column has to have its id.

Changes in the behaviour of ref property

ref is a path specification, which allows us to place a named reference to a component in one of is owner containers. It seems there were some changes in the implementation of this attribute in Ext 3.1. Look at this example:

Ext.onReady(function(){
    var g = new Ext.grid.GridPanel({
        renderTo: document.body,
        store: [1],
        columns: [{
            header: 'col'
        }],
        tbar: new Ext.Toolbar({
            items:[{
                text: 'Foo',
                ref: '../deleteBtn'
            }]
        }),
    });

    new Ext.Button({
        text: 'Click',
        renderTo: document.body,
        handler: function(){
            console.log(g.deleteBtn);
        }
    });
});

It worked flawlessly in 3.0.3. When clicking on the button, the system writes g.deleteBtn in the JavaScript console. deleteBtn is not a direct child of g, but we achieved this direct access using ref.

After the migration, something ‘under the hood’ made this code broke, but taking a look at it, the only questionable thing is the definition of the toolbar, which can be simplified. After some experiments, I found out that the problem was fixed changing that definition:

        tbar: [{
            text: 'Foo',
            ref: '../deleteBtn'
        }]

Now ref works correctly again. Not sure about what happened, but it seems that the redundant definition of the toolbar now has this undesired side effect.

So…

It was an unexpected effort, but I’m happy with the results. I was waiting to get some annoying cross-browser bugs solved, for example, those huge calendars in WebKit-based browsers. I have the migrated code of PhpReport in a separate branch called migration-to-ext-3.3.1, and we are testing it heavily right now, before merging into master.

New Year’s Resolution: releases for PhpReport

If you take a look to the repository history, you’ll notice that PhpReport is active, receiving patches to fix bugs and even some new features:

  • Custom templates for the most common tasks.
  • Filter for projects in project evaluation page.
  • A visual revamp, to make it look a bit prettier 😉

Tasks screen

But there is something that has been in my TODO list for too much time: simplify the installation process and start releasing the application periodically in tarballs. That will be my New Year’s Resolution 🙂 .

And by the way, Happy Holidays! 😀

PhpReport meets NavalPlan

I haven’t posted about that, but I’m also involved in the development of NavalPlan, a production management application with features to schedule projects and follow their advance graphically, controlling the costs and deviations. I have to say its dynamic Gantt diagrams are quite impressive for a web application 😉 .

NavalPlan has a work report system to store the information about the hours devoted by the employees to every task scheduled, and also provides web services to import and export those data, so it felt natural to connect PhpReport, our time tracking tool, with NavalPlan, to share the dedication data.

I’ve started writing a plugin for PhpReport to be executed right after creating a task, with the purpose of sending that task to NavalPlan using its web services. Right now it’s functional, but lacks extensive error checking. I still have to write similar plugins for the update and delete operations.

Check out the code from the remote branch navalplan-plugins in PhpReport repository:

git clone https://github.com/Igalia/phpreport.git
git checkout origin/navalplan-plugins

This is how it looks, so far 😉 :

Tasks in PhpReport

The same tasks, imported into NavalPlan as a work report