I was working on some applications with heavy customizations of Dojo DataGrid involved, which is cumbersome if the API doesn’t provide good features exposed to the developers like me (may be like you ☺). Unfortunately the application has DataGrids in multiple places with more custom features, so I couldn’t get my hand to migrate it to EnhancedDataGrid. It should’ve been done earlier; my job could’ve been simpler.
One of the simple expected features was to set the sort icon by default or wherever the sort icon is required. After searching in many forums including dojofoundation and stackoverflow I couldn’t find a straightforward method or API. So I had to do it on my own without adding much complexity in the existing code. Here is what I did,
As you see above, the function has two parameters one is the Grid (dijit based object), and the field name (data field from your data store). You can also use index based sort icon. Thanks to DOJO, the DataGrid has layout API exposed which would help any developer to play and customize the grid like they want.
Step by step explanation of the code and how I came to this solution,
I loop through the cells that are part of the layout API and find out the column I want based on the field name comparison. Could be index-based comparison as well.
I’m using jQuery for all my DOM manipulations. You can use DOJO as well for your DOM. Based on the cell id I’ve created a jQuery object (targetCell) to perform some DOM changes over the cell.
Setting the ARIA (Accessibile Rich Internet Applications) attribute to ascending (could be descending). Setting this attribute tells the screen reader that the column in ascending order.
Every cell has a sort node (div element) in it. It has to be replaced with the sort icon code. Once the sort node is found, the Sort DOM structure should be added.
I have added the sort DOM structure to the sort node to render it properly with the sort icon and the column label.
After adding the DOM structure, this sort information has to be informed to the Grid using setSortIndex. Then only it would reflect or render the sort icon when you click other columns. The second parameter should be false, otherwise the grid will sort the data again.
I hope you find this simple and easy. From the forums I read, there could be other ways to do it. Leave your suggestions in the comments section.
Lately, I was talking to a friend of mine who used to be a Flex (RIA) developer like me, in the middle of conversation he asked me a simple and straightforward question like any normal Flex developer could ask,
“ How do you develop UI components like Adobe Flex / AIR / AS 3? Remember we use ItemRenderer / Skinning / AS 3 custom components / event listeners / binding?” … ah… etc… etc…
Let’s start with a simple form, say a login form with two fields and submit button. Like in the screenshot below.
Some concretes before I go in detail, #1: In Adobe Flex, Application tag is the root of the entire application, which holds several UI components with various ItemRenderers and skins. In HTML, HTML tag is the root of the entire page, however, BODY tag holds all the UI elements.
# 2: In Flex, generally many people uses Box, HBox, VBox, HGroup, VGroup, some times Canvas, etc. for creating component as shown above (keeping UI and Logic separate from main Application). Likewise in HTML we can create components mainly based on DIV and Span elements and attach (append) it to the main application / page / parent (DIV) element by accessing the placeholder (like Component declaration in Flex with several properties).
# 3: In Flex, component UIs and logics usually kept in MXML or AS files; in HTML it can be in HTML Template file or in JS file. In case of HTML Template, we need some JS templating engines like Mustache, EJS, Underscore, HandleBars, Jade and more if you want to keep your UI (view) in separate HTML file. However, one good news is HTML5 has new feature under Working Draft called “Web Components” http://w3c.github.io/webcomponents/explainer/ . In this post, the focus is more on writing UI and Logic in separate JS file.
Having these concretes in place, let’s dive into the code directly. Like I said in concrete 1, here is the base / main page going to hold all the components. Oh oh, I forgot to mention one thing, in Flex every component goes through its own life cycle called “Component Life Cycle” similarly in HTML world, the life cycle (Parsing, Rendering and Painting) will be entirely taken care by the browsers. In other words, the component creation is loosely coded unlike Flex / AS3.
Main HTML Code
<!-- Main Container to hold Grid and Navigation Pad -->
<!-- To hold instance 1 UI -->
<!-- To hold instane 2 UI -->
As you see in the code snippet above, there are two instances (components) having unique identifiers. Through these identifiers the components are going to be attached (appended) to the main page. This is a very straightforward declaration of HTML elements. As the base is ready, it’s time to write some nifty JS snippets for adding the UI and logic.
<input class="btn submit" type="submit" value="Login to your account"/> \
Declaration of the component LoginControl is given above . There are three variables, loginData to hold the data model, loginUI to hold the UI (view), and a name to represent the name of the instance. This is a simple approach for declaring the view (UI elements of the component). In my next post hopefully I will be writing about the Template Engine approach.
Through LoginControl.prototype you can access the different elements of the component and add the functionality on top of it. This is basically to extend the functionality of the class. Here, I wrote a function loginInitialize which helps binding all the events and attaching the UI via placeholder parameter jQuery object.
So once the page DOM is ready (Loaded completely) the components will be added, in our case two Login Controls namely instance1 and instance2. Function loginInitialize() handles the view and logic attachment to the source parameter. In other words, the element acts as the holder of the component is passed as a parameter to the function along with the instance alias name.
All these code snippets are available in my Github Demo page. Feel free to use it. 🙂