Why selectOneMenu Send ItemLabel to the converter?
my JSF page
<h:form>
<h:selectOneMenu id="studlist" value="#{studBean.selectedStudent}">
<p:ajax event="change" process="studlist" update="studdep" ></p:ajax>
<f:selectItems value="#{studBean.student}" var="s"
itemValue="#{s.studid}" itemLabel="#{s.name}"/>
<f:converter converterId="studentconverter"/>
</h:selectOneMenu>
</h:form>
converter class(StudentConverter)
public Object getAsObject(FacesContext context, UIComponent component, String value) {
Student studConvert= new Student();
List<Student> students=new ArrayList<Student>();
students=(ArrayList<Student>)((UISelectItems
component.getChildren().get(0)).getValue();
}
on this converter the Argument 'String value' gives the itemLabel i why it happens?? i wand the itemValue on this string
Solution 1:
I'm not sure why you got the item label instead of the item value inside getAsObject()
. Perhaps your getAsString()
is doing it wrong and it is returning student name based on the student ID.
At any way, I can tell that your itemValue
is definitely not right.
<h:selectOneMenu id="studlist" value="#{studBean.selectedStudent}">
<f:selectItems value="#{studBean.student}" var="s"
itemValue="#{s.studid}" itemLabel="#{s.name}" />
<f:converter converterId="studentconverter" />
</h:selectOneMenu>
A converter is intented to be used to convert between a complex Java object and a String representation so that it can be passed around as a HTTP request parameter. However, you're specifying the student ID as item value instead of the whole student object. You need to specify the whole student object instead. You should also ensure that #{studBean.selectedStudent}
refers to a Student
property, not some Long
property representing the student ID.
When you fix the itemValue
as follows:
<h:selectOneMenu id="studlist" value="#{studBean.selectedStudent}">
<f:selectItems value="#{studBean.student}" var="s"
itemValue="#{s}" itemLabel="#{s.name}" />
<f:converter converterId="studentconverter" />
</h:selectOneMenu>
and your converter as follows (trivial nullchecks omitted):
public String getAsString(FacesContext context, UIComponent component, Object value) {
// This method is called when item value is to be converted to HTTP request parameter.
// Normal practice is to return an unique identifier here, such as student ID.
Student student = (Student) value;
Long id = student.getStudid();
return String.valueOf(id);
}
public Object getAsObject(FacesContext context, UIComponent component, String value) {
// This method is called when HTTP request parameter is to be converted to item value.
// You need to convert the student ID back to Student.
Long id = Long.valueOf(value);
Student student = someStudentService.find(id);
return student;
}
then it ought to work.
Alternatively, you could keep your itemValue
as you initially had and remove the <f:converter>
altogether, but then you have to change #{studBean.selectedStudent}
to point to a Long
property representing the student ID.
Solution 2:
You have to use selectitem list in the f:selecitems
attribute of h:selectOneMenu
Your page will be like this;
<h:form>
<h:selectOneMenu id="studlist" value="#{studBean.selectedStudent}">
<p:ajax event="change" process="studlist" update="studdep" ></p:ajax>
<f:selectItems value="#{studBean.studentSelectItemList}" />
<f:converter converterId="studentconverter"/>
</h:selectOneMenu>
</h:form>
At the backing bean side you have to fill the studentSelectItemList selectitem.
private List<SelectItem> studentSelectItemList;
//fill studentSelectItemList at the appropriate place
studentSelectItemList.add(new SelectItem(studentId,studentName));
After these settings you should have student id as select value.