JSF SelectItem exception - exception

I am trying to give a list of SelectItems to a selectOneMenu and I am getting this exception :
[Ljavax.faces.model.SelectItem; cannot be cast to javax.faces.model.SelectItem
which looks kind of weird to me. This is the code in the page:
<h:selectOneMenu value="#{user.name}">
<f:selectItem value="#{user.names}" />
</h:selectOneMenu>
And in User class:
import javax.faces.model.SelectItem;
private final SelectItem[] users = {new SelectItem("Jack"),new SelectItem("Max")};

<f:selectItem> represents a single SelectItem, but your EL-expression feeds it an array of SelectItems. Did you mean <f:selectItems>?
Also, since JSF 2.x f:selectItems is quite capable of working with ordinary Java Beans, as the official docs show:
<h:selectOneListbox size="1" id="escape02" value="#{select05NoSelection.initialCollectionValues}">
<f:selectItems value="#{select05NoSelection.hobbitList}"
var="n"
itemValue="#{n}"
itemLabel="#{n.bio}"
itemDescription="#{n.description}"
itemDisabled="#{n.disabled}"
itemLabelEscaped="true"
noSelectionValue="#{select05NoSelection.hobbitList[0]}"/>
</h:selectOneListbox>
It is therefore no longer necessary to create SelectItems in the backing bean.

Related

PropertyNotFoundException for p:column filterValue attribute

we are trying to migrate our application from tomcat/websphere to was liberty profile.
Additionally we are upgrading the myfaces-version, we are using 2.1, to myfaces-2.2.
To save the current state of a table (filtering) we store the filtered value in a map and read it when loading the table (filterValue attribute of p:column).
When initially loading the table the correct method will be used (in our case its getFilterValue in the DataModel). But if we start filtering a column, the method wont be found anymore and the following exception occurs:
javax.el.PropertyNotFoundException: Die Eigenschaft 'getFilterValue' wurde nicht im Typ package.LazyModel gefunden.
javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:245)
javax.el.BeanELResolver$BeanProperties.access$300(BeanELResolver.java:222)
javax.el.BeanELResolver.property(BeanELResolver.java:332)
javax.el.BeanELResolver.getType(BeanELResolver.java:83)
javax.el.CompositeELResolver.getType(CompositeELResolver.java:99)
org.apache.myfaces.el.unified.resolver.FacesCompositeELResolver.getType(FacesCompositeELResolver.java:150)
org.apache.el.parser.AstValue.setValue(AstValue.java:199)
org.apache.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:257)
org.jboss.weld.el.WeldValueExpression.setValue(WeldValueExpression.java:64)
org.apache.myfaces.view.facelets.el.ContextAwareTagValueExpression.setValue(ContextAwareTagValueExpression.java:153)
org.primefaces.component.datatable.DataTable.processUpdates(DataTable.java:746)
org.apache.myfaces.context.servlet.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:787)
org.apache.myfaces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:213)
org.primefaces.component.api.UIData.visitTree(UIData.java:822)
The table:
<p:dataTable id="table" var="group"
value="#{bean.lazyModel}"
selection="#{bean.selectedMulti}"
rows="#{bean.lazyModel.rows}" paginator="true"
currentPageReportTemplate="#{msg['data.table.pagereport']}"
paginatorTemplate="#{msg['data.table.paginator']}"
rowsPerPageTemplate="#{msg['data.table.rows']}"
resizableColumns="true" rowKey="#{group.pkId}" lazy="true"
filterDelay="1000" emptyMessage="#{msg['data.table.empty']}"
style="font-size: 8pt;"
tableStyle="font-size: 8pt; table-layout:auto;"
first="#{bean.lazyModel.first_m}"> >
<p:column headerText="Name"
sortBy="#{group.name}" filterBy="#{group.name}"
filterValue="#{bean.lazyModel.getFilterValue('name')}"
filterStyleClass="column_filter" styleClass="wrap">
<h:outputText value="#{group.name}" />
</p:column>
...
The lazymodel:
#Named
#Scope(value = "prototype")
public class LazyModel extends AbstractLazyModel<Brand> {
private static final long serialVersionUID = 2247660292777600670L;
/**
* Konstruktor
*/
public LazyModel() {
super();
}
public Object getFilterValue(final String keyForColumn) {
return this.filterManager.getFilterField(this.getKeyForPage(), keyForColumn);
}
I think this should be the most important things to know.
So, i dont understand what changed between these versions that trigger the exception.
Every help would be great. TIA!
I don't know why this has worked before (it should not have (properly)), but the error you are currently getting is sort of expected. The filterValue attribute should be bound to a property with read and write access. You could bind each column filter value to an individual property, but it is more convenient to use a Map<String,Object> for your filter values.
Bean (lazy model in your case):
private Map<String,Object> filterValues = new HashMap<>();
// ... add getter and setter for filterValues
XHTML:
filterValue="#{bean.lazyModel.filterValues['name']}"

JSF create dynamic commandLinks

I'm working on a Maven project with Eclipse Mars.2, Java 1.8 update 102 for 64bits, JSF Mojarra 2.2.2, Primefaces 6.1, Spring 3.2.3, Hibernate 4.3 (MySQL 5.1.39) and Tomcat 7.0.53.
I have 2 xhtml pages with their respective #ViewScoped backing beans. In page A I have the following code:
<p:dataGrid var="theReg" value="#{pageA_BB.listOfReg}" columns="1" rows="5" paginator="true" paginatorPosition="bottom">
<p:commandLink value="#{theReg.title}" action="pageB?faces-redirect=true&idvalue=#{theReg.paramValue}" />
</p:dataGrid>
The above code is supposed to render some URLs with different param values. The theReg.title is a String and the theReg.paramValue is an Integer
In page B backing bean I have the following code to rescue and use the "idvalue" parameter:
#PostConstruct
public void init() {
if (FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("idvalue")!=null){
idvalue = Integer.parseInt(FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("idvalue"));
}else{
idvalue = 0;
}
}
The above code doesn't work because EL is not allowed inside commandLink action.
I have tried to use a f:param as described here but the use of f:params require the backing bean to be #Requestscope (other way a scope error triggers) and I need a #Viewscoped because some Primefaces components require it.
I have thought about using EL inside an onClick event like that:
<p:commandButton onclick="window.open('pageB.xhtml?faces-redirect=true&idvalue=#{theReg.paramValue}', '_blank')" value="#{theReg.title}"/>
But I would like to use params as I feel it would be the "cleanest" method.
Any suggestion?
Thanks a lot in advance!

PrimeFaces 5.2 selectCheckboxMenu not support Map<String,String> style selectItems

I am trying to use
Map<String,String>
style selectItems in my
<p:selectCheckboxMenu>
but unfortunately, it not works.
Backing bean:
#Named(value = "roleBean")
#SessionScoped
public class RoleBean(){
private Map<String,String> roleMap;
private String[] selectRoles;
......
......
public void findRoleMap(){
if(roles.size()>0){
for(Role r:roles){
roleMap.put(r.getRoleId(),r.getRoleName());
}
logger.info("Role Map size: " + roleMap.size());
}
}
}
jsf as:
<p:selectCheckboxMenu id="roles" value="#{roleBean.selectRoles}" label="Select your roles" filter="true" filterMatchMode="startsWith" height="200" panelStyle="width:200px">
<f:selectItems value="#{roleBean.roleMap.entrySet}" var="entry" itemLabel="#{entry.value}" itemValue="#{entry.key}"/>
</p:selectCheckboxMenu>
When I access the page, I found there is 6 records were added into the map. but unfortunately, there is nothing shows up in the selectCheckboxMenu drop down list.
If I change the UIComponent to
<p:selectOneMenu>
from
<p:selectCheckboxMenu>
it shows up properly in dropdown list.
I tried to find out through google, I didn't find anyone else trying to use key/value pair in Map style as selectItems in selectCheckboxMenu. I was very confused.
My question is: Does selectCheckboxMenu support key/value pair mapping style or not, if it does. How To do it?
Please advise!!

Weird dataTable behaviour when combined with accordionPanel

I get a very strange behaviour when I combine the accordionPanel (dynamic tabs) together with a dataTable. In my project the total amount of dynamic tabs can get really big (>1000) so I really need the dynamic loading of the accordionPanel working, otherwise it is way too slow.
The problem
Instead of only loading the datatable for the currently selected tab, the getter method to load the elements from a list variable is being called 6 times the total amount of dynamic tabs. So if I have 300 dynamic tabs, the getter method is called 1800 times. If I however do not use a dataTable but i.e. just output text, the getter method is only called once like it should be.
Here is a small working example which produces the unwanted behaviour:
xhtml
<p:accordionPanel id="datasetHistoryAccordionTab" value="#{Bean.orderDatasets}" var="dataset" dynamic="true">
<p:tab title="Dataset ##{dataset.id}">
<p:tabView>
<p:tab title="All Processes">
<p:dataTable value="#{Bean.datasetProgressHistoryAll}" />
<!-- <h:outputText value="#{Bean.datasetProgressHistoryAll}" /> -->
</p:tab>
</p:tabView>
</p:tab>
</p:accordionPanel>
Bean
#ManagedBean
#ViewScoped
public class Bean implements Serializable
{
private List<DatasetBE> orderDatasets = new ArrayList<DatasetBE>(300);
private List<DatasetHistoryBE> datasetHistoryAll = new ArrayList<DatasetHistoryBE>();
public List<DatasetBE> getOrderDatasets() {
return orderDatasets;
}
public void setOrderDatasets(List<DatasetBE> orderDatasets) {
this.orderDatasets = orderDatasets;
}
public List<DatasetHistoryBE> getDatasetHistoryAll() {
log.debug("getDatasetHistoryAll() called...");
return datasetHistoryAll;
}
public void setDatasetProgressHistoryAll(List<DatasetHistoryBE> datasetHistoryAll) {
this.datasetHistoryAll = datasetHistoryAll;
}
}
The initial state is OK but as soon as I change to another tab the getter method is being called like crazy...
Is this a bug in PrimeFaces or am I doing something wrong? In my project I still use PF 3.5 but for testing purposes I also tried PF 4.0 but the same strange behaviour applies... Any help would be greatly appreciated!

Primefaces 3.5 multisort failure on pagination .. do we have fix?

Primefaces 3.5 introduced multisort on dataTable. But it has a bug with pagination.
Everytime paginator button is pressed, the sort column(sortMeta obj of the col) set at the time of table initial render is sent to the load method and not the selected sort column(s). If the initial sortOrder is not set, a null is sent.
Has there been a fix to this problem? Does anybody know if this has been fixed in any of the Elite versions? Or if there is a workaround for it?
Need some urgent help.
Thanks
I was able to overcome the problem by doing some additional coding in the application. This wouldn't be needed if the original bug is fixed in the later versions.
My solution
I have added 2 ajax events, for 'sort' and 'page' on the table. I saw that on each 'sort' the table had the right list of multisortmeta, but on the pagination call, it was getting over written with initial data.
So I have saved the list of multisortmeta in the bean on each sort call and on pagination call i have over written the table's list of multisortmeta with what i have in the bean. My bean is a session bean hence there is no problem with saving the list.
Once this is done the multisort is working on pagination. Below is my code
view/xhtml code
<p:dataTable id="userDataTable"
value="#{userBean.userModel}" var="usr"
paginator="true" paginatorAlwaysVisible="false" sortMode="multiple"
rowsPerPageTemplate="20,40,60" rows="20"
sortBy="#{userBean.preSortOrder}" lazy="true"
resizableColumns="false" >
<p:ajax event="page" listener="#{userBean.onPage}" ></p:ajax>
<p:ajax event="sort" listener="#{userBean.onSort}" ></p:ajax>
Bean code
public void onSort( SortEvent event) {
UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
UIComponent tableComp = viewRoot.findComponent("userForm:userDataTable");
DataTable table = ((DataTable)tableComp);
preSortOrder = table.getMultiSortMeta();
}
public void onPage() {
UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
UIComponent tableComp = viewRoot.findComponent("userForm:userDataTable");
DataTable table = ((DataTable)tableComp);
table.setMultiSortMeta(preSortOrder);
}
Hope this will be useful to others as well.