jsf - How to populate options of h:selectOneMenu from database? -
i creating web application, have read list of objects / entities db , populate in jsf <h:selectonemenu>. unable code this. can show me how it?
i know how list<user> db. need know is, how populate list in <h:selectonemenu>.
<h:selectonemenu value="#{bean.name}"> ...? </h:selectonemenu>
based on question history, you're using jsf 2.x. so, here's jsf 2.x targeted answer. in jsf 1.x forced wrap item values/labels in ugly selectitem instances. fortunately not needed anymore in jsf 2.x.
basic example
to answer question directly, use <f:selectitems> value points list<t> property preserve db during bean's (post)construction. here's basic kickoff example assuming t represents string.
<h:selectonemenu value="#{bean.name}"> <f:selectitems value="#{bean.names}" /> </h:selectonemenu> with
@managedbean @requestscoped public class bean { private string name; private list<string> names; @ejb private nameservice nameservice; @postconstruct public void init() { names = nameservice.list(); } // ... (getters, setters, etc) } simple that. actually, t's tostring() used represent both dropdown item label , value. so, when you're instead of list<string> using list of complex objects list<someentity> , haven't overridden class' tostring() method, see com.example.someentity@hashcode item values. see next section how solve properly.
also note bean <f:selectitems> value not need same bean bean <h:selectonemenu> value. useful whenever values applicationwide constants have load once during application's startup. make property of application scoped bean.
<h:selectonemenu value="#{bean.name}"> <f:selectitems value="#{data.names}" /> </h:selectonemenu> complex objects available items
whenever t concerns complex object (a javabean), such user has string property of name, use var attribute hold of iteration variable in turn can use in itemvalue and/or itemlabel attribtues (if omit itemlabel, label becomes same value).
example #1:
<h:selectonemenu value="#{bean.username}"> <f:selectitems value="#{bean.users}" var="user" itemvalue="#{user.name}" /> </h:selectonemenu> with
private string username; private list<user> users; @ejb private userservice userservice; @postconstruct public void init() { users = userservice.list(); } // ... (getters, setters, etc) or when has long property id rather set item value:
example #2:
<h:selectonemenu value="#{bean.userid}"> <f:selectitems value="#{bean.users}" var="user" itemvalue="#{user.id}" itemlabel="#{user.name}" /> </h:selectonemenu> with
private long userid; private list<user> users; // ... (the same in previous bean example) complex object selected item
whenever set t property in bean , t represents user, need bake custom converter converts between user , unique string representation (which can id property). note itemvalue must represent complex object itself, type needs set selection component's value.
<h:selectonemenu value="#{bean.user}" converter="#{userconverter}"> <f:selectitems value="#{bean.users}" var="user" itemvalue="#{user}" itemlabel="#{user.name}" /> </h:selectonemenu> with
private user user; private list<user> users; // ... (the same in previous bean example) and
@managedbean @requestscoped public class userconverter implements converter { @ejb private userservice userservice; @override public object getasobject(facescontext context, uicomponent component, string submittedvalue) { if (submittedvalue == null || submittedvalue.isempty()) { return null; } try { return userservice.find(long.valueof(submittedvalue)); } catch (numberformatexception e) { throw new converterexception(new facesmessage(string.format("%s not valid user id", submittedvalue)), e); } } @override public string getasstring(facescontext context, uicomponent component, object modelvalue) { if (modelvalue == null) { return ""; } if (modelvalue instanceof user) { return string.valueof(((user) modelvalue).getid()); } else { throw new converterexception(new facesmessage(string.format("%s not valid user", modelvalue)), e); } } } (please note converter bit hacky in order able inject @ejb in jsf converter; 1 have annotated @facesconverter(forclass=user.class), but unfortunately doesn't allow @ejb injections)
don't forget make sure complex object class has equals() , hashcode() implemented, otherwise jsf during render fail show preselected item(s), , you'll on submit face validation error: value not valid.
public class user { private long id; @override public boolean equals(object other) { return (other != null && getclass() == other.getclass() && id != null) ? id.equals(((user) other).id) : (other == this); } @override public int hashcode() { return (id != null) ? (getclass().hashcode() + id.hashcode()) : super.hashcode(); } } complex objects generic converter
head answer: implement converters entities java generics.
complex objects without custom converter
the jsf utility library omnifaces offers special converter out box allows use complex objects in <h:selectonemenu> without need create custom converter. selectitemsconverter conversion based on readily available items in <f:selectitem(s)>.
<h:selectonemenu value="#{bean.user}" converter="omnifaces.selectitemsconverter"> <f:selectitems value="#{bean.users}" var="user" itemvalue="#{user}" itemlabel="#{user.name}" /> </h:selectonemenu>
Comments
Post a Comment