Skip to main content
Skip table of contents

Context: Context bus and sysContext event

Learning objectives

In this lesson, you will learn about communication between portlets, including:

  • Portal bus events: events that can be broadcast between portlets.
  • Context events: shared context between portlets.
  • Global context variables: workspace and global state.

Key concepts

  • The bus is where inter-portal action takes place. We've already seen sysRemove, where an event is raised, potentially with parameters, and we handle the event in a UI action or a data action.
  • The concept of handlers within the same portlet. For example, a button is pressed in a table within a layout and a UI action handles things to show a particular pop-up.
  • Sharing context or events between portlets where we communicate over the portal bus, which is a communication bus that enables us to send and receive events with parameters. An important event is sysContext, which provides a context variable name and value as parameters. One portlet can say "I've changed the EntityId context and it is now Tim Lamont," and other portlets that are listening can respond.
  • Context is shared between portlets. For instance, in the Contacts workspace, the main context variable is EntityId (case is important). There are two types of participants - context setters and context receivers. All portlets with a given context in their context property listen for changes to that context variable.

    CODE
    <Portlet context="EntityId">
       ...
  • A portlet can declare that it is interested in more than one context variable by setting the context property to a space-separated list of context variable names. The second part of the connection is hooking up context changes to a layout in the portlet for receiving or broadcasting. This is done using either the context-form-source (broadcast) function or the context-form-target function (receive).

Layouts were previously called forms, so you will still see some functions with names like (context-form-target and so on).


Based on your work from the previous lesson, your files should appear as follows. They will also include some extra UIEvent and UIAction elements in the training:EntityList.layout file, which are not required for this or future lessons. We recommend that you replace the contents of your training:EntityList.layout file with the code below.

training:Contact.portal

XML
<Portal caption="idsa.training.portal.Contact.caption">
   <Tool name="toolNotifications" caption="ids.notifications" icon="icon:notifications" event="setSidebar" parameter="NOTIFICATIONS"/>   
   <WorkspaceRef name="refSandbox" workspace="training:Sandbox"/>
   <WorkspaceRef name="refHome" workspace="mda:Home"/>
   <WorkspaceRef name="refContacts" workspace="mda:Contacts"/>
   <Drawer event="setSidebar" name="refNotifications" portlet="mda:NotificationDrawer"/>
</Portal>

training:Sandbox.workspace

XML
<Workspace caption="idsa.training.workspace.Sandbox.caption" icon="icon:attach_money">
   <Page name="page">
      <Tab layout="cols:3 fluid:true" name="tabDetail" type="grid">
         <PortletRef name="training_EntityList_portlet" portlet="training:EntityList"/>
      </Tab>
   </Page>
</Workspace>

training:EntityList.portlet

XML
<Portlet>
   <Composite name="composite">
      <LayoutRef layout="training:EntityList" name="training_EntityList_layout"/>
   </Composite>
</Portlet>

training:EntityList.layout

XML
<Layout class="Entity">
   <UIActions>
      <UIAction event="sysProperties">
         <Popup association="tblEntityList" edit="true" screen="training:mda:EntityProperties"/>
      </UIAction>
   </UIActions>
   <Composite name="composite">
      <Table caption="idsa.training.layout.EntityList.caption" name="tblEntityList" rows="(@)">
         <Menu name="mnuRightClick">
            <Item caption="ids.edit2" event="sysProperties" icon="edit" name="mitProperties"/>
			<Item event="sysRemove" name="deleteItem"/>
         </Menu>
         <Column name="colType" caption="idsa.training.layout.EntityList.type" icons="type iconDefault"/>
         <Column name="colIcon" caption="idsa.training.layout.EntityList.icon" icons="(image . image)(data . mimeData)(type . mimeType)" texts="initial"/>
         <Column name="colName" caption="idsa.training.layout.EntityList.name" length="100" values="fullName"/>
      </Table>
   </Composite>
</Layout>

training:mda:EntityProperties.dialog

XML
<Dialog caption="ids.caption.editPopup">
   <Composite cols="2" name="composite">
      <LayoutRef layout="mda:EntityPropertyDashboard" head="true" name="mda_EntityPropertyDashboard_layout"/>
      <Switch caption="ids.detail" head="true" name="grpDetailLayout" span="2" value="mda_EntityPropertyDashboard_layout">
         <Composite case="UserPerson" name="compUser">
            <LayoutRef association="mda_EntityPropertyDashboard_layout" layout="mda:UserPersonEditDetail" head="true" name="mda_UserPersonEditDetail_layout"/>
         </Composite>
         <Composite case="Person" name="compPerson">
            <LayoutRef association="mda_EntityPropertyDashboard_layout" layout="mda:PersonEditDetail" head="true" name="mda_PersonEditDetail_layout"/>
         </Composite>
         <Composite case="Company" name="compOrg">
            <LayoutRef association="mda_EntityPropertyDashboard_layout" layout="mda:CompanyEditDetail" head="true" name="mda_CompanyEditDetail_layout"/>
         </Composite>
      </Switch>
      <LayoutRef association="mda_EntityPropertyDashboard_layout" head="true" layout="mda:EntityAuditFields" name="mda_EntityAuditFields_layout" span="2"/>
   </Composite>
   <Actions layout="mda:PopupButtons" name="mda_PopupButtons_layout"/>
