Ext.extend and Conquer

Today it was a very productive day.

I’ve redesigned several problematic screens of an application into more functional versions, working much faster, providing more information to the end user and – the best thing – with a very consistent appearance on their layout.

ExtJS provides some nice features to standardize its components by extending its standard classes.

The simplest way to do that is like what I show on the code snippet below. It simply provides some default values – that can be easily overriden when the custom component is instantiated – that help with the implementation of sets of components.

var myCustomCombo = new Ext.extend(
    Ext.form.ComboBox,
    {
        width: 180,
        mode: "local", // I load the data manually from the store.
        triggerAction: "all",
        emptyText: 'Choose an option...',
        autoSelect: false,
      editable: false
    }
);
Ext.reg('mycustomcombo', myCustomCombo);

I did custom implementations of panels, forms, combo boxes and grids. With that, I make only slightly variations from one case to the other – imagine addresses, where you have several different components from the country up to the zip code for a street, avenue, square, etc.

The new layout also made it possible to eliminate different pages and consolidate all the information on a single page where all records could be browsed, edited, removed or new records could be added to the database.

On the backend – my TurboGears application – my code also shrunk considerably as I didn’t have to make some convoluted queries to get the information. All modules were better decoupled and obtaining the information using AJAX – or better AJAJ since I don’t use XML but use JSON – much easier through a cleaner interface.

Summing up: it was a complete redesign of a whole module in a day. Some hundreds of lines of code eliminated and functionality added to the system.

I hope that tomorrow the day becomes as productive as today.

An AJAX option to remember

I always forget how useful is the “$(<selector>).load(‘url’, {para: meter});” function on jQuery.

It is really a problem solver when loading HTML structures.  I am converting some old code where I got HTML fragments to replace some existing content on the page and using the usual process, I’d have to do the AJAX query, call a callback procedure and then there I’d replace the contents of the section / div / whatever I wanted.

With jQuery.load I can do that on a single call and in a more effective way.

Silly thing and so simple that I always keep forgetting about it.

Starting a mercurial (hg) remote repository

I always forget and have to search for the correct order of things here…

There are some VCS — as in Version Control System — (and DVCS, where the “D” stands for Distributed) where you can create a copy of the repository on your own system and then somewhat easily move it to the server or copy it there using the VCS software itself.

Mercurial seems to require that the thing be done in two stages:

  1. Create the repository on the central (reference) server
  2. Clone the repository on each workstation

So, here are the commands that should be run to accomplish that:

At the reference server

hg init <repository_name>

At the workstation

hg clone ssh://user@server//path/to/repository/<repository_name> <local_name>

Yes, it is that simple…  But since I work for a long time on projects, I always forget to double the slash after the server name while cloning and that I need to create the repository on the server “first”, to later start working with it locally.

I could probably do the opposite and revert the clone order, but then I am not sure if “push” and “pull” would be switched or if something else would be required to make them work.

KDE 4.2 on OpenSuSE 11.0

Continuing with updates from Factory, I’m now using KDE 4.2.

Several things have improved, the interface is as clean as 4.1’s was and I feel that some things take less resources.

It is worth a change for anyone running KDE 4.x to update to KDE 4.2.  But be aware that some configurations might be lost, so backup your settings before the change, just in case. 🙂

On what to do prior to contact another company’s tech support

I work for a company that does off shore for other companies from the same group.  There are two types of activities that are done worldwide (100+ countries): internal support and support to external business partners (mostly clients, some suppliers, etc.).

As I work with networks and data transmission, and I lead a team that interfaces with external business partners almost 100% of the time, it is common to get some support requests for problems that really aren’t our problems.

It is something that is annoying because when there is a problem — specially in production environment — we need to stop working on everything else and solve that.  Out of those, 99.999% of the times the problem isn’t on our end: we work with thousands of business partners and have the structure in place to work with them: servers, network, firewalls, etc.  Everything is working fine, debugged and stable — there are some destabilizing changes from time to time, of course, but those are rare and very well tested.  Then, there comes the question from the external business partner: “We can’t connect to your server.  What did you change?  We need to submit that data today!”

