Client Side User Preferences Manipulation

I just built a sample Porltet to demonstrate how to use Client Side API for manipulating the User Preferences. You can download the source code for sample from here

This is the screen shot of how my portlet looks like



The portlet has two parts, first part allows you to enter a key value pair and that will be set as preference for user, using client side API and the second part is Current User Preferences, that displays the user preferences for the portlet.

The portlet has one userpref.jsp file that has all the business logic


<%@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 prefStr = "";
for (var i=0; i<prefs.length; i++) {
prefStr = prefStr + prefs[i].name+ " - "+prefs[i].values +"<br/>";
}
dojo.byId("userPref").innerHTML = prefStr;
}else{
console.error("Error in getting preferences");
}
}
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 changePreference(){
console.log("Entering changePreference()");
console.log("Preference Name " + dojo.byId("preferenceName").value);
console.log("Preference Value " + dojo.byId("preferenceValue").value);
var _portletWindow = new ibm.portal.portlet.PortletWindow("<%=portletWindowID%>");
_portletWindow.setAttribute("preferenceName",dojo.byId("preferenceName").value );
_portletWindow.setAttribute("preferenceValue",dojo.byId("preferenceValue").value );
_portletWindow.getPortletPreferences(loadPreferences);

console.log("Exiting changePreference()");
return false;
}
printPreferences();
</script>
<portlet:defineObjects />
<form method="post" onsubmit="changePreference()">
<table>
<tr>
<td>Preference Name</td>
<td><input type="text" name="preferenceName" id="preferenceName" /></td>
</tr>
<tr>
<td>Preference Value</td>
<td><input type="text" name="preferenceValue"
id="preferenceValue" /></td>
</tr>
<tr>
<td><input type="button" onclick="changePreference()"
value="Set Preference" /></td>
<td><input type="button" onclick="printPreferences()"
value="Print Preference" /></td>

</tr>
</table>
</form>
<h4>Current Preferences</h4>
<div id="userPref">
</div>


Getting User Preferences
You can print the user preferences by clicking on "Print Preferences" button. When you do that printPreferences() method will get called. This method get the current PortletWindow object by using constructor like this new ibm.portal.portlet.PortletWindow("<%=portletWindowID%>"). Once you have the PortletWindow object you can call its getPortletPreferences(), and pass it name of the callback function. When you do that the client side API will make a call to server to get preference ATOM feed and once the feed is available it will call the printPreferencesCallback() method.

The printPreferencesCallback() takes three argument PortletWindow, status and PortletPreferences. Status indicates if the request was successful or not, the PortletWindow object is the object that you used for making request. Inside the callback method check if the request was successful if yes then you can start working with portletPref object which is object of ibm.portal.portlet.PortletPreferences. Once you have that object you can use the methods of ibm.portal.portlet.PortletPreferences to manipulate preferences.

The ibm.portal.portlet.PortletPreferences object is equivalent to the javax.portlet.PortletPreference object on the client side and provides near about same methods.



Setting User Preferences

You can set preferences by entering value for "Preference Name" and "Preference Value" and then clicking on "Setting Preferences" button, when you do that it will pass control to changePreference method, which will read values entered by user, then it will create object of PortletWindow and call its getPrefernces method, passing loadPreferences as callback method name.

When the getPreferences() method gets called portal will make HTTP Get call to get portlet preferences in the ATOM feed format, then inside the method i am setting preference by calling portletPrefs.setValue(preferenceName,preferenceValue), but the setValue only udpates the ATOM feed for the preferences. In order to persist these changes on the server you will have to call portletWindow.setPortletPreferences(portletPrefs,printPreferencesCallback) method, passing it the modified preferences object. This method will PUT the modified ATOM feed for portlet preferences to the server side by making HTTP PUT call.

On the server side there is ContentHandler Servlet which takes care of reading ATOM feed and updating the underlying portlet data model.