tags:

views:

209

answers:

1

I have been trying with limited success to code a JSF application. In one section of the application, I need users to select from a select menu which displays a list of selectable status values. The Status class (presented below), which is used to populate the List that is displayed in the select menu, is a simple class made up of two Strings: one is the code used to look up the description in the database, the other is the human-readable description. I am trying to find out if I need a converter here at all, and if so, how best to implement the converter. This is a JSF 1.1 project using Java 1.5

I am using the following code in the JSP:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
 <f:view>
<html>
<h:graphicImage id="image" url="/images/appname.jpg"
 alt="app name" />
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<jsp:include page="/jsp/menu.jsp" />
</head>
<body>

<h:outputText
 value="Add Value"
 style="font-size:20px;" />

<h:messages errorStyle="color: red" infoStyle="color: green"
 layout="table" />

<h:form id="statusReasonEditForm">

 <table>
  <tr>
   <td><h:outputText id="txtvalue" value="Status" /></td>
   <td><h:selectOneMenu id="selectStatus"
    value="#{pc_statusReasonBacker.status}"
    binding="#{pc_statusReasonBacker.selectItem}">
    <f:selectItems value="#{pc_statusReasonBacker.selectStatuses}" />
    <f:converter converterId="statusConverter" />
   </h:selectOneMenu>
   <td><h:outputText id="txtvaluereason" value="Status Reason" /></td>
   <td><h:inputText id="txtinputreason"
    value="#{pc_statusReasonBacker.statusReason.statusReason}"
    maxlength="100" size="40" /></td>
   <td><h:outputText id="txtvaluereasondesc"
    value="Status Reason Desc" /></td>
   <td><h:inputText id="txtinputreasondesc"
    value="#{pc_statusReasonBacker.statusReason.statusReasonDesc}"
    maxlength="100" size="40" /></td>
  </tr>

 </table>
 <tr>
  <td><h:commandButton id="savebutton" value="Save"
   action="#{pc_statusReasonBacker.save}" /></td>
  <td><h:commandButton id="cancelbutton" value="Cancel"
   action="#{pc_statusReasonBacker.cancel}" /></td>
 </tr>

</h:form>
<hr />
</body>
</html>
 </f:view>

The backing bean is shown here (some non-related sections, such as paging, removed for clarity):

public class StatusReasonBacker {

private List<StatusReason> statusReasonList;
private List<Status> statusList;
private List<SelectItem> selectStatuses;
private StatusReason statusReason;
private StatusDao sDao;
private Status status;
private UIData statusReasonTable;
private HtmlSelectOneMenu selectItem;
private String selectedStatus = "";

public StatusReasonBacker() {
 sDao = new StatusDao();
 statusReason = new StatusReason();
 selectStatuses = new ArrayList<SelectItem>();
 status = new Status();
 selectItem = new HtmlSelectOneMenu();
}

public String insert() {
 status.setStatusCde("");
 statusReason.setStatus(status);
 statusReason.setStatusReason("");
 statusReason.setStatusReasonCde("");
 statusReason.setStatusReasonDesc("");
 return "success";
}

public String edit() {
 this.statusReason = (StatusReason) statusReasonTable.getRowData();
 selectItem.setValue(statusReason.getStatus().getStatusCde());
 return "success";
}

public String update() {

 if ("".equalsIgnoreCase(statusReason.getStatusReason().trim())) {
  Message
    .addErrorMessage("You must enter a value for the status reason.");
  return "failure";
 } else if (("".equalsIgnoreCase(statusReason.getStatusReasonDesc()
   .trim()))) {
  Message
    .addErrorMessage("You must enter a value for the status reason description.");
  return "failure";
 }
 sDao.updateStatusReason(statusReason);

 return "statusreasons";
}

public String delete() {
 StatusReason statReason = (StatusReason) statusReasonTable.getRowData();
 sDao.deleteStatusReason(statReason);
 return "statusreasons";
}

public String cancel() {
 return "statusreasons";
}

public String save() {

 statusReason.setStatus(status);
 sDao.insertStatusReason(statusReason);
 return "statusreasons";
}

...

public StatusDao getSDao() {
 return sDao;
}

public void setSDao(StatusDao dao) {
 sDao = dao;
}

public List<StatusReason> getStatusReasonList() {
 statusReasonList = sDao.getStatusReasons();
 return statusReasonList;
}

public void setStatusReasonList(List<StatusReason> statusReasonList) {
 this.statusReasonList = statusReasonList;
}

public UIData getStatusReasonTable() {
 return statusReasonTable;
}

public void setStatusReasonTable(UIData statusReasonTable) {
 this.statusReasonTable = statusReasonTable;
}

public StatusReason getStatusReason() {
 return statusReason;
}

public void setStatusReason(StatusReason statusReason) {
 this.statusReason = statusReason;
}

public List<Status> getStatusList() {
 statusList = sDao.getStatuses();
 return statusList;
}

public void setStatusList(List<Status> statusList) {
 this.statusList = statusList;
}

public List<SelectItem> getSelectStatuses() {

 selectStatuses.clear();
 if (statusList == null) {
  statusList = this.getStatusList();
 }

 for (Status sr : statusList) {

  SelectItem si = new SelectItem();
  si.setValue(sr.getStatusCde());
  si.setLabel(sr.toString());
  si.setDescription(sr.toString());
  selectStatuses.add(si);
 }
 return selectStatuses;
}

public void setSelectStatuses(List<SelectItem> selectStatuses) {
 this.selectStatuses = selectStatuses;
}

public String getSelectedStatus() {
 selectedStatus = statusReason.getStatusDesc();
 return selectedStatus;
}

public void setSelectedStatus(String selectedStatus) {
 this.selectedStatus = selectedStatus;
}

public Status getStatus() {
 return status;
}

public void setStatus(Status status) {
 this.status = status;
}

public HtmlSelectOneMenu getSelectItem() {
 return selectItem;
}

public void setSelectItem(HtmlSelectOneMenu selectItem) {
 this.selectItem = selectItem;
}

 }

Thanks!

+3  A: 

I am trying to find out if I need a converter here at all, and if so, how best to implement the converter.

You need a converter whenever you want to pass non-standard Java Objects from a HTTP request to another HTTP request. With non-standard I mean not a String, Number or Boolean. This all simply because HTTP request parameters can only be Strings. That Number and Boolean works is because EL can recognize them and has built-in coercions for it.

For non-standard Java Objects you need to implement a javax.faces.convert.Converter which converts the Object to a String (or a Number so you want, for example a Long id which can be the PK of the associated row in database table) inside the getAsString() method before displaying in HTML. You do the other way round in the getAsObject() method during processing of the request parameters (e.g. get the associated object from DAO by its id).

You can find here an example of how to use a Converter for a h:selectOneMenu. You see that this article also contains an alternative, but you'll need to do a bit more work in the backing bean to convert (map) the objects yourself.

BalusC