Last time this happened, I had a meeting with an Indian company from 1:30 AM to 3 AM here…  And what was the issue?  They could manually submit data, but their automation couldn’t.

Anyone that can solve a hard problem — such as adding 2+2 — can see that there is something wrong with that and that something is probably at their end…  But no, this didn’t happen.  So, we scheduled a meeting and after one hour asking questions and asking about changes, they said that they changed the server: manual process (working) was from one host, automated process from another.  When asked to manually test from the new host, it didn’t work as well.  The problem?  They changed from one server to another and didn’t update their own firewall policies…  And then, it is our fault… 🙂

Second time there even was a paging sent to our team: data corrupted.  Oh well, the customer had to fix it and not us as we don’t change data in any way.  Even within our own company, business first assumes it is our fault and then we have to insist to have them go to the customer.

Now, back to the subject:

  1. Make a change procedure, schedule times, analyze impact, etc.
  2. Keep a backup of all of your changes.  Never demise the server after the change, you might need something from it back or reverting back to the old server in case something goes wrong
  3. Check everything that has to be changed (servers, configurations, user profiles, firewalls, IP addresses, etc.)
  4. Have a “recent changes” log and don’t assume that one change is irrelevant, specially when talking to other companies trying to solve a problem
  5. Check your company first: go to your IT team or contractor, ask what has been changed, why it worked before and what is exactly the problem you’re having
  6. If it is a connectivity problem, check that you can connect to other sites that provide a similar service / interface, check that you can get out of your network to the Internet from the same host that will be used and that is presenting the failure
  7. Supply the support team a traceroute / tracert output from the failing host to their server

Give the support team from both companies enough information to solve your problem.  Guessing is too time consuming, error prone and isn’t something specialists like doing without enough information to discard the most obvious problems first.

“Help us to help you”, I always say (no, I didn’t create this expression, but I really enjoyed it!).

Changes @ Work

Lots of things happening lately.

Several big projects that required a lot of attention, a new team has been assigned to me — so now I’m leading my old team and the new one — and I have a third team to put together…

Besides all that, there’s the marriage that is closer: April 18th, 2009.  🙂

I hope to be able to post more, though…

Quick trick with tables: fixing column width

It is interesting how we never get bored while creating different solutions.

I’m improving the design of an application — and I guess if I am improving it then it was really ugly before… — and needed to add a column that will be larger than the other ones.  Unfortunately, unless you have your data displayed already then all columns will be shown with the same width.

How to solve that?  Using an old trick!

First of all, you define — using colspans, if possible — what is the proportion of the expanded column.

After that, you just specify that such a table should be rendered with a fixed layout in your CSS:

table-layout: fixed;

This will do the trick and render the table the correct way.

Creating namespaces for your code

As part of the migration I mentioned earlier, I adopted one of the many recipes available on the Internet to start creating a namespace for my common code as well as exclusive namespaces for each project I’m delivering.

The idea is to minimize how much code is available globally as well as to prevent name collisions.  It also allows me to isolate my code from some JavaScript frameworks (as I said, I’m still migrating code, so I have both MochiKit and jQuery loaded) or all of them.

if (typeof MainNamespace == "undefined") {
    var MainNamespace = {};
}

MainNamespace.namespace = function () {
    var a=arguments, o=null, i, j, d;
    for (i=0; i<a.length; i=i+1) {
        d=a[i].split(".");
        o=window;
        for (j=0; j<d.length; j=j+1) {
            o[d[j]]=o[d[j]] || {};
            o=o[d[j]];
        }
    }
    return o;
};
;

The above code is available on a file by itself and its only purpose is to initialize the main namespace for my own code.  Since it allows me to create any namespace, I don’t need to replicate that on individual projects.

To use the above, my code looks like this:

