Integrate third-party widgets with IBM ECM Widgets, Part 2: Using the Content List widget to display documents and to change search events

There are numerous enhancements in the IBM ECM Widgets 4.5.2 release, including the Content List widget event enhancements. The new events enable displaying documents, changing the search, requesting selected rows, sending selected rows, and creating custom actions. This article, the second in the series about integrating third-party widgets, describes how you can use the new events in the Content List widget to add value to your business.

Xin Yu Zhou (zhouxinyu@cn.ibm.com), Software Engineer, IBM  

Photo of Xin ZhouXin Yu Zhou is a software engineer in IBM China Software Development Lab (CSDL). He works on IBM FileNet products development in IBM Information Management.



Gai Li (ligai@cn.ibm.com), Software Engineer, IBM

Photo of Gai LiGai Li is a Software Engineer in IBM China Development Lab. She has rich development experience in widget, Dojo, and Web 2.0 applications.



26 August 2010

Also available in Chinese

Introduction

The Content List widget in the 4.5.2 release supports five new events:

  • Display documents (com.ibm.ecmwidgets.ce.ReceiveDocumentIDs)
  • Change search (com.ibm.ecmwidgets.ce.ReceiveStoredSearch)
  • Request selected rows (com.ibm.ecmwidgets.ce.RequestSelectedRows)
  • Send selected rows (com.ibm.ecmwidgets.ce.SendSelectedRows)
  • Custom actions (com.ibm.ecmwidgets.ce.<CustomActionName>)

The com.ibm.ecmwidgets.ce.Xxx is the programming name for the event. For the Custom Actions event, the business analyzer creates the names when designing the business solution.

This article shows you how to make use of the Display Documents event and the Change Search event to fulfill your business needs.

The Display Documents event and the Change Search event are handler (or receiving) events.

  • You can use the Display Documents event to join your data with a third-party data source, such as a widget. The event generates a document list that merges the data from the Content Engine repository and the third-party data source.
  • You can use the Change Search event to receive stored search parameters using an event payload and then retrieve documents with a newly stored search URL carried by the passed-in parameters. This event is an enhanced feature of the stored search function. It is driven by a pre-configured, stored search URL of the IBM ECM Widgets 4.5.1.

Using the Display Documents event

One of two types of business scenarios most commonly make use of the Display Documents event.

Scenario 1
A business analyzer can design a customized widget to populate the Content List widget by passing in a list of Content Engine document IDs. The Content List widget would retrieve a set of documents from the Content Engine whose IDs match those passed in. The properties of these documents are specified in the payload, and these properties are populated in the Content List widget. For example, a company that maintains some Content Engine document IDs in a separate database could use the Content List widget to retrieve documents and to provide viewing, check-in, and check-out to the business analyzer. The business analyzer could leverage this feature to fulfill the requirement.
Scenario 2
Similar to Scenario 1, a business analyzer can provide additional data from the customized widget along with document IDs and display both document properties and the additional data in the Content List widget.

Payload

The name of the payload defined for this event is PropertyList, which contains four parts: objectStoreNames, symbolicNames, externalColumns, and values, as shown in Listing 1.

Listing 1. PropertyList payload
<iw:payloadDef name="PropertyList">
       <iw:payloadDef name="objectStoreNames" type="any" defaultValue="" 
       description=""/>
       <iw:payloadDef name="symbolicNames" type="any" defaultValue="" 
       description=""/>
       <iw:payloadDef name="externalColumns" type="any" defaultValue="" 
       description=""/>
       <iw:payloadDef name="values" type="any" defaultValue="" description=""/>
</iw:payloadDef>

Although the types of these four sub-payloads are any, they still have specific formats as follows:

objectStoreNames
An array that defines search scope, that is, the object stores to be searched
symbolicNames
An array that defines document properties to be returned. The elements of the array are the Content Engine document property symbolic names.
externalColumns
An array that defines property names and types provided by external data sources. Each array element is a JSON object that includes a symbolic name, a display name, and a property type. The display names serve as column headers in the Content List widget.
values
An array that defines the Content Engine document Version Series IDs and the additional data attached to each document provided by external data sources. Each element of the array is a JSON object. Typically, each element contains a VersionSeries that defines the document Version Series ID. If there are additional properties defined in the externalColumns section, the values of each property will be defined as a name/value pair. Note that it is not necessary to specify the version information because the query only returns the documents in released versions. If no released version document exists for a given Version Series ID, no document will be returned for that Version Series ID.

