Tuesday, April 29, 2008

Showing dynamic User Interface using Struts2

The main purpose for writing this post is to help understand the compilation process of a Struts2 JSP, and to highlight how useful the OGNL expression can be.

I had to make a form that would display different sets of text-fields in different situations. So I did something like what follows:

Action:
public class ShowDynamicForm extends ActionSupport {

private List fields = new ArrayList (); //will be iterated in the following JSP

public String execute() throws Exception {
//The list: 'fields' can be populated from database depending on requirement
fields.add("name");
fields.add("number");
fields.add("class");
fields.add("result");

return SUCCESS;
}

public List getFields() {
return fields;
}
public void setFields(List fields) {
this.fields = fields;
}
}

JSP: The jsp is the most important artifact to understand. It mainly does the following:
- Iterates the list (populated by ShowDynamicForm action) and
- Dynamically renders labels and text-boxes for the required fields using OGNL expressions.
<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<%-- author: Rushikesh Thakkar --%>

<html>
<body>
<s:i18n name="labels">
<table border="0" bordercolor="gray" cellpadding="5" cellspacing="0">
<tr>

<s:iterator value="fields" status="status" id="field">

<td><s:text name="%{fields[#status.index]}"/></td>
<td><s:textfield name="field.%{fields[#status.index]}" theme="simple" value="%{#status.index}" /></td>
<s:if test="#status.even">
</tr>
</s:if>
</s:iterator>

</table>

</s:i18n>
</body>
</html>

Explanation: First, the OGNL expressions are evaluated in the JSP. This helps
<s:text /> and <s:textfield /> get values for their attributes 'name' and 'value'. So in the first pass
<s:text name="%{fields[#status.index]}"/> becomes
<s:text name="name"></s:text> and similarly for
<s:textfield name="field.%{fields[#status.index]}" theme="simple" value="%{#status.index}" /> for entire itearation.
And then its simple to understand. I am using the following labels.properties file to provide values for
<s:text /> tag.

labels.properties:
name=Student Name
number=Roll No.
class=Class
result:Result

No comments: