This section describes important concepts for developing portalized applications in NexJ CRM.
NexJ CRM portals
NexJ CRM portals provide a flexible and open architecture that allows you to create user interfaces. Applications running on the NexJ CRM application server consist of one or more workspaces. Each workspace, in turn, collects one or more related portlets that together provide users with coherent interactions with your model data.
Interactions between portlets are mediated by two buses: the context bus and the event bus.
Portal container structure
Portal containers provide a framework for interface components, called portlets, to be assembled into coherent screens, called workspaces.
Workspaces are placed into a single portal container to be accessed by application users. From the end user perspective, the portal container defines the application. Each workspace appears as a tab on the toolbar and, when in use, its contained portlets are displayed in the main portal workspace.
At the top of the portal container is the toolbar. This gives users access to menu commands required by the portlet and allows them to navigate between workspaces. The portlets themselves appear within the workspace:
The portal container defines the boundaries of a portalized application.
The container houses the toolbar, workspaces, and portlets that comprise the application. It also provides the buses
The toolbar is a UI element in the portal container providing users access to the menu icons and entries that apply to the active workspace.
Any portlet can contribute buttons to the toolbar. These buttons are available to users whenever the workspace containing the portlet becomes active. In this way, only the functions applicable to the current workspace are ever accessible to the end user.
It is also possible for the portal container to contribute toolbar items. For example, the application definition that defines the portalized application contributes a small number of buttons that make the settings and help functions available. These buttons are always available to the end user, regardless of the active workspace.
Workspaces collect portlets together to create a coherent, integrated view of one or more functional areas.
Workspaces provide an integrated view that displays information from one or more systems and allows the user to interact with them.
When a user accesses a NexJ solution, each available workspace appears as a tab within the application.
Solution administrators can design workspaces for users of the solution, including any portlet that has been registered with the portlet library.
Strictly speaking, context is an abstract concept that groups together a number of related portlets through the use of shared context variables.
These are variables that any portlet within the context are able to read or update. Additionally, portlets within a context are able to "listen" for changes made to the context variables by other portlets, and react appropriately. Often, this reaction involves obtaining the new value for the context variable and refreshing based on the new data. The act of receiving this notification and then fetching the new variable value is sometimes referred to as receiving context.
In practice, portlets grouped in the same workspace will share context with each other, and be able to receive notification through the context bus whenever one of the context variables in the workspace is updated.
Portlets in separate workspaces do not share context and can neither read or set each other's context variables, nor receive notification of their updates.
Portlets are self-contained user interfaces that provide atomic units of functionality, and which display application information to end users.
Portlets can also be used to gather user input and submit it to other portlets through the use of context variables and events, or supply the information back to the model server.
Portlets interact with one another by setting and receiving context on a workspace or firing and handling events.Portlets use a standard API to interact with the portal container's context and event buses.
Portlets do not interact with each other directly. Instead they communicate over two buses, the context bus, and the event bus. When a portlet submits information to these buses, other portlets listening to the buses might then refresh and update as a result of the posted information. See Portal communication for details on how this communication takes place.
Broker portlets allow you to make portlet functionality available across an entire application without limiting access to it to a specific workspace.
Typically, you group portlets together using workspaces to create and provide groups of functionality. However, sometimes you want to make your portlet functions available across an entire application, regardless of the active workspace. A portlet operating in this way is called a broker portlet.
Broker portlets are associated with the application being run, not a specific workspace within it. As a result, they are always open and active, regardless of which workspace is active. Broker portlets do not contribute UI elements in the same way as other portlets, but can contribute buttons to the application toolbar and facilitate cross-workspace event handling. Any UI layout information specified within a broker portlet is ignored. Because broker portlets exist outside of a workspace, they neither provide context information to the context bus, nor receive information from it. However, they are able to broadcast and receive event notifications.
Broker portlets can handle some application specific operations. Their functionality is similar to how the application controller was previously used. All NexJ CRM portlets have access to the broker portlet and it can therefore be used for globally accessible event handling. For example, broker portlets can be used to navigate users to a specific workspace or screen using the navigation API. Although portlets are self-contained user interfaces that are not aware
of other portlets in NexJ CRM, the broker portlet is used to provide application-wide orientation and event handing.
Broker portlets contain the functionality to provide all workspaces a common place to send and receive messages. For example, the NexJ CRM application references a broker portlet called
ContactBrokerPortlet. This portlet makes a standard set of functions, such as the ability to add a contact, available regardless of the workspace that you are in.
The portlet library catalogs all of the portlets that are available for use in a workspace.
Portlets are conceptually independent UI components, each delivering an atomic set of functionality.
Those portlets can then be combined through workspaces to provide a coherent and comprehensive set of ways for users to interact with the contents of the business model. Because portlets are independent components, however, they are never directly aware of the number or even presence of other portlets that share a workspace with them.
One portlet affects other portlets through three main mechanisms:
- Updates to context variables.
- Sending and receiving of event notifications.
- Use of the global properties.
Context variables provide a mechanism by which changes in one portlet in a workspace can be reflected by other portlets in the same workspace.
Context variables are a special set of variables whose values can be shared by multiple portlets within a single workspace. The storage of the variable values is maintained by the context bus, which also provides notification to the workspace portlets when the variable value is modified.
When one portlet updates the value of a context variable, the context bus records the new value, and sends notification to the other portlets in the workspace. Any portlets listening for notifications of the change receive the notification and can then get the new value as required.
The context bus can be imagined as a bulletin board on which the values of the different context variables are posted. A portlet listening for changes in that variable is notified immediately when it changes. However, all portlets within the same workspace can still access the variable value at any time whether or not they are listening for changes.
Notification of context variable updates and access to existing values are limited to only those portlets in the same workspace. That is, a portlet in one workspace cannot access or receive notification about the context variables in another workspace. This allows you to re-use the same portlet in multiple workspaces within the portal without the risk of actions in one workspace affecting the state of the other workspaces.
The act of posting a new value for a context variable is referred to as setting context. The acts of receiving notification that a variable has changed and getting the new value is referred to as getting context. Additionally, portlets accessing the same set of context variables are sometimes referred to as being in the same context. In almost all cases, referring to the "context" of a portlet is the same as referring to the "workspace" in which the workspace exists.
Assume you have a portlet called
RestaurantListPortlet, which uses the form
RestaurantList to display a list of restaurants that meet a certain set of search criteria. In the same workspace you have a portlet called
RestaurantDetailsPortlet, which uses a form called
RestaurantDetails to display the address, menu, and operating hours for a given restaurant.
You want your workspace to operate so that if a user clicks a restaurant in the restaurant list, then the details of that restaurant will appear in the restaurant details portlet. However, the details portlet has no way of directly knowing what has happened in the list portlet. To achieve the behavior that you want, the details portlet must receive a notification when the selected restaurant in list portlet changes, including the identification of the selected restaurant.
This communication is achieved through use of a context variable. In this example, the list portlet and the details portlet will both make use of a commonly named variable,
RestaurantID. The details portlet additionally includes it in its context variable definitions. When the workspace is configured, the list portlet is given permission to update the value of the context variable, and the details portlet is set up to listen to the bus for changes in the variable value.
When the list portlet updates the value, the new value is sent to the context bus. The bus then broadcasts a notification to the portlets in the workspace. The details portlet, which is listening for changes to the value, receives this notification, gets the new value, and updates the details that it displays as required.
Events and the event bus
The event bus is one of two key buses used to communicate changes made through a portlet.
When an event takes place, it is possible to broadcast that event to the event bus. Any portlets listening for those events can then receive notification of the event's occurrence and take appropriate action.
The event bus broadcasts events across all workspaces within a portal container. That is, all portlets in the container that are configured to listen for the event will receive notification of it, regardless of the workspace in which they reside. Portlets within the active workspace receive immediate notification of the event. Portlets in other workspaces, receive notification of the event when they become active. See Shelving for a detailed description of how this works.
Unlike the context bus, which maintains a record of the currently applicable values of the context variables, notifications sent through the event bus are transitory and the information passed by the events cannot be accessed after they are processed within a workspace.
UI Events are notification objects that tell your NexJ application that a user has performed an action. For example, a UI Event can notify your application that a user has clicked a button.
A UI Event triggers when a user interacts with a control that is associated with the event. To associate an event with a control, specify the UI Event in the control's event property. When the UI Event triggers, the event is broadcast to the event bus.
UI Actions handle events received from the event bus at the form, screen, and application levels of your NexJ application. Events are passed through the levels of your NexJ application in the following order: Form → Screen → Application. If a UI Action to handle a specific UI Event is not present at a level, the event is passed up to the next level.
Create UI Events in the UI Events tab in the Presentation layer. Associate UI Events with controls in the Forms, Screens, and Applications tabs in the Presentation layer.
UI Event properties
UI Events have the following properties:
A unique identifier for the UI Event. The name typically reflects the event's function. For example, the UI Event for adding a financial security in NexJ CRM is named
Specifies whether to bind the UI event to a class or client model, or to not bind the event. Binding allows the control associated with a UI Event to be dynamically enabled or checked based on properties of the class or client model.
Allows the control associated with the UI Event to be enabled or checked based on an attribute from the specified class or based on a Scheme expression. Specify the class in the Class field. Specify the attribute or a Scheme expression in the Checked and Enabled fields. If you do not specify a Class, you can still specify a default checked and enabled value by selecting or clearing Checked and Enabled.
Allows the control associated with the UI Event to be enabled or checked based on the client model's state or based on a Scheme expression. Specify the state attribute or a Scheme expression in the Checked and
Text or a StringID that represents the text associated with the UIEvent.
Specifies whether controls associated with the UI Event are checked or unchecked. When
clientmodel is specified in the Bound To field, the Checked field allows you to enter a Scheme expression or the name of an attribute from the bound class or client model.
Specifies that the UI Event commits changes in a pop-up dialog.
Specifies whether controls associated with the UI Event are enabled or disabled. When
client-model is specified in the Bound To field, the Enabled field allows you to enter a Scheme expression or the name of an attribute from the bound class or client model.
A description of the UI Event.
An icon that appears beside the name of the UI Event in the list of UI Events.
A shortcut key that triggers the UI Event. Specify a key using ASCII or SWT codes. For example, to specify that the Delete key triggers the UI Event, enter
127, which represents the decimal ASCII control code for Delete.
Modifier keys that must be pressed in conjunction with the key specified in the Key property to trigger the UI Event. Available modifier keys are Ctrl, Alt, and Shift. For example, to specify that the key combination
Ctrl+P triggers the UI Event, enter
112 for the Key property, which represents the ASCII key code for the letter "p", then select Ctrl for the Key Modifier property.
Additional text that displays when a user hovers their cursor over a control that is associated with the UI Event.
Shelving refers to a behavior of the event bus in which event data is temporarily stored, or placed "on the shelf" while that workspace is inactive.
Notifications of events are always sent out immediately to the listening portlets in the active workspace. However, instead of immediately sending the notification to inactive workspaces, the event bus shelves the notification, putting it in a queue for each inactive workspace. When a workspace becomes active, the bus processes the appropriate event queue, effectively taking the event notifications “off the shelf” and allowing the portlets to respond to the event as appropriate.
NexJ CRM supports the concept of shelving when portlets are not visible to the end user when an event occurs.
When the portlets become visible, all events that had been shelved are passed to the event handler as an array with
the elements in the same order as the original event firing sequence. This reduces the amount of RPC traffic that
occurs when an event is fired.
The shelving functionality applies the following rules in order to control the number of shelved events:
- All shelved events except for sysRestoreMemento are cleared when a sysContext event is fired on a shelved portlet.
The sysRestoreMemento events are preserved because they are needed in order to update the portlet state before subsequent events are handled. This allows the portlet update behavior to accurately behave as if the events had occurred while the portlet was visible.
- When an event fired on a portlet already exists in the queue of shelved events for that portlet, then the prior instance will be removed and the new occurrance added to the end of the queue.
Global properties enable the sharing of variables between workspaces. The value of global property variables are available to all portlets in NexJ CRM, regardless of what workspace they belong to.
Although updates to global properties are not broadcast by the NexJ Framework, portlets can retrieve the current value of a global property at any time and appropriately make use of it. An example of using a global property variable in NexJ CRM would be creating a task in the Schedule workspace with the currently selected contact in the Contacts workspace as the initial entity.