I would like to know how I can fill a h:selectManyListbox from a database, i.e. not with static options.
Use <f:selectItems> in combination with a property which returns List<SelectItem>, or when you're already on JSF 2.0, a List<SomeObject>.
<h:selectManyListbox value="#{bean.selectedItems}">
<f:selectItems value="#{bean.selectItems}" />
</h:selectManyListbox>
You can load the items from the DB in bean's constructor or #PostConstruct method.
public class Bean {
private List<String> selectedItems;
private List<SelectItem> selectItems;
public Bean() {
selectItems = new ArrayList<SelectItem>();
// Fill select items during Bean initialization/construction.
// Below is just an example, you could replace this by getting a list
// of some objects from DB and creating new items in a loop.
selectItems.add(new SelectItem("value1", "label1"));
selectItems.add(new SelectItem("value2", "label2"));
selectItems.add(new SelectItem("value3", "label3"));
}
// Getters, etc
}
Related
I have following field in my jsp. Selected value is not set to the element.
When I did Inspect element on this drop down field in FF, it shows that element is not selected. Also its not set to the backing bean.
What am I missing?
<h:selectOnMenu id="scriptEngine" value="#{AddScriptBean.scriptEngine}" required="true">
<f:selectItems value="#{AddScriptBean.scriptEngines}"/>
</h:selectOneMenu>
The backing bean code is as follows
public List<SelectItem> getScriptEngines() {
List<SelectItem> items = new ArrayList<SelectItem>();
try {
GetScriptEngineNamesCommand command = (GetScriptEngineNamesCommand) CommandFactory.getInstance().getCommand(GetScriptEngineNamesCommand.class.getName());
command.doExecute();
Map<String, String> engineNames = command.getEngineNames();
MessageSource messageSource = getMessageSource();
Locale locale = RequestUtils.getUserLocale((HttpServletRequest) FacesContext.getCurrentInstance()
.getExternalContext().getRequest(), Globals.LOCALE_KEY);
String label = messageSource.getFormattedMessage(locale, "com.soa.console.faces.script.select", new Object[] {});
items.add(new SelectItem("", label));
for (String name : engineNames.keySet()){
items.add(new SelectItem(engineNames.get(name), name));
}
}catch (GException e){
String eMessage = e.toString();
FacesMessage msg = new FacesMessage("", eMessage);
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
return items;
}
I guess getter method is not calling becuase you have bounded <f:selectItems> tag to the bean with scriptEngines but your getter method is getScriptEngines().It should have been getscriptEngines().This could be the problem
<h:selectManyListbox id="sectorsListBox" size="2" multiple="multiple" value="#{Mybean.classificationSelectedItems}">
<f:selectItems id="sectors" value="#{Mybean.classificationSelectItems}"/>
</h:selectManyListbox>
Backing Bean has:
public class Mybean
{
private Map<String,String> classificationSelectItems = new LinkedHashMap<String,String>();
private List<String> classificationSelectedItems = new ArrayList<String>();
//getter and setter for both.
}
init()
{
classificationSelectItems.put("INS","Insurance")
classificationSelectItems.put("HLC","HealthCare")
}
The select many box gets initialized with these 2 values but the problem is only the last selected entry is getting stored in classificationSelectedItems. Why is that so ? And how do I get all the selected entries stored in the list of classificationSelectedItems ?
Adding FYI, the init method is class by Spring.
I have tested with an examle(reference:http://www.mkyong.com/jsf2/jsf-2-multiple-select-listbox-example/), good luck :)
Facelets:
<h:form id="form">
<h:selectManyListbox value="#{user.favFood1}" >
<f:selectItems value="#{user.favFood2Value}" />
</h:selectManyListbox>
<h:commandButton value="test"/>
</h:form>
Bean:
#ManagedBean(name = "user")
#ViewScoped
public class UserBean implements Serializable {
private static final long serialVersionUID = 1L;
public List<String> favFood1;
private Map<String, Object> food2Value;
public UserBean() {
favFood1 = new ArrayList<String>();
food2Value = new LinkedHashMap<String, Object>();
food2Value.put("Food2 - Fry Checken", "Fry Checken1"); //label, value
food2Value.put("Food2 - Tomyam Soup", "Tomyam Soup2");
food2Value.put("Food2 - Mixed Rice", "Mixed Rice3");
}
public List<String> getFavFood1() {
return favFood1;
}
public void setFavFood1(List<String> favFood1) {
this.favFood1 = favFood1;
}
public Map<String, Object> getFavFood2Value() {
return food2Value;
}
}
I noticed exactly this behaviour when I used a Collection in the setter method, like
public void setClassificationSelectedItems(Collection<String> in){
// store it somewhere
}
This setter is called during the restore phase but not during the update phase, so the previously set value will be set, but never the new one. If you use a List, it works as expected:
public void setClassificationSelectedItems(List<String> in){
// store it somewhere
}
Note that you will need to redeploy the application after such a change because the JSP needs to be recompiled but this isn’t done automatically.
I'm using the PrimeFaces p:autoComplete widget in a search form of my project. The user can choose how many and which form-elements (search parameters) he wants to include so I need to pass an ID to the completeMethod for each of them. I've tried adding onfocus=".." to pass the object to the bean but that only would be activated when the element first is loaded.
My question: How can I pass an attribute to the completeMethod?
XHTML of the element (simple):
<p:autoComplete value="#{filter.value}" label="dynamic search attribute"
completeMethod="#{myBean.complete}" />
The bean (simple):
#Named("myBean")
public class MyController implements Serializable {
public List<String> complete(String query) {
List<String> results = new ArrayList<String>();
// ... code
return results;
}
}
In theory this would seem like the perfect solution:
<p:autoComplete value="#{filter.value}" label="dynamic search attribute"
completeMethod="#{myBean.complete(filter)}" />
And again the bean:
#Named("myBean")
public class MyController implements Serializable {
public List<String> complete(String query, FilterObject o) {
List<String> results = new ArrayList<String>();
// ... database query based on FilterObject o
return results;
}
}
You can set it as an attribute:
<p:autoComplete value="#{filter.value}" label="dynamic search attribute" completeMethod="#{myBean.complete}">
<f:attribute name="filter" value="#{filter}" />
</p:autoComplete>
and get it by UIComponent#getCurrentComponent():
public List<String> complete(String query) {
FacesContext context = FacesContext.getCurrentInstance();
FilterObject o = (FilterObject) UIComponent.getCurrentComponent(context).getAttributes().get("filter");
// ...
}
Alternatively, as that #{filter} appears in your case to be already in the EL scope, you can also leave the <f:attribute> away and get it by evaluating the EL expression programmatically with help of Application#evaluateExpressionGet():
public List<String> complete(String query) {
FacesContext context = FacesContext.getCurrentInstance();
FilterObject o = context.getApplication().evaluateExpressionGet(context, "#{filter}", FilterObject.class);
// ...
}
Or, if it is also a #Named bean, then you can just #Inject it in the parent bean:
#Inject
private FilterObject o;
How do I collect all selected values from UISelectMany components such as h:selectManyListbox, h:selectManyMenu, h:selectManyCheckbox, p:selectManyListbox, p:selectManyMenu, p:selectManyCheckbox, etc in backing bean?
If someone can help with an example, that would really help.
As with every other input component, just bind its value attribute with a managed bean property. It can map to a List or an array of the same value type as you've used in f:selectItem(s). If the value type is not one of the standard EL types (String, Number or Boolean), then you have to supply a Converter as well.
Here's an example with a value type of String:
<h:selectManyListbox value="#{bean.selectedItems}">
<f:selectItems value="#{bean.availableItems}" />
</h:selectManyListbox>
<h:commandButton value="Submit" action="#{bean.submit}" />
with
public class Bean {
private Map<String, String> availableItems; // +getter (no setter necessary)
private List<String> selectedItems; // +getter +setter
#PostConstruct
public void init() {
availableItems = new LinkedHashMap<String, String>();
availableItems.put("Foo label", "foo");
availableItems.put("Bar label", "bar");
availableItems.put("Baz label", "baz");
}
public void submit() {
System.out.println(selectedItems); // It's already set at that point.
}
// ...
}
See also:
Our selectOneMenu wiki page
How to populate options of h:selectOneMenu from database?
In a Screen to be rendered by a JSF Implementation, I had to show a static drop down or list box (which means the values are not changing ), So I decided to use a list of select Items and in the getter of the List , I am populating all the select Items as this
List.add(new SelectItem(VALUE,TEXT)) and so on..
If I used this way - What are the pitfalls? I made this List static since this will be common for all the Request Scoped Beans the JSF Implementation creates. Is this okay to do?
Sometimes , the items are added twice if multiple requests are fired.Is there an Application Scope ? or Whats the standard way of doing these stuff?
I'm also looking into API.Sometimes SO is quicker.
I'm using JSF Apace My Faces 1.2 without Tomahawk or any extra libs
Thanks,
Sometimes , the items are added twice if multiple requests are fired.
This indicates that you're adding the items in the getter method like follows
public class Bean {
private List<SelectItem> items = new ArrayList<SelectItem>();
public List<SelectItem> getItems() {
items.add(new SelectItem("value1", "label1"));
items.add(new SelectItem("value2", "label2"));
items.add(new SelectItem("value3", "label3"));
return items;
}
}
This is not good. A javabean getter should have the sole purpose to return a bean property or at highest do lazy loading, not to do some business stuff. You should create and fill the list during bean construction
public class Bean {
private List<SelectItem> items;
public Bean() {
items = new ArrayList<SelectItem>();
items.add(new SelectItem("value1", "label1"));
items.add(new SelectItem("value2", "label2"));
items.add(new SelectItem("value3", "label3"));
}
}
or initialization
public class Bean {
private List<SelectItem> items;
{
items = new ArrayList<SelectItem>();
items.add(new SelectItem("value1", "label1"));
items.add(new SelectItem("value2", "label2"));
items.add(new SelectItem("value3", "label3"));
}
}
or #PostConstruct
public class Bean {
private List<SelectItem> items;
#PostConstruct
public void init() {
items = new ArrayList<SelectItem>();
items.add(new SelectItem("value1", "label1"));
items.add(new SelectItem("value2", "label2"));
items.add(new SelectItem("value3", "label3"));
}
}
Is there an Application Scope ?
There is. Just use <managed-bean-scope>application</managed-bean-scope>.
or Whats the standard way of doing these stuff?
An application scoped bean is the way to go.
See also:
Why does JSF call getters multiple times?