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