(function($) {
  MainNamespace.namespace('NewNamespace.common');
  NewNamespace.common = {
    __name__: "NewNamespace.common",
    __version__: "1.0",

    myFunctionOne: function() {
        // code
    },

    myFunctionTwo: function() {
        // code
    }
})(jQuery);

This is also an implementation of the Module Pattern, from Douglas Crockford (or is it more from Dustin Diaz?) as explained by Eric Miraglia, from YUI.  I believe this comes from Crockford, due to his prior work on this area, but the discussion on Diaz’ blog is really full of useful information.

After showing this, some recommendations:

  1. Use UPPERCASE for your MainNamespace (making it MAINNAMESPACE) as this is more visible and make it clear that you are using a module
  2. Use a name that is under your control: your company name, for example.  This will prevent namespace clashes with other code
  3. Make your code generic enough so that you can reuse it as many times as needed

I hope this helps with a better coding practice as well as to spread the word on namespaces 🙂

jQuery: this and that

Actually, I prefer using self instead of that, but just because I’m more used to program in Python.

The problem actually started when I decided on doing two big changes to my JavaScript code: move from MochiKit to jQuery and change from plain functions in a global scope to namespaced “classes”.

The first part is mostrly straightforward…  Some things change here and there, some rewriting is needed in a few places, but then it is not all that hard after you start to understand the differences between both libraries.

The second part, though, is what prompted me to write this article here.

To make your life easier, jQuery changes the context of the this object according to what triggered the code to run.  It might be an object or it might be a DOM element (another kind of object).

By comment 9 from the above link I found the solution to allow me to use jQuery and keep my object oriented code, using namespaces and factoring out common code.

$('selector').bind('event', {self : namespace}, my_function);

Then, at my JavaScript function, I have:

namespace = {
    my_function: function(evt) {
        var self = evt.data.self;
        // code
    }
};

This allow me to use other functions within the same namespace by referring to this namespace as self.

It took me a while to join the pieces together and the mentioned post helped a lot on creating a clean solution to the problem.

Sadness about giving up…

I can’t go on with my masters…  I am not being able to dedicate any time to it and it is making me suffer too much.

I have always demanded a lot from myself and not being able to dedicate enough time to this has been bothering me since the beginning.  Now that I am not being able to find even some minutes at the weekend — when I am too tired to think about mathematical equations, logic problems, processes, etc. — I have finally decided on giving up.

It all started a bit more than two years ago.  I spent time watching classes, reading books, reading articles, solving problems and equating things, but now…  I am letting it all go.

It is hurting a lot to take this decision.  But it will hurt much more trying to finish it.

I have tears in my eyes…  But the simple thought of not having this pressure that I impose on myself relieves me and makes my body relax.

The pain is not emotional only, it gets to the physical level.

I will be better letting it go…  I just need enough courage, now, to go to the university and request the cancellation and say goodbye to everyone.

I wish I had the possibility of dedicating myself to research, but unfortunately this is something I can’t do.  Somebody has to pay my bills and unfortunately that person is me 😦

Life keeps going on…

Not enough time for crazy thoughts lately…

I’ve been a lot busy lately.  Specially with work.

All those happening in the US, specially on the financial market, have increased the awareness level at work and put a lot more of responsibility on our daily activities at work.  That’s the price to pay, I think.

Anyway, I’ll try posting more often now…

Dojo: Still not ready for business applications

I felt in love with Dojo.  I loved the way it interacted with my existing code and its compatibility with MochiKit (that I am currently using).

Unfortunately, I can’t migrate some business applications to it because Opera isn’t supported.

I did test a very simple website using Dojo 1.1.1 from AOL CDN where I implemented just some layout Dijit widgets and an accordion pane, but it wasn’t rendered correctly on Opera.

What happened?  I had to move back and remove Dojo from the code.  I’ll keep on looking at it, but for now I’ll have to search other JavaScript frameworks (jQuery and YUI come to my mind) to implement my applications.

As I said, too bad because I was really liking Dojo.

Problems with KDE 4.1 on OpenSuSE 11

Same problems continue happening after many successive updates.

KMail — kde4-kmail-4.1.0-29.11 — is still crashing when moving (individually) several messages in a row.  It looks like something isn’t updated or some information from the IMAP server (Courier IMAP from an OpenSuSE 10.1 installation in my case) makes it crash.

If running Kontact, when KMail crashes it takes the whole Kontact with it.

I commute a lot from one network to another — at least four changes daily: home wireless net, work “dial up” on 3G, client wireless network, home wireless; plus some periods without any network at all — and Korganizer — kde4-korganizer-4.1.0-29.11 — isn’t smart enough to only try fetching my Google Calendar updates when I am connected to the Internet (just noticing a network other than 127.0.0.0/8 would do it!), making me have to dismiss update errors every “X” minutes (the fetch interval).  It could use the flag from KMail, when I mark that I’m offline (this could be implemented in Kontact — kde4-kontact-4.1.0-29.11 –, for example, and shared by all of its components).

I don’t have the problem of “desktop” crashes as I did on KDE 4 with KDE 4.1.  This is a huge plus.

I had to “lock widgets” on my Desktop to prevent their position from being reset and having them superposed to each other after I shutdown the computer.  With them locked it looks like the system learnt that I want my plasmoids listing files at the place where they are and that I want my notes plasmoid right beside them.  I can live with that, since I don’t keep adding / removing widgets, but it is annoying to have to unlock the widgets first to them be able to add new ones.  Why can’t this lock just prevent widgets from being changed?  I mean, let me add them to the screen, but don’t allow me to delete, move or do anything with them after they are on the desktop (this would create a consistent behavior and would allow me to add new things).  The placement algorithm could also be “smarter” and try the best it can to prevent widgets from being one above the other.

My Kopete — kde4-kopete-4.1.0-15.13 — is getting stale when I try to close it.  And it is having problems to connect to networks…  The icon on the panel disappears, but the application screen doesn’t close and I have to “CTRL-ALT-ESC” and click on it to kill the application and make it disappear from the screen.  Reopenning it makes it work perfectly again.

If I remember something else, I’ll post again 🙂  And this time I remembered including version numbers, so that those posts can be contextualized and tracked more easily.

Accessibility when developing for the web

There are two concerns when speaking about accessibility: accessibility for disabled people and accessibility for “disabled” browsers.

I’m talking, on this post, about the second category.

So, is this really something that is needed nowadays?  Even the browser on my mobile phone has JavaScript support (though it doesn’t have Flash support) and can run a complex dynamic website without any special change or anything designed to be used on mobile browsers (be them Blackberries, iPhones or other mobile phones).

Some recommendations are to degrade the design when JavaScript is disabled, but the vast majority of users has no idea how to disable JavaScript on their browsers.  If some IT guy from a company does that, should you really be worried with this person accessing your website?  Of course, you are reducing the market for your product, but how many people are excluded?  Are they people that would “buy” some service from the website?  Is this amount of people worth the extra investment that it takes to design a website to degrade and to be pleasant when used fully dynamically?

Some Compiz + KDE shortcuts

I don’t know if those shortcuts are available everywhere Compiz is used or if they are exclusive to KDE, but:

  • CTRL + F12: puts all windows on the background and displays a ghost window with your widgets.  It is the “Plasma Panel”
  • CTRL + F10 (also accessible moving the mouse pointer to the upper left corner): shows all windows opened and make them clickable so that you can change to that application.  If there is something dynamic happening — like a video being played — then you can see it being updated in real time.
  • CTRL + F9: zooms out so that you can see all applications from that particular desktop, side by side, and click on them to choose which one you want to be active.
  • CTRL + F8: zooms out and shows you the current view for all existing virtual desktops.

The ESC key exits from all of those views.

Using them makes it better to see what is happening on multiple environments.

KDE 4.1 on OpenSuSE 11.0

I’ve added the Factory repository to the list of repositories I use to update my OpenSuSE install and now I am running KDE 4.1.

There were a lot of bugfixes and it looks like we’ll have a more stable interface when OpenSuSE 11.1 comes out.  This is great and I am anxious for the next enhancements we’ll get ’til there.

I am now using two plasmoids to show the files available on my home directory and on my Desktop directory.  No other icons on the Desktop, as with the KDE 4 that was released with OpenSuSE 11.  This, in my humble opinion, makes the process of creating new shortcuts easier and makes the Desktop area cleaner and more efficient.

I’ve also added a plasmoid for “post-it” like notes on the Desktop.  This helps taking quick notes for things that I am changing or that I’m about to revisit / work in the very very near future (something that I saw while leaving work and want to get back to it at home, for example).