Archive for the ‘UI’ Category
Create a custom headerRender for the AdvancedDataGrid column with a checkbox control embeded and adhering to the following functional requirements
- support(retain) the column sort functionality
- must be a reusable component (no tight coupling)
- easy to extend and plugin to use in any other grid control
Provide the Select All rowItems functionality for the grid column. Each row item will have a checkbox to allow its (un)selection.
The Select All functionality for all the row items in the grid is a very common requirement for any application, but however before implementing we need to be clear about the dataProvider as well.
Will the dataProvider for the grid have dataFields, which can be binded to the state of the checkbox in the column header and for each of the row items?
If the dataProvider contains dataFields which can be binded to the UI it is fairly simple to handle the use case, but if the SelectAll is purely a UI operation for populating the list of selected items for further processing, then it becomes little more challenging.
One more challenge here is to preserve the sort functionality for the column, as any custom implementation of the headerRenderer or any component being used as the headerRenderer will strip off the sort functionality for the column. Check it out for yourself if you dont believe it.
Here is the approach that I followed to address the constraint on
>ReUsability: Program to an interface and avoid tight coupling with the parentDocument while handling the communication and binding with the grid.
>Extensibility: Encapsulate the behaviour in the class as a separate .as file extending UIComponent and provide the customizable behaviour in the virtual methods which cane be overriden if required by the derived classes.
There are two approaches to implement the checkbox headerRenderer
Appraoch 1: Specify any implementation of UIComponent (say CustomCheckbox) as a headerRenderer for the grid column
But then you need to be prepared to handle the layout and rendering of the sortItemRenderer inorder to provide the sort functionality on the column. Also you need to be prepared to hook onto the instance of the headerRenderer for communication with the grid as you will be stumped to discover that the grid creates a new instance of the headerRenderer every now and then. Possible work around for this is to create the instance of the headerRenderer as an instance of the classFactory and store it as a bindable value in the parentDocument. After managing all of it you still need to be able to differentiate between a click to Sort and click to SelectAll by putting in vague logic based on the position of mouse click. I hope you agree that it cant get simpler than this 🙂
Approach 2: Implement the custom headerRenderer by extending the default AdvancedDataGridHeaderRender implementation and specify it in the grid column
This approach looks the obvious natural choice but then you need to know how and where to insert the custom implementation. Refer to my post on creating custom Flex controls for more info on it. Also you need to be able to differentiate between a click to Sort and click to SelectAll, which I managed it by controling the sort property of the column in response to mouse hover 😉 . Look below for the OnMouseRollOver method.
Show me the source code: Continue reading
commitProperties(): Update/Bind the properties of the child controls in the custom control here. This is the last method to be called before rendering, hence it is a good place to update the properties of the child controls to acheive the binding . More Info
We would not require to make an explict call to any of the methods above as they are called by the Flex framework itself, we only need to plugin in the custom code in the invocation sequence appropriately. Refer to the link “More Info” for a comprehensive documentation of the usage of the methods.
We may not need to override all of them, but it is important to know the appropriate method to be overriden. Also do not forget to call the implementation of the base class unless you are really sure to do so.
The first obvious step would be to look at the source code implementation located at <Flex 3.1.0 SDK Installation Directory\frameworks\projects\framework\src\mx\core\UIComponent.as>
In my opinion the most effective approach for creating your own custom controls is to extend them from the base controls and customize by overriding and digging into the source code of the base controls.
Some of the common methods, that you might want to override in your custom component are
Refer to the next post for creating the custom flex UIComponent
Here is the list of the types and variations of the Undo/Redo functionalty.
The Undo/Redo functionality without specifying the operation which will be performed.
The menu item offering the Undo/Redo functionality also displays the operation which will performed. This makes use of the DisplayName of the edit to be performed.
The typical notepad style supporting Undo/Redo only for the last operation performed.
Multiple Undo/Redo supports unlimited no of edits for all the opertaions performed.
5.Multiple Undo/Redo with the UI to choose the number of edits.
Its the typical MS word style. The UI(toolBar Button) shows the DisplayName of all the edits in the Undo/Redo stack providing the option to choose the multiple edits to be performed. This provides the option of performing Undo on the last N opertaion at one shot.
More sophisticated implementation would be allow the user to choose the edit which need not correspond to the last edit operation.
Operation 1- Delete a line
OPeration2- Find Replace operation performed for a particular word
What if user wants to perform Undo for operation1 but NOT for operation2?
My next post will be on the Challenges that I faced in implementing Multiple (Instructional) Undo/Redo .
Imagine preparing your project report in MS Word without having to use Ctrl Z/Y. You will bulb for sure, its going to be very very painful.
That’s the power of Undo/Redo. We take it for granted in any standard, user-friendly software.
- It acts as a Saviour, during the times of distress
- It makes the learning process like a ride on a Highway.
- It allows the users to explore the software with a confidence that he can always recover easily from the mistakes, during the learning process.
Q. But why does a computer application need the Undo/Redo functionality, when the underlying piece of code will never ever go wrong it its output. You run the same operation 1000 times with the same inputs you are guaranteed to get the same output every time?
Ans. The Undo/Redo is meant for the User and not the application itself. Yes the computer program never makes a mistake but humans do. They are by default error prone.
What the designed applications treats as an invalid input for an operation might be a perfectly valid input from the users side.
The role of Undo/Redo comes into picture when an error(s) is made and the user realises it and express a strong intent to recover from the mistake(s) made.
The application must always assume that the user is always right.
The environment may dish out all the possible operations that could be performed on the current object in the context to the user from different sources. It could be from the right click context menu on the current object or the cute icon in the toolbar or the menuItem in the global menu bar or a tree layout in the side bar or an icon in the tray.
The same set of operations may be offered by multiple sources. Then
Q.How can we manage to keep all of them in sync?
>The context specific menu items must be populated dynamically. They must never be cached with the current object
>All the menuItems/icons must be tagged to their associated actions , i.e, if a certain operation is disabled for the given context then all the UI components offering that particular operation must be disabled or should not be populated at all.
To achieve this, possibly you must have a registration mechanism of all the operations against the UI components offering them.
>Populate the ContextMenu with the selection oriented commands
>Populate the ContextMenu with a fixed set of comands for each selection type and then enable/disable them to reflect the selection state.
This will help the user to see an expected and same set of consistent context menu and will make navigation easier.
>The context specific menu must be consistent across all the object displayed in the editor.
>If the same object appears in more than one editor, then same contextMenu must be available.
>Classify and group the menuItems using menu separators.
>Provide the common operations on the editor itself, which are not selection specific rather than on each of the object. For eg: Reload, SelectAll, Back, Undo/Redo, Find, Zoom
Q. How can the editor cope up when the menuItems, which might possibly be contributed by a add-ons and plugins?
>There must be a registration mechanism to allow the menuItems dispayed in the editor to be registered with the HostControl.
>Implement a command filter for each object type in the editor.
Some dumb questions to ask…
>Whats the best way to provide response to the functionality from the editor but inturn being offered by different objects?
>If the functionality of an operation is provided by a specific object in the editor, then that particular functionality must be exposed as public method inorder to allow the editor to provide response to the menuItemClick.
>If for the sake of consistency, all the context specific menuItems are being populated by the editor, then the editor must be able to exactly locate and identify the current Object and must enable/disable menuItems accordingly but how to do it cleanly?
>If the effect of an operation being performed by using object1 or object2 is same, then why have functionality available from both objects?
Writing about it so far has helped me in clearing some blockages and probably would be in a better state to comment more on it once I solve it completely.