Saturday, March 22, 2008

Ext JS

My boss, a former Swing programmer, has decided we need to be more cutting edge (I mean, we use Rails already, how much more cutting edge can we be?), so we are incorporating the ext javascript framework into several of our applications. We are starting with the 'grid' layout, thereby getting sorting and column manipulation for 'free'.

I had tried to use ext js before, and approaching it again filled me with fear and apprehension. The documentation focuses so much on what is possible, that it is easy to be overwhelmed. Fortunately, a coworker turned me on to the ext scaffold plugin, which generates working ext code based on a model. The code it generates is not meant to be used, but rather provides something to copy from the generated source and play with in the views. (I created a separate rails project for the plugin so I could keep the clutter out of my production project.) I found it much easier to play with working code than to start from scratch.

Playing around with the generated code helped me understand that grids are really just a combination of two elements: a datastore and a column model. The column model is a set of column definitions, each of which includes the label of the column header and the key to the item in the datastore. The datastore consists of the data (either an array or a 'proxy' to an http resource that will supply the data) and a 'reader' (parser) that will convert the data into a dictionary that the column model can call.

But working with generated code only gets you so far. If you want anything but default behavior, you will need to search through the discussion forums. Searching through the forums takes patience, but through them I have been able to solve some of my particular problems.

Example: I wanted to add an item to each column's "context menu". This information is nowhere in the API documentation. In fact I needed to search the forum just to find out what terms to use to search the forum effectively for this information. One post pointed me to the part of the code that sets the default elements of the context menu, and I managed to get my functionality in place by example.

FYI, the "menu" that the columns use, is available through the chain: grid.getView().hmenu. The item you need to give the menu consists of a label, a function to call when the label is clicked, and grid.getView(). This latter is the 'scope' of the menu item, which means that all of the 'this' references in the body of the function will use this object. (My JavaScript skills were insufficiently leet for me to intuit this meaning of the word 'scope'.) You call the gridview to get the hdCtxIndex and the column model, both of which are necessary to figure out which column's context menu was used.