NexJ Logo

Docking workspaces

NexJ Studio models support the concept of docking an item, such as a contact, task, or calendar entry.

When a user docks an item, the system takes the item's information and opens a new workspace, populating its context variables using the information from the item. This new workspace typically contains a subset of the portlets that were contained by the workspace from which the information was taken. For example, in NexJ CRM, docking a contact opens a new workspace with that contact's details, including their journal information, but not including their portfolio information.

This behavior is the result of a number of contributing actions:

  • You must create or identify a workspace to which the item's information will be passed when a user invokes the Dock action.
  • You must ensure that the item has attributes set to provide workspace label information.
  • You must add either a button or menu item to the screen that you want to launch the dock workspace from.

When all of these programmatic elements are in place, then when a user clicks on the button or menu item that you define, the context information about the item is passed to a new workspace, the dock workspace, through the event bus. The dock workspace takes its label information from the attributes of the docked item.

Defining dock workspaces

When a user docks an item in their application, context information from the original workspace is passed into a new workspace, called the dock workspace.

This dock workspace, like any other workspace, must be designed and defined as a screen in NexJ Studio. Typically, a single workspace is created for each specific class that you want to allow users to dock. In NexJ CRM, the following classes already have dock workspaces defined for them:

  • Act
  • Campaign
  • DocumentMrgItem
  • Entity
  • Event
  • ImportProcess
  • Opportunity
  • ServeRequest

To create a dock workspace:

  1. In the Presentation layer, create a new screen. By convention, the screen name should be Docked<ClassName> where <ClassName> is the name of the class that you intend to use the workspace to dock.
  2. In the Overview tab:
    1. Set the Portlet property for the screen to False.
    2. Set the Context property of the screen to include the context variable that passes the ID of the class you want to enable docking for. By convention, this is usually set to <ClassName>Id where <ClassName> is the name of the class that you intend to dock. If you are unsure, you should check the model information for the class.
    3. Design the rest of the screen by using the adding portlet references.
  3. Using the Layout tab, assemble the screen in the same way that you would assemble any other workspace, adding portletrefs and positioning them on the screen.
  4. When the layout is complete, save your changes.

After you have created the target workspace, ensure that the class that you are going to be docking has the required summary attributes set.

Setting workspace summary attributes

The workspace summary attributes are a set of five class attributes that are contained in the SUMMARY_INFO aspect.

This aspect is either referenced directly by the classes that you might want to dock, or inherited from a parent class. They define the information that is displayed in the workspace tab on the user's screen when a user docks an instance of the class.

Of the five attributes in this aspect, there are three that you will have to ensure you override and set for the class you want to dock:

  • summaryIcon
  • summaryHeading
  • summarySubHeading

The values of the remaining two classes should not typically be overridden.

To set the workspace summary attributes:

  1. In the Business Model layer, open the class that you want to enable docking for.
  2. In the Base Attributes tab, review the inherited values for the summaryIcon, summaryHeading, and summarySubHeading attributes. If you want to change the values of any of these attributes, use the Attributes tab to override them.

    Info

    If the attributes do not appear on the Base Attributes tab, then use the Overview tab to add the SUMMARY_INFO aspect to the class. Then use the Attributes tab to set their values.

  3. If you made any changes, save them.

After you have reviewed the workspace summary attributes, you can continue by adding the controls to the UI that will allow users to dock the class.

Adding controls to open dock workspaces

You can enable a user to dock a class instance by providing a right-click menu item in a list form that displays the class, or by adding a Save and Dock button to a dialog that displays the class details for review or editing.

Adding dock menu items

You can add Dock menu items to enable users to dock a class instance by right-clicking it from a list of class instances.

The contact list in the Contacts workspace is an example of this kind of access.

By convention, and for consistency within the UI, the Dock menu item is normally added to all lists that display dockable items.

