0

Inside my controller StudentController I have a variable Course course and I want to set this variable with the value, selected in a selectOneMenu, inside my JSF-page. Clicking the save-button would temporarily just call the JSF-page index (I will fill that part with my own code that will persist the student course, which will not be a problem). The corresponding part in my JSF-page:

<h:form>
    <h:panelGrid columns="2" style="margin-bottom:10px" cellpadding="5">
        <p:outputLabel for="course" value="Select Course:" />
        <p:selectOneMenu id="course" value="#{studentController.course}">
            <f:selectItem itemLabel="--- Please Select ---" itemValue="" />
            <f:selectItems value="#{studentController.courses}" var="course"
                itemLabel="#{course.name}" itemValue="#{course}" />
        </p:selectOneMenu>
    </h:panelGrid>
    <p:commandButton action="index?faces-redirect=true"
        value="Save" icon="ui-icon-circle-check" />
</h:form>

The corresponding part in the controller:

@ManagedBean
@SessionScoped
public class StudentController {

    // list contains available courses, is not empty
    private List<Course> courses;

    private Course course = new Course();

    // getter, setter and other functionality
}

When I click the save-button, nothing happens. No error messages in my console, no redirecting. How can I store the value, selected on the selectOneMenu inside my course variable?

John
  • 735
  • 2
  • 14
  • 32
  • 1
    You hve to use Converter Interface. Here is some example: Converter : http://stackoverflow.com/questions/18422134/converter-in-jsf-primefaces-with-selectonemenu-validation-error – Szarpul Jan 13 '15 at 11:04
  • Just a bit curious : In your recent posts, you have been using some verbose session scoped JSF managed beans including the one in this question which appear to be utterly superfluous maintaining beans per HTTP session quite unnecessarily. Don't simple view scoped beans (or sometimes even request scoped beans) serve your purposes in such circumstances? Session scoped beans should only be needed whenever you need to maintain some states per HTTP session. – Tiny Jan 13 '15 at 14:38
  • Should I use RequestScoped Beans instead? – John Jan 14 '15 at 09:44
  • 1
    Yes you may but everything is fully dependent upon the requirements - [when to use which scope](http://stackoverflow.com/q/7031885/1391249). The current trend however, is to use CDI instead, if you are willing to use. You should find [this answer](http://stackoverflow.com/a/4347707/1391249) interesting. [These](https://docs.oracle.com/javaee/7/tutorial/cdi-basic008.htm) are basic CDI scopes. You can also find them in the Weld documentation over [here](http://docs.jboss.org/weld/reference/latest-2.2/en-US/html_single/#_built_in_scopes). (Java EE 7 provides a view scope and a flow scope too). – Tiny Jan 14 '15 at 15:21
  • Thank you very much! I will check the resources in any case! – John Jan 14 '15 at 18:05

1 Answers1

2

In order to map value from <p:selectOneMenu to your java object you'll need to use jsf converter.

You can use generic converter without adding any dependencies

import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.WeakHashMap;

import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

@FacesConverter(value = "entityConverter")
public class EntityConverter implements Converter {

    private static Map<Object, String> entities = new WeakHashMap<Object, String>();

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object entity) {
        synchronized (entities) {
            if (!entities.containsKey(entity)) {
                String uuid = UUID.randomUUID().toString();
                entities.put(entity, uuid);
                return uuid;
            } else {
                return entities.get(entity);
            }
        }
    }

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String uuid) {
        for (Entry<Object, String> entry : entities.entrySet()) {
            if (entry.getValue().equals(uuid)) {
                return entry.getKey();
            }
        }
        return null;
    }

}

Then change your xhtml as

<p:selectOneMenu converter="entityConverter"> 

Now you'll have selected value in the managed bean.

Makky
  • 15,166
  • 17
  • 58
  • 81