Listing 2 shows a PropertyList payload sample.

Listing 2. PropertyList payload sample
{
    "objectStoreNames": ["XObjectStore"],
    "symbolicNames": ["CompanyName", "DocumentTitle"],
    "externalColumns": [
       { "symbolicName": "SerialNumber", "name": "Serial Number", "type": "string" },
       { "symbolicName": "PurchaseCode", "name": "Purchase Code", "type": "string" }
    ],
    "values": [
       {"VersionSeries": "{B99F251C-0F2F-48A8-A828-C0730EE27A26}", 
       "SerialNumber": "1003", "PurchaseCode": "1003ABC"},
       {"VersionSeries": "{C3766EB7-64F2-4995-A33C-41F4AE26B317}", 
       "SerialNumber": "1004", "PurchaseCode": "1004ABC"}
    ]
}

The payload in Listing 2 indicates that the event publisher would want to retrieve two released documents from a Content Engine Object Store XObjectStore. The Version Series IDs for the released documents are {B99F251C-0F2F-48A8-A828-C0730EE27A26} and {C3766EB7-64F2-4995-A33C-41F4AE26B317}. The Content List will return the document property CompanyName and DocumentTitle, and attach additional data for each document.

For the first document, two properties would be attached:

  • Property SerialNumber for which the display name is Serial Number and the value is 1003
  • Property PurchaseCode for which the display name is Purchase Code and the value is 1003ABC

For the second document, two properties would be attached:

  • Property SerialNumber for which the display name is Serial Number and the value is 1004
  • Property PurchaseCode for which the display name is Purchase Code and the value is 1004ABC

Sample widget

This section describes how to create a new widget to illustrate Scenario 2. This widget provides an input field for a user to enter a company name. After obtaining the company name, the widget fetches data from the server side and composes a PropertyList payload. The widget then publishes the Display Documents (com.ibm.ecmwidgets.ce.ReceiveDocumentIDs) event to the Content List widget. Once the Content List widget obtains the payload, it retrieves documents and displays the document properties along with the external data.

Typically, a widget uses an XML file and a JavaScript file to provide definitions that describes the widget's behavior. The XML file mainly addresses the widget definition, while the JavaScript file defines the widget's behaviors and publishes or handles the events.

SampleWidget1.xml

Listing 3 shows the XML of the first sample widget. There are three items defined in the XML file: the JavaScript resource file that the widget refers to, the event, and the widget user interface.

Listing 3. SampleWidget1.xml
<iw:iwidget name="SampleWidget1" xmlns:iw="http://www.ibm.com/xmlns/prod/iWidget" 
iScope="com.ibm.im.ecmwidgets.sample.SampleWidget1" allowInstanceContent="true" 
supportedModes="view" mode="view">
    <!-- Resource references -->
    <iw:resource uri="SampleWidget1.js"/>
    
    <!-- Event definition section -->
    <!-- Send Documents Info is used to wire with Content List to send the documents 
    information as the input -->
    <iw:event id="Send Documents Info" published="true" 
    eventDescName="SendDocumentsInfo"/>
    <iw:eventDescription id="SendDocumentsInfo" payloadType="any" 
    description="" lang="en"/>
    
    <!-- Initial widget content -->
    <!-- An text type input and a button in it to trigger the event -->
    <iw:content mode="view">
       <![CDATA[
       <div id="_IWID_view">
          <b>companyName:</b>&nbsp;&nbsp;<input 
          dojo.Type="dijit.form.TextBox" id="companyName" style="60%">
          &nbsp;&nbsp;<label>Input a companyName, such as 
          "IBM" or "ECM" or "FN".</label><br>
          <input type="button" dojo.Type="dijit.form.Button" 
          id="mybutton" name="submit" value="Submit"/>
       </div>
       ]]>
    </iw:content>
</iw:iwidget>

SampleWidget1.js

Listing 4 shows the JavaScript of the first sample widget. The widget’s behavior and the methods to publish the events are illustrated.

Listing 4. SampleWidget1.js
dojo.require("dojo._base.xhr");
dojo.require("dijit.form.TextBox");
dojo.require("dijit.form.Button");
    
dojo.provide("com.ibm.im.ecmwidgets.sample.SampleWidget1");
 
dojo.declare("com.ibm.im.ecmwidgets.sample.SampleWidget1", null, {
    
    //onLoad function is invoked after the widget is loaded
    //define the button behavior here
    onLoad: function() {
       var button = dojo.byId("mybutton");
       dojo.connect(button, "onclick", dojo.hitch(this, this.SendEvent));
    },
    
    SendEvent: function(){
       var companyName = dojo.byId("companyName").value;
       this.handle(companyName);
    },
    
    handle: function(companyName) {
       dojo.xhrGet({
          url: "/SampleWidget1/SampleService.jsp?companyName="+companyName,
          handleAs: "json",
          sync: true,
          timeout: 5000,
          handle: dojo.hitch(this, function (result, io_arg) {
             this.result = result;
          })
       });
    
       var payload = this.result;
       this.iContext.iEvents.fireEvent("Send Documents Info", "any", payload);
    }
});

SampleService.jsp

The JSP in Listing 5 simulates a backend service. It returns the corresponding JSON formatted data back to the requester based on the posted company name. The data is hard coded in this sample. You will need to replace the hard-coded data with what you have in your Content Engine.

Listing 5. SampleService.jsp
<%@page contentType="text/html;charset=UTF-8"%>

<%
    //This is a sample service.
    String companyName = (String)request.getParameter("companyName");
        
    int i=0;
    
    if(companyName.equals("IBM")) i=1;
    else if(companyName.equals("ECM")) i=2;
    else if(companyName.equals("FN")) i=3;
    else if(!companyName.equals("IBM") && !companyName.equals("ECM") 
    && !companyName.equals("FN") && !companyName.equals("")) i=4;
        
    String result = "";
                             
    switch(i){
        case 1:
            result = 
"{'objectStoreNames': ['os4']," + 
"'symbolicNames': ['CompanyName', 'DocumentTitle']," +
"'externalColumns': [{ 'symbolicName': 'SerialNumber', 'name': 'Serial Number', 
                            'type': 'string' }," +
              "{ 'symbolicName': 'PurchaseCode', 'name': 'Purchase Code', 
                            'type': 'string' }]," +
"'values': [{'VersionSeries': '{8AF9A9AD-0BEE-4F47-8555-41B7EC4E5140}', 
        'SerialNumber': '1002', 'PurchaseCode': '1002ABC'}," + 
         "{'VersionSeries': '{6D3142CC-92AB-4A2C-B446-6FA1C0F9747E}', 
        'SerialNumber': '1005', 'PurchaseCode': '1005ABC'}," +
         "{'VersionSeries': '{54C72465-4E7F-433E-A146-B447B8C9EE5E}', 
        'SerialNumber': '1010', 'PurchaseCode': '1010ABC'}," +
         "{'VersionSeries': '{38BE6F59-A723-4576-A895-FD7873E59469}', 
        'SerialNumber': '1012', 'PurchaseCode': '1012ABC'}," +
         "{'VersionSeries': '{2C10F8DE-CA9C-408D-8F83-27E2713EE47F}', 
        'SerialNumber': '1020', 'PurchaseCode': '1020ABC'}]" +
"}";
            
            break;
            
        case 2: ...
        case 3: ...
        case 4: ...
        default:...
    }
	out.println(result);
%>

Configure and deploy the widget for the Display Documents event

The IBM ECM Widgets 4.5.2 are developed to operate in an IBM WebSphere® Business Space 7 container. Complete the following steps to deploy the sample widget into the same IBM WebSphere Business Space 7.

  1. Build the web application source files SampleWidget1.js and SampleWidget1.xml into an EAR file in the directory SampleWidget1.war/catalog/com/ibm/im/ecmwidgets/sample, as shown in Figure 1.
