ERP/3.00/Projects/UI Technology/FormAndGridDesign
Introduction
This document outlines the technical design and architecture of a re-implementation of the Openbravo user interface. This document uses the sales order entry window as an example but tries to be generic in the solution strategies and proposed architecture.
Standard OB Concepts
This section gives an overview of the standard Openbravo concepts which need to be supported by the new form and grid implementation.
Window, Hierarchical Tab structure
- A main characteristic of the Openbravo user interface is that a Window consists of a set of tabs organized in a hierarchy.
- Selecting a record in a parent tab automatically refreshes the child tab
- Selecting a child tab automatically means that other grand-child tabs are shown (multi-level).
DefaultValue
A column can have a default value defined in AD_COLUMN. The default value can be a fixed value or an expression or even a sql query, some examples:
- @SQL=SELECT COALESCE(MAX(LINE),0)+10 AS DefaultValue FROM FIN_FINACC_TRANSACTION WHERE FIN_Financial_Acount_ID=@FIN_Financial_Acount_ID@
- @#Date@
- N
- S
- @AD_CLIENT_ID@
Display and Readonly Logic
This section describes how the display logic concept will be implemented in the new architecture. The displaylogic/readonlylogic consists of expressions like:
- @IS_Percent_Wh@='Y'
- @Payout_Allow@='Y'&@Payout_Execution_Type@='A'&@Payout_Execution_Process_ID@!
- (@ArgNo@=1 | @ArgNo@=2 | @ArgNo@=3) & @Type@='C'
- @Processed@='Y'
Validation
Validation is used to filter the records shown in a combobox. Most validations are defined using a SQL where clause. However it is also possible to define validations in javascript or java.
Callouts
Field Implementations
Field Groups
In Openbravo fields can be organized in a field groups, a field only belongs to one fieldgroup, a fieldgroup structure is one level deep.
I18N
The following I18N concepts should be taken into account:
- labels should be read from the corresponding TRL table (ad_field_trl for example)
- (error) messages need to be translated, current translations need to be re-used.
- the date and number formatting defined in the Openbravo.properties and the format.xml need to be supported/used.
Main Functionality
This section how the Openbravo concepts, introduced in the previous section, can be supported.
Toolbar Functions
Field Implementations
There will be Openbravo specific field implementations for each different type of field. The Openbravo specific field implementations will inherit from the standard Smartclient FormItem implementations. Currently the following field implementations are identified:
- boolean (yes/no)
- date
- date time
- text (one line)
- text (edit box)
- text (password)
- enum (list reference)
- tabledir reference
- table reference
- selector reference
The editor type is defined in the Smartclient simpletype. For each Openbravo reference a Smartclient simpletype is created, the simpletype is used in the datasource for the datasource fields.
Boolean/Yes/No
There is already an Openbravo specific field type: OBYesNo.
Date and DateTime
The OBDate and OBDateTime have been implemented for the selector, these will be re-used for the date and datetime fields.
Text (single line)
Text (multi line)
Text (password)
List Reference/enum
Tabledir Reference
Table Reference
Selector Reference
Common Behavior of Field implementations
- each field should support displaying an error message in a user-friendly way.
- Support checking mandatory
- Each of the field implementations will have common behavior to support read-only-logic and display-logic.
Field Groups
The idea is to use Smartclient SectionItems to implement field groups. The Openbravo field group can be translated directly to Smartclient SectionItems.
Callout
Validation
Tab Header Info
The identifier of the record should be used to add information to the tab header of the main layout tab.
Generative Approach
The architecture should generate the user interface on the basis of the window/tab/field definition. The current view manager implementation already provides a load-on-demand mechanism to retrieve view implementations from the server.
The logic works as follows:
- the user selects a window from the menu/quick launch/create
- the window id is used to identify the view to open.
- if the view class is already loaded on the client then it is instantiated and shown in a tab
- if the view class is not loaded yet a call to the server is done with the window id.
- the ad_window record is loaded and its template (new field) is used to generate the correct representation which is returned to the server.
Runtime Representation
At runtime the sales order entry window will be managed by client and server objects which take care of:
- client-side logic to build the form/grid itself (create the fields/columns etc.)
- client-side logic to handle user actions and validations in the form/grid
- server-side logic to handle server oriented user actions (save, delete, etc.) and return results to the client.
Client side: OBStandardView
The client side runtime representation reflects the hierarchical structure of the user interface.
The main client-side object is the OBStandardView which is responsible for managing the visualization and runtime behavior of an Openbravo Form and Grid combination and the children. An OBStandardView can be used in two ways:
- Root: a root tab which is shown in the main layout. This OBStandardView is capable of setting the tab header and it understands that it runs in the main layout.
- Child: a child tab is aware of the fact that it has a parent OBStandardView which can send actions (like refresh or repaint) to it.
The OBStandardView controls both the grid and form representation. The Form can be seen as a single-record view on a multi-record dataset. The OBStandardView uses a single datasource to supply the data for the form and grid views.
For visualization the OBStandardView consists of a horizontal layout with 2 members:
- OBViewForm: extends the Smartclient DynamicForm and adds additional behavior related to callout and displaylogic handling. The field in an OBViewForm will probably be Openbravo specific subclasses of the standard Smartclient fields. This to implement additional Openbravo specific behavior on Field level.
- OBViewGrid: extends the SmartClient ListGrid adding additional behavior related to filtering etc.
The horizontal layout will have a splitter bar so that a user can view both the grid and form at the same time.
The OBStandardView keeps track of the current record and uses it to update/refresh child OBStandardView.
The OBStandardView has a list of child OBStandardViews which are shown in a TabSet below the main form/grid. The child OBStandardViews are aware of the fact that they are visualized as part of a parent. When the current record in the OBStandardView changes then the child OBStandardViews are refreshed. The parent-child OBStandardView structure is multi-level, so a child OBStandardView can again have child OBStandardView instances.
The OBStandardView has a separate toolbar object which manages the toolbar actions which consist of standard actions and custom actions.
There will be a standard/generic implementation of the OBStandardView which can handle a standard form/grid combination. In practice this standard OBStandardView class will be extended with a custom instance which adds specific behavior related to callouts and displaylogic and custom buttons.
Generation
When the user selects a window to be viewed the window definition is generated on the server (if the window definition was not already loaded on the client). The generation creates javascript which creates a subclass of the OBStandardView. This subclass definition is loaded on the client and used to instantiate a specific instance of the window.
This structure is chosen because one window can be shown (instantiated) multiple times in different tabs.
The window specific subclass of the OBStandardView consists of the complete hierarchical structure of tabs, child tabs and grand child tabs, meaning that each tab has a corresponding OBStandardView instance with the corresponding fields (form) and columns (grid).
Context Information, resolving expressions
Many expressions in Openbravo (for example DisplayLogic) uses information which is stored in the http session. In the new architecture this information is not stored anymore in the session but stored on the client-side where it is accessible for client-side code.
To support this concept the Openbravo StandardView will have a so-called Context object which represents the session for the client-side logic.
The context object is filled/updated when the user loads records in a form or changes values in form fields.
This means that:
- the fields in a form need to set their value in the context object when they are loaded or when they change. So they need access to the context object.
- for each field change the
Some context values can not be resolved on the client. For example the default value definition can contain a sql query. When such a value is requested the context object should be capable of performing the following actions:
- resolve the context values in the sql queries
- send the sql query to the server for execution and receive the result
The context object should be capable of storing values from form fields and also to evaluate expressions which are currently used within Openbravo:
- @SQL=SELECT COALESCE(MAX(LINE),0)+10 AS DefaultValue FROM FIN_FINACC_TRANSACTION WHERE FIN_Financial_Acount_ID=@FIN_Financial_Acount_ID@
- @#Date@
- N
- S
- @AD_CLIENT_ID@
- @IS_Percent_Wh@='Y'
- @Payout_Allow@='Y'&@Payout_Execution_Type@='A'&@Payout_Execution_Process_ID@!
- (@ArgNo@=1 | @ArgNo@=2 | @ArgNo@=3) & @Type@='C'
- @Processed@='Y'
OBToolbar
The OBStandardView has an instance of the OBToolbar class. The OBToolbar implements the main toolbar actions:
- save: save the current record
- new: create a new record, in form view start with a new form with empty fields, in grid view, start with a new empty row
- delete: delete the current record, or the selected records.
- undo
- redo
- attach
- export
- first/previous/next/last: browse buttons
- bookmark
- inner join
- outer join
- toggle view
- save view
OBViewForm
The OBViewForm is a subclass of the Smartclient DynamicForm.
To initialize a form data is required for form fields. This can be the values of a list reference or the default value of a field. One approach could be to do a request to the server for each form field. This results in many requests. A better approach is therefore to let the form do one call to retrieve all the required information to initialize form. The information which needs to be read is:
- list values for a combobox
- default values
The default values use an expression (see next section) which need to be resolved against context information. This is discussed in the next section.
OBViewGrid
- sorting
- filtering
- select rows (for delete)
- delete
- multi-select
- editable grid
Server side: OBStandardView
On the server side there will also be an implementation of the OBStandardView. The server side implementation takes care of:
- executing standard actions like save, delete, etc.
- executing callouts
Custom Implementations
As outlined above: client and server side logic is provided by a generic implementation. It should be possible to specify the implementation class for a specific tab. This provides a very powerfull extension and overriding mechanism.
SQLQueryHandler: querying for entities using SQL Where Clauses
In several parts of the Openbravo system where clauses are defined as SQL. These clauses can not converted to HQL. Therefore we need to develop a query mechanism for entities which does not use HQL but uses SQL. Hibernate provides a mechanism called entity query for this.
To support SQL querying we need to implement something like a SQLQueryHandler which supports querying for entities using complete sql queries or sql where clauses.
Also the datasource querying needs to be adapted to work in SQL-mode.
Security Model
Discusses topics related to the security Model.
Parameter Windows
Four Columns Layout
2.50 Approach
In 2.50 there are only 2 columns where the fields are generated. Depending on the field length and the type of reference, the width can be one of the following:
- Half column
- One columm
- 2 Columns (Full page)
- 2 Columns Multiline
Check the image below.