[jboss-user] [JBoss Seam] - Re: What is the common pattern for selecting objects?

grettke_spdr do-not-reply at jboss.com
Fri Jun 8 14:21:54 EDT 2007


Here is what I came up with. I am posting it in order to elicit comments on my approach (code review) and also in case this is right and anyone else needs to  use selectItems with a custom converter when you want to populate it using objects. In the interest of brevity this is not a compilable

In other words, does this look like the typical approahc for solving a problem like this?

This is the object Contact from which folks can choose. This is a once off selection (for now atleast), so these are not persisted. Once one is chosen, it will become an embedded entity.

  | protected String name = "";
  | protected String title = "";
  | protected String role = "";
  | protected String phoneNumber = "";
  | protected String emailAddress = "";
  | 

There are two components: a user facing (form-like) component that stores the users selections (this will become an entity) and then the action.

  | priority1DataUf: the "form" data, users selection goes here
  | priority1RequestAction: the action itself, it also exposes a property that is the list of contacts from which the user may choose "contacts"
  | 

On the page itself:

  | <h:selectOneRadio id="contactSelector"
  |                           value="#{priority1DataUf.contact}"
  |                           layout="pageDirection"
  |                 required="true">
  |             <s:selectItems value="#{priority1RequestAction.contacts}"
  |                            var="contact"
  |                            label="#{contact.title} #{contact.name}: #{contact.phoneNumber}"/>
  |             <s:convertEntity/>
  |             <rms:contactListConverter/>
  |         </h:selectOneRadio>
  | 

Finally, the converter. The converter assumes that it would only be used for Contacts. Contact checks for equality using NAME and TITLE. Those are the values used by the equals method on the class. The lifecycle is that the page gets loaded, and the converters gettAsString is called taking in a Contact and returning the value to populate the html control. That value roughly the key for that object in priority1RequestAction.contacts (althought it is not a map now, perhaps it ought to be). The user makes a selection on the page and submits it, and then the converter takes that key. It gets the value binding for the selectItems and tries to find an object with that key. If it finds it, that value is returned.

  | public Object getAsObject(FacesContext context,
  |                               UIComponent comp,
  |                               String value)
  |             throws ConverterException {
  | 
  |         Object result = null;
  |         try {
  |             if (Contact.validItem(value)) {
  |                 // comp is "this" component, the one in which the tag lives.
  |                 // This converter may live inside, for example, a
  |                 // javax.faces.component.html.HtmlSelectOneRadio
  | 
  |                 // We need to iterate through its children to get the list of Contacts
  |                 // from the <s:selectItems>
  |                 List children = comp.getChildren();
  | 
  |                 for (Object child : children) {
  |                     // Its children include UIComponent(s)
  |                     if (child instanceof UIComponent) {
  |                         UIComponent c = (UIComponent) child;
  |                         // The value binding for a component is the data to which it is
  |                         // bound. An example here is:
  |                         // /priority1.xhtml @118,94 value="#{priority1RequestAction.contacts}":
  |                         // ValueExpression[#{priority1RequestAction.contacts}]
  |                         ValueBinding b = c.getValueBinding("value");
  |                         // The class of the value binding is an interface, java.util.List, since we
  |                         // provide java.util.List<contact>.
  |                         // b.getType(context) -> interface java.util.List
  |                         // At this point we assume it is a list of Contacts
  |                         List<Contact> contacts =
  |                                 (List<Contact>) b.getValue(context);
  |                         for (int i = 0; i < contacts.size(); i++) {
  |                             Contact contact = contacts.get(i);
  |                             if(Contact.getItem(contact).equals(value))
  |                             {
  |                                 result = contact;
  |                                 break;
  |                             }
  |                         }
  |                     }
  |                 }
  |             }
  |         } catch (Exception e) {
  |             throw new ConverterException(
  |                     "ContactListConverter error: " + e.toString());
  |         }
  |         if (result == null) {
  |             throw new ConverterException(
  |                     "A valid Contact itemString is required");
  |         }
  |         return result;
  |     }
  | 
  |     public String getAsString
  |             (FacesContext
  |                     context,
  |              UIComponent
  |                      component,
  |              Object
  |                      object)
  |             throws ConverterException {
  |         String result;
  |         if (object == null) {
  |             result = null;
  |         } else {
  |             result = Contact.getItem((Contact) object);
  |         }
  |         return result;
  |     }
  | 

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4052694#4052694

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4052694



More information about the jboss-user mailing list