Figure 1. EAR file structure
Screen cap: Explorer style hierarchy
  1. Package the EAR file, a catalog file, and an endpoints file into a ZIP file, as shown in Figure 2.
Figure 2. ZIP file structure
Screen cap: catalog folder with catalog_SampleWidget1.xml, ear folder with SampleWidget1.ear, and endpoints folder with SampleWidget1Endpoints.xml

The catalog_SampleWidget1.xml and SampleWidget1Endpoints.xml are used to provide information to register the widget in the IBM WebSphere Business Space 7. Note that the name of the catalog file must start with the prefix catalog_.

Listing 6. The catalog xml file fragment
<catalog id="SampleWidget1">
        <resource-type>Catalog</resource-type> 
        <category name="SampleWidget1"> 
        ... ...
  1. Deploy the widget with the IBM WebSphere Business Space 7 commands in a Windows® command window. You might need to modify the path according to your system and where you put the zip file.
Listing 7. Deploy commands
C:\> cd <WAS_install_path>\profiles\<profile_name>\bin
C:\> wsadmin -connType NONE C:\>$AdminTask installBusinessSpaceWidgets
     {-serverName server1 -nodeName WMADBS7Node01 -widgets C:\ SampleWidget1.zip}
C:\> $AdminConfig save
  1. Restart the IBM WebSphere Application Server.
  2. Configure the widget in the IBM WebSphere Business Space 7.

After you restart the server, you will find that the widget becomes available when you edit a page, as shown in Figure 3.

Figure 3. Widget registered
Screen cap shows SampleWidget1 icon highlighted
  1. Drag the widget into the Content List widget page, which is Sample Widgets Space for the example, as shown in Figure 4.
Figure 4. Add the widget in a page
Shows Sample Widgets Space with tabs for Sample Widget 1 and Sample Widget 2
  1. Open the Content List widget configuration panel, and select the Property list radio button, as shown in Figure 5, which indicates that the Content List widget can accept the com.ibm.ecmwidgets.ce.ReceiveDocumentIDs event that receives the event's payload Property list. If you select the Stored Search radio button, the Content List widget ignores any com.ibm.ecmwidgets.ce.ReceiveDocumentIDs event.
Figure 5. Property list mode in the Content List widget
Screen cap: Property List radio button selected and indicates 15 items per page to display
  1. Enable events by selecting the Send Documents Info publishing event from the Sample widget and wiring it with the Display documents event of the Content List widget in the IBM WebSphere Business Space 7 wiring window, as shown in Figure 6.
Figure 6. Wire the widget
Sample Widget 1 wired to Content List

Widgets in runtime

After you configure and deploy the widgets, the widgets are in runtime mode and searchable. In the sample widget, input a company name and click Submit to send payload to the content list. The Content List widget fetches a list of released documents with the IDs passed in and displays the document and external properties, as shown in Figure 7.

Figure 7. Show the search result
Screen cap: Sample Widget 1 form at the top with content list containing document titles, company names, and so on

The Change Search event is a new capability in the ECM Widgets 4.5.2 release. It is an extension of the store search function. In the ECM Widgets 4.5.1 release, a Content List widget can only search based on a pre-configured store search URL. With the Change Search feature in the 4.5.2 release, a Content List widget can use the payload to construct a store search URL dynamically and to run a new search.

Scenario

In this example scenario, a Business Analyzer defines several store searches in the Content Engine and wants to use them to search for documents in a Content List widget dynamically. The Business Analyzer would create a widget to pass the store search URL parameters to the Content List widget by sending the com.ibm.ecmwidgets.ce.ReceiveStoredSearch event.

The com.ibm.ecmwidgets.ce.ReceiveStoredSearch event is a new inbound event of the Content List widget. This event can carry the vsId, the releaseId, and the ObjectStore name of a stored search as its payload. The Content List widget can populate a new search list for a new stored search after receiving this event. Listing 8 shows the StoredSearch payload definition for the scenario.

