Manipulating Portlet Preferences using Adobe Flex application

I built this PortletPreferencesFlex sample portlet to demonstrate how you can manipulate the Portlet Preferences from the Flex application.

You can download the sample application from here

  1. PortletPreferencesFlex portlet

  2. Portlet Preferences Flex code




The sample portlet has two things first, when you click on the Print Preferences button it will get all the preferences for the user and list them in the Grid. You can add new preference by entering value of preference Name and value and then clicking on the Add preference button.

In this sample application i am using the Client Side API for Preference Management and the JavaScript to Flex communication for getting as well as setting preferences.

I followed these steps to create the sample application

  • First i did develop a FlexPortletPreferences portlet like this

    public class FlexPortletPreferences extends GenericPortlet{
    protected void doView(RenderRequest request, RenderResponse response)
    throws PortletException, IOException {
    System.out.println("Entering FlexPortletPreferences.doView()");
    response.setContentType("text/html");
    getPortletContext().getRequestDispatcher("/preference.jsp").include(request, response);
    System.out.println("Exiting FlexPortletPreferences.doView()");
    }
    }

    This portlet is very simple only thing that it does is pass control to the preference.jsp in the doView() method

  • Then i did develop preference.jsp file like this

    <%@page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1" session="false"%>
    <%@taglib uri="http://java.sun.com/portlet" prefix="portlet"%>
    <%@taglib
    uri="http://www.ibm.com/xmlns/prod/websphere/portal/v6.1/portlet-client-model"
    prefix="portlet-client-model"%>
    <%@taglib uri="http://java.sun.com/portlet" prefix="portletx"%>
    <portlet-client-model:init>
    <portlet-client-model:require module="ibm.portal.xml.*" />
    <portlet-client-model:require module="ibm.portal.portlet.*" />
    </portlet-client-model:init>
    <script language="javascript">
    function printPreferences(){
    var _portletWindow = new ibm.portal.portlet.PortletWindow("<%=portletWindowID%>");
    _portletWindow.getPortletPreferences(printPreferencesCallback);
    }
    function printPreferencesCallback(portletWindow, status, portletPrefs){
    if (status==ibm.portal.portlet.PortletWindow.STATUS_OK) {
    var prefs = portletPrefs.getMap();
    var prefList = new Array();
    for (var i=0; i<prefs.length; i++) {
    console.log(prefs[i].name);
    console.log(prefs[i].values[0]);
    prefList[i] = {"name":prefs[i].name,"values":prefs[i].values[0]};
    }
    getFlexApp('PortletPreferenceFlex').displayPreferences(prefList);
    }else{
    console.error("Error in getting preferences");
    }
    }
    function getFlexApp(appName){
    if (navigator.appName.indexOf ("Microsoft") !=-1){
    return window[appName];
    }
    else{
    return document[appName];
    }
    }
    function loadPreferences(portletWindow, status, portletPrefs){
    console.log("Entering loadPreferences()");
    if (status==ibm.portal.portlet.PortletWindow.STATUS_OK) {
    var preferenceName = portletWindow.getAttribute("preferenceName");
    var preferenceValue = portletWindow.getAttribute("preferenceValue");
    portletPrefs.setValue(preferenceName,preferenceValue);
    portletWindow.setPortletPreferences(portletPrefs,printPreferencesCallback);
    }else{
    alert("Error in loading preference");
    }
    console.log("Entering loadPreferences()");
    }
    function addPreferences(prefName, prefValue){
    console.log("Entering changePreference()");
    console.log("Preference Name " + prefName);
    console.log("Preference Value " + prefValue);
    var _portletWindow = new ibm.portal.portlet.PortletWindow("<%=portletWindowID%>");
    _portletWindow.setAttribute("preferenceName",prefName );
    _portletWindow.setAttribute("preferenceValue",prefValue );
    _portletWindow.getPortletPreferences(loadPreferences);
    console.log("Exiting changePreference()");
    return false;
    }
    </script>
    <portlet:defineObjects />
    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
    id="PortletPreferenceFlex" width="750" height="500"
    codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
    <param name="movie" value='<%=renderResponse.encodeURL(renderRequest.getContextPath()+ "/PortletPreferenceFlex.swf")%>' />
    <embed src="<%=renderResponse.encodeURL(renderRequest.getContextPath() + "/PortletPreferenceFlex.swf")%>"
    width="750" height="500"
    name="PortletPreferenceFlex" align="middle" play="true" loop="false" quality="high"
    type="application/x-shockwave-flash" pluginspage="http://www.adobe.com/go/getflashplayer">
    </embed>
    </object>

    Most of the JavaScript code in this file is same as Client Side User Preferences Manipulation with the difference that it has getFlexApp method which gives me the object of flex application. Inside the printPreferencesCallback method, first i am getting object of Flex application and then calling its displayPreferences() method with Array of the preferences. The displayPreferences() method is implemented in the flex application

  • Last and most important piece of the demo application is the PortletPreferenceFlex.mxml

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    width="100%" height="100%" initialize="initApp()">
    <mx:Script>
    <![CDATA[
    import flash.external.*;
    import mx.controls.Alert;
    public function initApp():void
    {
    if (ExternalInterface.available){
    ExternalInterface.addCallback("displayPreferences", displayPreferences);
    }
    }
    //Event handler for handling button click
    public function getPortletPreference():void
    {
    if (ExternalInterface.available) {
    // Make call to the printPreference method
    ExternalInterface.call("printPreferences");
    } else
    Alert.show("Error sending data!");
    }
    public function displayPreferences(obj:Object):void
    {
    dgPreferences.dataProvider = obj;
    }
    protected function prefValue_clickHandler():void
    {
    if (ExternalInterface.available) {
    // Make call to the printPreference method
    ExternalInterface.call("addPreferences",prefName.text,prefValue.text);
    }
    }
    ]]>
    </mx:Script>
    <mx:Panel id="pnlMain" width="600" height="324" layout="absolute" title="Portlet Preferences Example">
    <mx:Button label="Print Preference" y= "37" id="resourceUrl" click="getPortletPreference()" x="482"/>
    <mx:DataGrid id="dgPreferences" x="10" y="10" width="464" height="100">
    <mx:columns>
    <mx:DataGridColumn headerText="Name" dataField="name"/>
    <mx:DataGridColumn headerText="Values" dataField="values"/>
    </mx:columns>
    </mx:DataGrid>
    <mx:Button x="321" y="123" label="Add Preference" click="prefValue_clickHandler()"/>
    <mx:Label x="13" y="150" text="Preference Value"/>
    <mx:TextInput x="121" y="121" id="prefName"/>
    <mx:Label text="Preference Name" x="10" y="121"/>
    <mx:TextInput x="120" y="148" id="prefValue"/>
    </mx:Panel>
    </mx:Application>


    When user clicks on the Print Preferences button the control get passed to getPortletPreference method inside this method i am using ExternalInterface to call displayPreferences method which is JavaScript method inside preference.jsp.

    The displayPreferences makes call to _portletWindow.getPortletPreferences attaching printPreferencesCallback as callback. Inside that method first i am getting the preferences then converting them into Array and then passing that Array to the displayPreferences method which is part of PortletPreferenceFlex.mxml, which is using that array as data source for the Grid.

    Same thing happens when you click on Add Preference button control gets passed to prefValue_clickHandler method which in turn is passing control to the addPreferences method for actual adding of the preferences