To add a Dock menu item:

  1. In the Presentation layer, open the form to which you want to add the Dock menu item to the right-click menu.
  2. In the Outline view, insert a menu item:
    1. Right-click the Form node at the top.
    2. Select Insert Child → Menus beginning. The Menus node is added to the outline as the first child node.
    3. Right-click the Menus node and select Insert Menu.
    4. Right-click the Menu node and select Insert MenuItem.
  3. In the Properties view, set the name property to dockItem.
  4. Set the event property to dock.
  5. In the Script tab, add the following blocks of code:

    (define dockingEnabled 
       (client-workspace-mode? this) 
    ) 
    (client-enable-events this '() dockingEnabled "dock")

    Docking can only be used with portal applications. The first part of this code tests whether the application uses workspaces, which indicates a portal application. The client-workspace-mode? command returns #t when workspaces are used, and #f in all other cases. The second part enables or disables the dock event based on the result of the check.

  6. In the Data Action tab, add a data action with the following properties:

    1. Set the Condition to:
      (= locator 'selection)

    2. Set the Script to include:
      This condition and script disables the dock event when the list is empty.

  7. In the UI Actions tab, add a UI action for the dock event with the following script:
    (client-goto-docked-workspace this (getCurrent<ClassName>) "<ClassName>Id")
    where <ClassName> is the name of the class that you want to dock. This action launches the new workspace and passes it the item InstanceModel or DataObject, along with the corresponding context variable.

When you have completed these steps, the form will allow docking of the class. Carry out unit testing and other testing as required to ensure that the behavior is what you expect.

Adding Save and Dock buttons

The Save and Dock button appears on dialogs to allow users to save the changes made in those dialogs and open a new workspace for the class instance being edited.

Typically, this button is added to dialogs that allow users to create new class instances.

To enable this button, you must ensure that the button is included on one of the forms that make up the screen defining the dialog. You must also ensure that the form containing the button adds the correct UI action to the screen's property map.

Additionally, you must edit the close script for the screen. This is done in the UI actions of the script that launches the dialog.

To add a Dock menu item:

  1. In the Presentation layer, add a button to the form that the dialog uses to store its action buttons by doing one of the following:
    • If the dialog uses the WizardButtons form, replace it with the DockingButtons form, which includes a Save and Dock button definition.
    • If the dialog does not use either form, add a button to it. Set the Event property to saveAndDoc and the name property to SaveAndDockButton.
  2. Save your changes.
  3. [Optional] If you are using a form other than the DockingButtons form, then add a Script UI action to it, witthe following code:

    (((this'parent)'propertyMap)'saveAndDock #t) 
    (this'fireUIEvent "sysOK" parameter)


    This sets the saveAndDock property to #t in the screen's property map, and fires the sysOK event. You can skip this step if you use the DockingButtons form because it already contains the required action.

  4. Open the screen that defines the dialog that you have added the buttons to.
  5. In the Script tab, add the following code, which will disable the Save and Dock button when the screen displays in a non-portal environment.

    (unless (client-workspace-mode? this) 
       ((this'findEventModel "saveAndDock")'enabled #f) 
       ((this'findView '(frmDockingButtons SaveAndDockButton))'visible #f) 
    )
  6. Save your changes.
  7. Open the form that launches the dialog that you have just edited.
  8. In the UI Actions tab, locate the script that launches the dialog.
    This script will make use of the popup command, and is typically associated with the sysEdit event.
  9. Locate the closeScript section of the script.
  10. Add code to the closeScript section so that a postMessage calling the client-goto-dockedworkspace command runs in cases where the saveAndDock propertyMap value is true and the workspace mode is being used. For example:

    (popup'closeScript 
        (lambda (this) 
             ... 
           (when dockingEnabled 
              (when (= ((this'propertyMap)'saveAndDock) #t) 
                 (this'postMessage "dockEntity" 
                    (lambda () 
                       (client-goto-docked-workspace this model "<ClassName>Id") 
                    ) 
                  )
               ) 
            ) 
            #t 
         ) 
    )


    where <ClassName> is the name of the class that the dialog allows you to view or edit.

    Info

    The closeScript section should return #t to ensure that the dialog closes properly.

  11. Save your changes

When you have completed these steps, the dialog will allow docking of the class. Carry out unit testing and other testing as required to ensure that the behavior is what you expect.

Special considerations for nested dialogs

Docking behavior is not supported for nested dialogs.

A dialog launched from the main application can have a Save and Dock button but any dialogs launched from dialogs cannot have a Save and Dock button.

You must modify the initScript code of the screens that launch other screens in order to keep those buttons from appearing. This modification should be made to any screen that launches another screen as a dialog.

To update the initScript:

  1. In the Presentation layer, open the screen that launches the secondary screen.
  2. If the secondary screen launches through a script action:
    1. In the Scripts tab, add the following code:

      ; Disable saveAndDock event and hide SaveAndDockButton in a popup if the popup's parent is a popup. 
      ; @arg popupController PopupController The popup controller 
      ; @ret null () Null value is returned for initScript processing 
      (define (disablePopupDocking popupController) 
         ((popupController'findEventModel "saveAndDock")'enabled #f) 
         ((popupController'findView '(Buttons SaveAndDockButton))'visible #f) 
         ((popupController'findView '(Buttons SaveAndDockButton1))'visible #f)
         '() 
      )
    2. In the UI Actions tab, navigate to the event that launches the secondary dialog and update the initScript call to include a call to the disablePopupDocking command that you defined on the Scripts tab. For example:

      (popup'initScript (lambda (this) (disablePopupDocking this) ) )
  3. If the secondary screen launches through a popup action:
    1. In the UI Actions tab, click the popup action that opens the secondary window.
    2. In the Init Script subtab, add the following code to disable the Save and Dock button from appearing on the UI:

      ((this'findEventModel "saveAndDock")'enabled #f) 
      ((this'findView '(frmDockingButtons SaveAndDockButton))'visible #f)
      ; Return null value for initScript processing 
      '()
    3. Save your changes.

After updating the mode with these changes, carry out unit testing and other testing as required to ensure that the behavior is what you expect.