Listing 8. StoredSearch payload definition
<iw:payloadDef name="StoredSearch">
        <iw:payloadDef name="version" type="string" defaultValue="" 
        description="Version information"/>
        <iw:payloadDef name="vsId" type="string" defaultValue="" 
        description="Version Series ID"/>      
        <iw:payloadDef name="objectStoreName" type="string" defaultValue="" 
        description="Object Store Name"/>
</iw:payloadDef>
<iw:event id="Receive Stored Search" handled="true" 
onEvent="handleReceiveStoredSearch" eventDescName="ReceiveStoredSearchDescription"/>
<iw:eventDescription id="ReceiveStoredSearchDescription" payloadType="StoredSearch" 
description="" lang="en"/>

The ReceiveStoredSearch event works the same way the stored search event works. The following five conditions need to be met for a new search to execute properly.

  • The event must be manually wired. If there is no event wiring, the Content List widget uses the configured stored search URL in the configuration panel.
  • If the event is wired and a payload is received but the payload is not a StoredSearch payload, the Content List widget uses the configured stored search URL.
  • If the event is wired and a valid payload is received, the Content List widget populates the list with the received stored search parameters. Even though the stored search URL is configured, the list is replaced.
  • Received event data is retained until the user logs out or refreshes the page. After the refresh or re-login operation, the Content List widget switches back to use the configured URL until the widget receives the next event with a valid payload.
  • When the Content List widget uses the stored search parameters passed in, it can also handle the Receive Search Values event and use the payload to replace the search criteria of the received store search.

Sample widget code for the scenario

This sample widget shows how to create a widget to publish the com.ibm.ecmwidgets.ce.ReceiveStoredSearch event and pass in a stored search at runtime. The sample configuration also shows how to leverage both com.ibm.ecmwidgets.ce.ReceiveStoredSearch and Receive Search Values events to change the search criteria of a received stored search event.

SampleWidget2 has three input fields that carry the information of a pre-defined stored search. The information includes the version series ID, the version, and the object store name, as shown in the XML file in Listing 9.

Listing 9. SampleWidget2.xml
<iw:iwidget name="SampleWidget2" xmlns:iw="http://www.ibm.com/xmlns/prod/iWidget" 
iScope="com.ibm.im.ecmwidgets.sample.SampleWidget2" allowInstanceContent="true" 
supportedModes="view" mode="view">
	<iw:resource uri="SampleWidget2.js"/>
	
	<iw:event id="Send Payload" published="true" eventDescName="SendPayload"/>
	<iw:eventDescription id="SendPayload" payloadType="StoredSearch" description=""
	lang="en"/>
	<iw:payloadDef name="StoredSearch">
		<iw:payloadDef name="version" type="string" defaultValue="" 
		description="Version information"/>
		<iw:payloadDef name="vsId" type="string" defaultValue="" 
		description="Version Series ID"/>
		<iw:payloadDef name="objectStoreName" type="string" defaultValue="" 
		description="Object Store Name"/>
	</iw:payloadDef>
	
	<iw:content mode="view">
        <![CDATA[
		<div id="_IWID_view">
			<b>Version information:</b>&nbsp;&nbsp;
			<input dojo.Type="dijit.form.TextBox" id="version" 
			style="60%">&nbsp;&nbsp;<br>
			<b>Version Series ID:</b>&nbsp;&nbsp;
			<input dojo.Type="dijit.form.TextBox" id="vsId" style="60%">
			&nbsp;&nbsp;<br>
			<b>Object Store Name:</b>&nbsp;&nbsp;
			<input dojo.Type="dijit.form.TextBox" id="objectStoreName" 
			style="60%">&nbsp;&nbsp;<br>
			<input type="button" dojo.Type="dijit.form.Button" 
			id="mybutton" name="submit" value="Submit"/>
		</div>
      	]]>
    </iw:content>
    <iw:content mode="edit">
        <![CDATA[
		<div id="_IWID_edit"></div>
      	]]>
    </iw:content>
</iw:iwidget>

Listing 10 shows the SampleWidget2.js code for the example scenario.