</Dialog>

idsa.training.en.strings

CODE
idsa.training.portal.Contact.caption=My Training Application
idsa.training.workspace.Sandbox.caption=Sandbox
idsa.training.layout.EntityList.caption=Entity List
idsa.training.layout.EntityList.type=Type
idsa.training.layout.EntityList.icon=Icon
idsa.training.layout.EntityList.name=Name

Setting context

Portlets that want to set context, such as a navigator portlet, use the context-form-source script in their initialization. In the following example, the portlet will listen for changes in the EntityList layout and broadcast a sysContext event to the bus for the EntityId context variable.

Example

CODE
(context-form-source (this'view) "EntityId" "training_EntityList_layout")

Receiving context changes

In order to receive context changes so they show up-to-date and correct information, portlets use the context-form-target script in their initialization. In the following example, the portlet listens for sysChange events on the bus to the EntityId context, and updates the EntityDetail layout when that occurs.

Example

CODE
(context-form-target (this'view) "EntityId" "training_EntityDetail_layout" '())

Linked through their association property, other layouts in the portlet associated with this primary layout are also updated.

The arguments to these functions are:

viewViewThe portlet view.
varstringThe context variable name.
layoutstringThe layoutRef name.
argsOptionalAn association or a where clause function in the following format (: association value) or (: whereFunc value)

Learning activity

  1. Update your training:EntityList portlet as follows.

    training:EntityList.portlet

    XML
    <Portlet context="EntityId">
          <Script><![CDATA[(context-form-source (this'view) "EntityId" "training_EntityList_layout")]]></Script>
       <Composite name="composite">
          <LayoutRef layout="training:EntityList" name="training_EntityList_layout"/>
       </Composite>
    </Portlet>

    We added the following to the existing definition:

    • The context property to the portlet so the system knows that our portlet is interested in EntityId.
    • The context-form-source script entry that says, "Set the EntityId context on the context bus based on the current selection in training_EntityList_layout."
  2. Update the Sandbox workspace to include the example AFL bus portlet. This portlet, among other things, displays changes to the EntityId context variable as they occur.

    Sandbox.workspace

    XML
    <Workspace caption="idsa.training.workspace.Sandbox.caption" icon="icon:attach_money">
       <Page name="page">
          <Tab caption="IDS_DETAIL" layout="cols:3 fluid:true" name="spltDetail" type="grid">
             <PortletRef name="training_EntityList_portlet" portlet="training:EntityList"/>
    		 <PortletRef name="aflBus" portlet="app/bus"/>
          </Tab>
       </Page>
    </Workspace>
  3. Save, reload the UI, and reseed.
  4. Click around in the list.
    You will see the results of the EntityList updating the EntityList context variable and the AFL bus app displaying it. 
  5. To listen for the change in an MDA portlet:

    This is almost the same as the work we did in the EntityList portlet, but instead of setting the context, we will respond to it.


    1. Create a new layout called training:EntityDetail and update the layout's source with the following code:

      EntityDetail.layout

      XML
      <Layout class="Entity" caption="idsa.training.layout.EntityDetail.caption">
         <Composite name="composite">
            <Label caption="firstName" head="true" name="lblFirstName"/>
            <Label caption="lastName" name="lblLastName"/>
         </Composite>
      </Layout>
    2. Add the following to the idsa.training.en.strings file.

      CODE
      idsa.training.layout.EntityDetail.caption=Entity Detail

      The layout is bound to the Entity class.

    3. Create a new portlet called EntityDetail.portlet which will listen to the EntityId context, contain the layout, and set the context of the layout whenever a change is detected. Update the source of the portlet with the following code:

      training:EntityDetail.portlet

      XML
      <Portlet context="EntityId">
         <Script><![CDATA[(context-form-target (this'view) "EntityId" "training_EntityDetail_layout" ())]]></Script>
         <Composite name="composite">
            <LayoutRef layout="training:EntityDetail" name="training_EntityDetail_layout"/>
         </Composite>
      </Portlet>
      

      The portlet is using the context-form-target function to set the current entity for the layout.

    4. Add the new portlet to the workspace. Update the source of the training:Sandbox.workspace as follows:

      training:Sandbox.workspace

      XML
      <Workspace caption="idsa.training.workspace.Sandbox.caption" icon="icon:attach_money">
         <Page name="page">
            <Tab caption="IDS_DETAIL" layout="cols:3 fluid:true" name="spltDetail" type="grid">
               <PortletRef name="training_EntityList_portlet" portlet="training:EntityList"/>
               <PortletRef name="training_EntityDetail_portlet" portlet="training:EntityDetail"/>
               <PortletRef name="aflBus" portlet="app/bus"/>
            </Tab>
         </Page>
      </Workspace>
  6. Stop and restart your server.
  7. Re-seed and refresh your browser. As you click through the list, you should see the Entity Detail portlet updating its values to match the selected entity.




JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.