Here is an example using Enums and SelectOne using an indirect off to internationalised messages
Showing usage in a dataTable (including filtering) and on its own.
[Pure J6EE [JSF]]
faces-config.xml
Code: Select all
<!-- Standard Enum Converter -->
<converter>
<converter-for-class>java.lang.Enum</converter-for-class>
<converter-class>javax.faces.convert.EnumConverter</converter-class>
</converter>
messages.properties
Code: Select all
all=All
#Event States
event_state=State
event_setup=Setup
event_open_for_entries=Open For Entries
event_closed_for_entries=Closed For Entries
event_running=Running
event_completed=Completed
event_cancelled=Cancelled
Code: Select all
public enum EventWorkflowStateKind {
SETUP("event_setup"),
OPEN_FOR_ENTRIES("event_open_for_entries"),
ENTRIES_CLOSED_FOR_ENTRIES("event_closed_for_entries"),
RUNNING("event_running"),
COMPLETED("event_completed"),
CANCELLED("event_cancelled");
private final String inlLabel;
EventWorkflowStateKind(String inlLabel) {
this.inlLabel = inlLabel;
}
public String getInlLabel() {
return this.inlLabel;
}
}
inside a panel grid (simple use) (CR=CreateUpdate[Writeable] and RD=ReadDelete[Read Only])
Code: Select all
<!-- state-->
<h:outputLabel for="stateCU" value="#{messages.event_state}" rendered="#{(eventManagementController.CRUDMode eq 'UPDATE')}"/>
<h:outputLabel for="stateCU" styleClass="mandatory" value="*" rendered="#{(eventManagementController.CRUDMode eq 'UPDATE')}"/>
<p:selectOneMenu id="stateCU" value="#{event.state}" required="true" rendered="#{(eventManagementController.CRUDMode eq 'UPDATE')}">
<f:selectItems value="#{eventManagementController.eventWorkflowStatusValues}" />
</p:selectOneMenu>
<p:message for="stateCU" rendered="#{(eventManagementController.CRUDMode eq 'UPDATE')}"/>
...
<!-- state -->
<h:outputLabel for="stateRD" value="#{messages.event_state}" />
<h:outputText id="stateRD" value="#{messages[event.state.inlLabel]}"/>
inside a data table
Code: Select all
<p:dataTable id="eventsTable" value="#{events}" var="eachEvent" paginator="true" paginatorAlwaysVisible="false" emptyMessage="#{messages.events_no_events}" paginatorPosition="bottom"
rows="5">
...
<p:column id="event_state_col" headerText="#{messages.event_state}" sortBy="#{messages[eachEvent.state.inlLabel]}"
filterBy="#{eachEvent.state}" filterOptions="#{eventManagementController.eventWorkflowStatusValues}" filterMatchMode="exact">
<h:outputText value="#{messages[eachEvent.state.inlLabel]}" />
</p:column>
useful parts of the the Controller
Code: Select all
// Leverage EJB to get Transactional Support
@Stateful
// Lets be long running (multiple client-server round trips) - Needs Extended on
// PersistanceContext too to hold onto my objects and not get LIEs.
@ConversationScoped
// EL Can can find me...
@Named
public class EventManagementController
// Access to the persistence store so we can read from the DB with Long
// Running extension to go with Conversation Scope above.
@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager em;
@SuppressWarnings("unused")
@URLQueryParameter("cid")
private String cid;
// DON'T let any Entities be Proxied by WELD so just use class local.
// According to this definition, JPA entities are technically managed beans.
// However, entities have
// their own special lifecycle, state and identity model and are usually
// instantiated by JPA or using
// new. Therefore we don't recommend directly injecting an entity class. We
// especially recommend
// against assigning a scope other than @Dependent to an entity class, since
// JPA is not able to
// persist injected CDI proxies.
private List<EME_Event> events;
private CRUDMode cRUDMode;
// Inject this to make conversation magic happen
@Inject
private Conversation conversation;
private SelectItem[] statusSelectOptions;
...
private void setupEventWorkflowStatusValues() {
this.statusSelectOptions = new SelectItem[EventWorkflowStateKind.values().length + 1];
FacesContext fc = FacesContext.getCurrentInstance();
Locale myLocale = fc.getExternalContext().getRequestLocale();
ResourceBundle myResources = ResourceBundle.getBundle("messages", myLocale);
int index = 0;
this.statusSelectOptions[index++] = new SelectItem("", myResources.getString("all"));
for (EventWorkflowStateKind state : EventWorkflowStateKind.values()) {
this.statusSelectOptions[index++] = new SelectItem(state, myResources.getString(state.getInlLabel()));
}
}
public SelectItem[] getEventWorkflowStatusValues() {
return this.statusSelectOptions;
}
// In a sort of random way this allows for ANY use of a "list of Event",
// anywhere, for this to "feed" the request... Dodgy...
@Produces
// EL Can can find me...
@Named
public List<EME_Event> getEvents() {
this.logger.info("Getting the pre-fetched events ");
this.logger.info("conversation:" + this.conversation.getId());
return this.getAllEvents();
}
@SuppressWarnings("unchecked")
private List<EME_Event> getAllEvents() {
this.logger.info("Getting events from DB");
if (this.events == null) {
this.events = this.em.createQuery("select e from event e order by id desc").getResultList();
}
else {
this.logger.info("Already have events set up");
}
return this.events;
}