Listing 10. SampleWidget2.js
dojo.require("dojo._base.xhr");
dojo.require("dijit.form.TextBox");
dojo.require("dijit.form.Button");

dojo.provide("com.ibm.im.ecmwidgets.sample.SampleWidget2");

dojo.declare("com.ibm.im.ecmwidgets.sample.SampleWidget2", null, {

	onLoad: function() {
		var button = dojo.byId("mybutton");
		dojo.connect(button, "onclick", dojo.hitch(this, this.SendEvent));
    },

	SendEvent: function(){
	   	var version = dojo.byId("version").value;
		var vsId = dojo.byId("vsId").value;
		var objectStoreName = dojo.byId("objectStoreName").value;
		this.handle(version, vsId, objectStoreName);
    },
	
	handle: function(version, vsId, objectStoreName) {
		var payload = {"StoredSearch":{"version": version, "vsId" : vsId, 
		"objectStoreName":objectStoreName}};
		this.iContext.iEvents.fireEvent("Send Payload", "StoredSearch", payload);
	}
});

Configure and deploy the widget for the Change Search event

Complete the following steps to configure and deploy the widget for the Change Search event in SampleWidget2.

  1. Build the web application sources into an EAR file.
  2. Package the EAR file, a catalog file, and an endpoints file into a ZIP file. The catalog_SampleWidget2.xml and SampleWidget2Endpoints.xml are used to provide information to register the widget in the IBM WebSphere Business Space 7. Note that the name of the catalog file must start with the prefix catalog_.
  3. Deploy the widget with the IBM WebSphere Business Space 7 commands in a Windows® command window.
  4. Restart the IBM WebSphere Application Server.
  5. Add the widget to a page with a Content List widget and an In-basket widget.
  6. Wire the Row Selected event of the In-basket widget with the Search with Work Item event of the Content List widget.
  7. Wire the Send Payload event of the sample widget with the Change Search event of the Content List widget, as shown in Figure 8.
Figure 8. Content List wired with In-basket and the sample widget
In-basket and Sample Widget 2 wired with Content List
  1. In the Content List widget configuration panel, select the Stored search radio button, which indicates that the Content List widget will work in the mode in which it can accept the Change Search and Search with Work Item events, as shown in Figure 9. The Search with Work Item event was introduced in the ECM Widgets 4.5.1 as the Receive Work Item event (see Resources for more details).
Figure 9. Stored search mode in the Content List widget
Screen cap: Stored Search radio button selected and indicates 15 items per page to display
  1. In the SampleWidget2, enter information for a pre-defined stored search, and click Submit. The Content List widget fetches a list of documents with the stored search. In the example scenario, the pre-defined stored search fetches documents by CompanyName, as shown in Figure 10.
Figure 10. Run the Send Payload event from the SampleWidget2
Screen cap: SampleWidget2 with Submit highlighted and Content List populated with documents
  1. In the In-basket widget, select a work item, such as the work item having the CompanyName IBM. The Content List widget replaces the search criteria with CompanyName equals IBM and fetches the documents accordingly, as shown in Figure 11.
Figure 11. Run the Row Selected event from the In-basket widget
Screen cap: IBM highlighted in Inbasket, SampleWidget2 with Submit highlighted, and Content List populated with IBM documents

Conclusion

This is the second part of a four-part series that introduces the IBM ECM Widgets 4.5.2 new widget events. This Part 2 focused on the new Displaying Documents event and the Changing Search event of the Content List widget, describing the design purpose of the new events and how to leverage them with your widgets to gain more business value.

Acknowledgments

Thanks to Simon Chu for reviewing this article. He is an IBM Master Inventor and has been one of our great mentors.


Downloads

DescriptionNameSize
Sample widget 1 codesSampleWidget1.zip5KB
Sample widget 2 codesSampleWidget2.zip4KB

Resources

Learn

Get products and technologies

  • Build your next development project with IBM trial software, available for download directly from developerWorks.

Discuss

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Information management on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Information Management, Java technology, Industries
ArticleID=513145
ArticleTitle=Integrate third-party widgets with IBM ECM Widgets, Part 2: Using the Content List widget to display documents and to change search events
publish-date=08262010