Editor's note: Know a lot about this topic? Want to share your expertise? Participate in the IBM Lotus software wiki program today.
| IBM Mashup Center wiki |
|---|
IBM Mashup Center provides many ready-to-use widgets that you can use for building mashup applications. You can use these widgets to display data in a grid, a line chart, and even on a map. Sometimes more customization to the graphical user interface (GUI) display is wanted, and the available settings in the existing widgets are not sufficient.
There are multiple ways to develop your own customized widgets. IBM Mashup Center comes with Lotus Widget Factory, a great GUI tool for developing custom widgets without writing code. If you are familiar with JavaScript, Dojo, or other programming languages, you can develop custom widgets by writing code according to the iWidget specification. The iWidget framework is flexible, and it allows seamless integration with other technologies. In this article, you learn how to integrate Adobe Flex applications with IBM Mashup Center to significantly enhance the power of your mashup.
You should have a basic knowledge of the iWidget framework and Adobe Flex programming.
Flex is a popular open source framework for building rich Internet applications, and these applications can run in most browsers using the Adobe Flash Player. Flex provides many GUI interface components. Figure 1 shows a sample Flex dashboard application with interactive and animated charts.
Figure 1. Flex sales dashboard demonstration
To run the Flex application in a browser, all you need to do is embed an object tag to an HTML page. This tag is used to load the Flash player and pass in the proper parameters. Listing 1 is an example of what the script looks like.
Listing 1. Embedding an object tag to an HTML page
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="BasicDataGrid" width="482" height="348" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab"> <param name="movie" value=" http://drill.svl.ibm.com/mashuphub/demo/Flex/FlexDataGridSample.swf"/> <param name="wmode" value="opaque"/> <param name="quality" value="high"/> <param name="bgcolor" value="#869ca7"/> <param name="allowScriptAccess" value="always"/> <embed src= "http://drill.svl.ibm.com/mashuphub/demo/Flex/FlexDataGridSample.swf" quality="high" bgcolor="#869ca7" width="482" height="348" name="BasicDataGrid" align="middle" play="true" loop="false" wmode="opaque" allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer"> </embed> </object> |
You can learn more about Flex on the Adobe site.
Flex application development environment
Adobe provides various tools for developing Flex applications. Flex Builder is an Eclipse-based IDE that provides many great features such as code completion, step-through debugging, and drag-and-drop design of visual layouts. A free SDK is also available as an alternative to the commercial Flex Builder. Refer to the Adobe site for more details on Adobe tools.
Developing Lotus Mashups iWidgets
The IBM Mashup Center wiki provides useful information about widget development.
For developers who are new to iWidgets, this presentation is the best place to start.
Details of iWidget development are beyond the scope of this article, but let's review the key components of an iWidget that are relevant to integrating with Flex applications: the widget definition XML file and the widget JavaScript class file.
This file serves several purposes:
- Specifies the JavaScript class file:
<iw:resource uri="FlexWrapper.js"/> - Defines the events that this widget should publish. Listing 2 shows that this widget publishes an event named sendData.
Listing 2. Defining the events that a widget publishes
<iw:event id="sendData" published="true"
eventDescName="desc_sendData" />
<iw:eventDescription id="desc_sendData" payloadType="any"
description="This event sends data out." lang="en"> </iw:eventDescription>
|
- Defines the events that this widget should handle, and the method that is called when the event is received. Listing 3 shows that this widget can receive an event named receiveData, which triggers the function handleData.
Listing 3. Defining the events that a widget handles
<iw:event id="receiveData" handled="true"
onEvent="handleData" description="receiveDataDesc"/>
<iw:eventDescription id="receiveDataDesc" payloadType="any"
description="Receive some data" lang="en">
</iw:eventDescription>
|
- Defines what should display in the view mode of the widget. This display is the main interface shown when the widget is loaded on the mashup page. In this example, shown in listing 4, the view of the widget holds a <div> tag that displays "Hello.". At run time, you can manipulate the inner HTML code of this tag using JavaScript to display other content.
Listing 4. Defining the content of the view mode
<iw:content mode="view">
<![CDATA[
<div id="_IWID_FlexDiv">
Hello.
</div>
]]>
</iw:content>
|
- Defines what should display in the edit mode, or settings, of the widget. The settings tag usually contains a few HTML input element for users to enter some values, and it also includes a save and cancel button as shown in listing 5.
Listing 5. The settings tag in the edit mode
<iw:content mode="edit">
<![CDATA[
<table>
<tr>
<td>Settings 1:
</td>
<td><input id="param1" type="text" size="50">
</td>
</tr>
<tr>
<td>Settings 2:
</td>
<td><input id="param2" type="text" size="50">
</td>
</tr>
</table>
<div class="mmDialogBottomArea">
<a
href="javascript:iContext.iScope().cancelConfigData()"
id="_IWID_CONF_CANCEL" class="common_cancel">Cancel
</a>
<input id="_IWID_CONF_SAVE" class="lotusFormButton"
type="button" value="Save" name="save"
onclick="iContext.iScope().saveParams();" >
</div>
]]>
</iw:content>
|
This file contains the implementation of your widget object. The code in this file is responsible for initializing the widget when it is first loaded, and for publishing and handling any events for communicating with other widgets.
Running a simple Flex application in Lotus Mashups
As mentioned earlier, embedding a Flex application inside a Web page requires only that you add an object tag inside an HTML page. IBM Mashup Center provides a ready-to-use widget for embedding HTML fragments in a mashup page.
Follow these steps:
- Locate the widget under Tools, and drag it onto the canvas. See figure 2.
Figure 2. Adding the HTML Markup widget
- Edit the settings, and paste the Flex application script tag of your Flex application as shown in figure 3.
Figure 3. Setting up the HTML Markup widget
- Click Save. The Flex application runs on the mashup page as shown in figure 4.
Figure 4. Running Flex applications in the HTML Markup widget
It’s great to have the ability to display Flex applications using this method. To truly integrate with Lotus Mashups, though, these applications must be able to communicate with other iWidgets. The rest of the article discusses the architecture for setting up the communication framework between Flex applications and other iWidgets.
Integrating Flex applications with Lotus Mashups
To integrate Flex with Lotus Mashup, the key idea is to build a wrapper Lotus Mashup iWidget. This wrapper iWidget serves three purposes:
- Display the Flex application’s user interface.
- Publish iWidget events. When the Flex application wants to send an event, the Flex application first sends the data to this wrapper iWidget, and the wrapper iWidget then publishes the actual event and data to other iWidgets.
- Handle iWidget events. When other iWidgets want to send events to the Flex application, the events are first handled by the wrapper iWidget. Then, the wrapper iWidget forwards the data to the Flex application for further handling.
A sample Flex application and a corresponding wrapper iWidget are provided in the Downloads section of this article. This Flex application contains a data grid with some preloaded data. We show how you can connect this Flex application with other iWidgets, by allowing it to publish and receive events. With the wrapper iWidget, you can send the data selected in the Flex application to another iWidget. Similarly, you can also use other iWidgets to add rows to this Flex application.
The file FlexDataGridSample.mxml contains the Flex application code; see figure 5. The file FlexWrapper.war contains the iWidget and the Flex application binary. This widget can be deployed onto a Mashup Center the same way a regular iWidget could. After the widget is uploaded and added onto a Lotus Mashup page, edit the settings of this widget. For the Flex application URL parameter, the value should be:
http://[yourserver:port]/widgets/FlexWrapper/FlexDataGridSample.swf
Figure 5. Setting up the demo Flex wrapper iWidget
The following sections walk through the important parts of this sample widget to show how this wrapper iWidget and the Flex application are integrated.
Displaying the Flex application inside the wrapper widget
To display the Flex application, inject the object tag inside the view of the widget. In the wrapper iWidget’s definition file, FlexWrapper.xml, you have defined the view section to contain a simple div tag that serves as the placeholder for the Flex application as shown in listing 6.
Listing 6. Defining the view section
<iw:content mode="view">
<![CDATA[
<div id="_IWID_FlexDiv">
</div>
]]>
</iw:content>
|
At run time, the wrapper iWidget constructs the object tag that loads the Flex application. Take a look at the function onview inside the file FlexWrapper.js to see how the tag is constructed. This tag requires many parameters. Most values could be hard-coded, and other values should be provided by the user or generated automatically at run time. For example, the widget wrapper can allow users to pass in the name of the Flex application, location of the Flash file, and the dimension of this widget as shown in figure 5. By allowing users to pass in these variables, you can reuse the widget wrapper for multiple Flex applications, as long as these applications publish and receive the same list of events. The code in listing 7 shows a sample of the tag that you need to generate. The parameters in bold must be generated dynamically. The parameters in italic are passed in by the user, but could be hard-coded if you want.
Listing 7. Sample of the tag
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="XXXXXXXXX" width="482" height="348" codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab"> <param name="movie" value=" http://drill.svl.ibm.com/mashuphub/demo/Flex/FlexDataGridSample.swf"/> <param name="wmode" value="opaque"/> <param name="quality" value="high"/> <param name="bgcolor" value="#869ca7"/> <param name="allowScriptAccess" value="always"/> <param name="FlashVars" value="iWidgetID=XXXXXX"/> <embed src= "http://drill.svl.ibm.com/mashuphub/demo/Flex/FlexDataGridSample.swf" quality="high" bgcolor="#869ca7" width="482" height="348" name="XXXXXXXXXXX" align="middle" play="true" loop="false" wmode="opaque" allowScriptAccess="always" type="application/x-shockwave-flash" FlashVars="iWidgetID=XXXXXXXXXX" pluginspage="http://www.adobe.com/go/getflashplayer"> </embed> </object> |
Let’s look at the parameters that must be generated dynamically. The id attribute of the object tag and the name attribute of the embed tag must be unique throughout a mashup page. Otherwise, when there are multiple instances of this wrapper iWidget on the same page, they have conflicts. The iWidget framework generates a unique ID for every widget loaded on the page, and this widget ID can be retrieved by calling:
this.iContext.widgetId
We will use this ID as part of the object tag’s ID and name to make sure each instance of the widget wrapper gets a unique ID. Inside the onview function of the Flex wrapper, you can see that you retrieved this widget ID and saved in the variable domID. We are concatenating the Flex application’s name with the widget ID, and you set this string as the ID and name of the tag:
this.flexAppName + this.domID
This way, each instance of the wrapper iWidget gets a uniquely named tag. The final parameter that needs to be generated dynamically is the value for FlashVars. The variables defined in FlashVars are accessible from inside the Flex application. At run time, the Flex application needs to locate the correct instance of the wrapper iWidget object, based on the unique widget ID. We save the widget ID under a variable named iWidgetID, and in a later section you can see how the Flex application retrieves this value.
After you have finished constructing the object tag with the correct parameter values, you can embed it inside the Flex application placeholder div tag by calling:
dojo.byId(this.domID + "FlexDiv").innerHTML = flexDivHTML;
Now when the widget loads and triggers the onview function, it displays the Flash application as shown in figure 6.
Figure 6. Displaying the Flex interface inside an iWidget
Sending events from Flex to other widgets
Most of the user interface components in Flex can handle user events. For example, the DataGrid component triggers an event whenever users click a particular row. In this example, when users click a row, you want to send the data in the selected row out to another iWidget. To achieve this task, you need to perform three steps:
- Define an event to publish inside the widget definition XML (see the file FlexWrapper.xml).
- Implement the JavaScript function that publishes this event in the wrapper iWidget implementation.
- Inside the Flex application, call the JavaScript function when you want to send an event.
To define an event, add the code snippet in listing 8 to the widget definition XML, the same way as you would do in a normal iWidget.
Listing 8. Defining an event
<iw:event id="sendData" published="true"
eventDescName="desc_sendData" />
<iw:eventDescription id="desc_sendData" payloadType="any"
description="This event sends data out." lang="en"> </iw:eventDescription>
|
To publish an event, all you need is one line of code. The function sendData publishes the event using the code shown in listing 9.
Listing 9. Publishing an event
sendData : function(data) {
if(data != null){
this.iContext.iEvents.publishEvent("sendData", data);
}
}
|
The last step is to call this sendData JavaScript function from the Flex application. Inside the flex application, you first define the Flex event handler for the data grid component as normal. When users click a row, the function sendData is called:
<mx:DataGrid id="dgPeople" x="10" y="10" initialize="initDG()"
width="422" height="268" click="sendData()">
Inside the function sendData, you need to locate and call the JavaScript function to publish the event. Listing 10 shows how.
Listing 10. Locating and calling the JavaScript function
public function sendData():void
{
if (ExternalInterface.available) {
ExternalInterface.call(Application.application.parameters.iWidgetID +
"iContext.iScope().sendData", dgPeople.selectedItem);
}
}
|
As you can see, only a few lines of codes are needed to trigger the JavaScript function. ExternalInterface is a Flex object that allows you to call objects outside the Flex application. To locate the appropriate wrapper iWidget, you call:
Application.application.parameters.iWidgetID +
"iContext.iScope().sendData"
Does the value iWidgetID sound familiar? That is the value that you set up in the previous section. You set it inside the FlashVars parameter, and now the Flex application can retrieve it and locate the correct function to call. The value dgPeople.selectedItem contains the selected row in the data grid, in JSON format. Figure 7 shows the overall architecture.
Figure 7. Publishing events from Flex through the wrapper
You can wire the wrapper iWidget to a regular Event Explorer widget. When users select a row from the Flex Wrapper widget, the data is sent as JSON to the Event Explorer as shown in figures 8 and 9.
Figure 8. Wiring the Flex wrapper to an Event Explorer
Figure 9. Sending data from Flex to Event Explorer
Handling events from other widgets in Flex
Handling iWidgets events inside Flex can be done in a similar manner. To achieve this task, you need to perform four steps:
- Define the events to handle inside the wrapper iWidget.
- In the Flex application, implement an event handler, just as in any other Flex applications. For your data grid sample, you create a handler named receiveData that accepts a few strings and adds a row to the grid.
- In the Flex application, register a callback function to expose the event handler receiveData. This callback allows the wrapper iWidget to trigger this function when an event is received.
- Implement the event handler inside the wrapper iWidget to call the Flex callback function.
The wrapper iWidget first defines the events it receives in the XML implementation file. See listing 11.
Listng 11. Defining the events
<iw:event id="receiveData" handled="true"
onEvent="handleData" description="receiveDataDesc"/>
<iw:eventDescription id="receiveDataDesc" payloadType="any"
description="Receive some data" lang="en">
</iw:eventDescription>
|
This code allows other widgets to pass data to the wrapper iWidget. When an event is received, it triggers the handleData function (which is implemented later).
You need first to implement a handler in Flex. In this sample’s Flex data grid, you display the name, title, and age of a few employees. You implement a handler to add an extra employee to the list as shown in listing 12.
Listing 12. Adding an employee
public function receiveData(name:String, title:String,
age:String):void
{
(dgPeople.dataProvider as ArrayCollection).addItem(
{Name: name, Title: title, Age: age});
}
|
The variable dgPeople in listing 12 is a reference to the Flex data grid object that displays the people list. How does JavaScript trigger Flex functions? All you need to do is add a callback. You first create a function named initApp() that is triggered when the Flex application initializes as shown in listing 13.
Listing 13. Adding a callback
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" width="482" height="348"
initialize="initApp()">
|
Inside initApp(), you add a callback to expose the function receiveData shown in listing 14.
Listing 14. Adding a callback to expose the receiveData function
public function initApp():void
{
if (ExternalInterface.available)
ExternalInterface.addCallback("receiveData", receiveData);
}
|
The final step is to implement the iWidget event handler to trigger the Flex callback. To locate the Flex callback, you first need to locate the Flex application by its tag name. In the section "Displaying the Flex application inside the wrapper widget," you specified the ID of the Flex wrapper widget tag to be this.flexAppName + this.domID. This is the ID that you use to locate the Flex application. The code snippet shown in listing 15 locates the Flex application and triggers the receiveData function.
Listing 15. Locating the Flex application and triggering the receiveData function
handleData: function(JSONpayload) {
var data = eval('(' + JSONpayload.payload + ')');
this.getFlexApp(this.flexAppName + this.domID).receiveData(
data.Name, data.Title, data.Age);
},
getFlexApp: function(appName) {
if (navigator.appName.indexOf ("Microsoft") !=-1) {
return window[appName];
} else {
return document[appName];
}
}
|
The handleData function is implemented to handle JSON data, but you can customize it to handle other data types if you choose. Figure 10 shows the outline of the architecture.
Figure 10. Handling iWidget events in Flex
You are now ready to wire this widget to handle some events. For this example, you can use the User Input widget, to create a form so that you can enter new employee data. you can then wire the entered values as JSON to the Flex wrapper widget. Follow these steps:
- Drag a User Input widget from the Favorites drawer as shown in figure 11.
Figure 11. Adding the User Input widget
- Edit the settings to add three textboxes named Name, Title, and Age as shown in figure 12.
Figure 12. Setting up the User Input widget
- Wire the User Input widget to the Flex wrapper iWidget as shown in figure 13.
Figure 13. Wiring the User Input widget to the Flex wrapper
- Now the widgets are connected. Enter the name of a new person in the User Input widget, click Submit, and the new name shows up in the Flex data grid as shown in figure 14.
Figure 14. Sending data from User Input widget to the Flex wrapper
Congratulations! You have successfully wrapped a Flex application inside an iWidget, and the Flex application can now publish and handle iWidgets events and communicate with other iWidgets.
In this article, you walked through the architecture that can integrate Flex applications with IBM Mashup Center. The key idea to integrate Flex with iWidgets is to build a wrapper iWidget. With this wrapper iWidget, Flex applications can publish events to other iWidgets and can handle events from other iWidgets. The sample application demonstrates how to send content inside a Flex data grid object to an Event Explorer iWidget; it also shows how to receive content entered into a User Input iWidget and add it to the Flex data grid. Using the mechanisms described in this article, other Flex user interface components, such as tree views, charts, and more, can be integrated with IBM Mashup Center. Mashup creators can enhance the features of their mashups by taking advantage of the capability of Flex.
| Name | Size | Download method |
|---|---|---|
| FlexDataGridSample.mxml | 1.98KB | HTTP |
| FlexWrapper.zip | 986KB | HTTP |
Information about download methods
- Participate in the discussion forum.
-
Learn more about the iWidget Specification.
-
Learn more about IBM Mashup Center.
-
Read and contribute to the IBM Mashup Center wiki.
-
Learn more about IBM Lotus Mashups.
-
Learn more about Adobe Flex.
-
Check out free video training for Flex development.
Comments (Undergoing maintenance)





