PrimeFaces pickList - exception

Is it necessary to use a converter when working with pickList? Well, here's my code:
<p:pickList value="#{usuarioBean.listaMembros}" var="#{usuario}" itemLabel="#{usuario.nome}">
<f:facet name="cadastrados">Membros</f:facet>
<f:facet name="equipe">Membros da Equipe</f:facet>
</p:pickList>
All I keep getting is:
java.util.ArrayList cannot be cast to org.primefaces.model.DualListModel

Your picklist needs to point to a DualListModel...which itself contains a source list and a target list. So you need to create a source list and a target list and then create a DualListModel from them e.g. taking the primefaces showcase example:
List<Player> source = new ArrayList<Player>();
List<Player> target = new ArrayList<Player>();
source.add(new Player("Messi", 10, "messi.jpg"));
source.add(new Player("Iniesta", 8, "iniesta.jpg"));
source.add(new Player("Villa", 7, "villa.jpg"));
source.add(new Player("Alves", 2, "alves.jpg"));
source.add(new Player("Xavi", 6, "xavi.jpg"));
source.add(new Player("Puyol", 5, "puyol.jpg"));
listaMembros = new DualListModel<Player>(source, target);
Then your getter and setter would get and set a DualListModel...e.g
public DualListModel<Player> getListaMembros() {
return listaMembros;
}
public void setPlayers(DualListModel<Player> players) {
this.listaMembros = listaMembros;
}
Then in your xhtml the value of your picklist would be
#{usarioBean.listaMembros}
If your data within your lists is a complex type then you'll need to use a converter to convert the object

Related

PRIMEFACES: What java code can be run in XHTML files in PRIMEFACES

Traditionally,all the java methods in XHTML code in Primefaces is of the form
<p:commandButton action="#{bean.variable}">
Is there another way to call java methods in XHTML code like
<p:commandButton action="#{bean.method()}">
I need to run the class below. I can use the #ManagedBean (and also use CDI and use #Named) but unsure how the method will be called even if i place a #PostConstruct on public void build(); Something is missing and i dont know how to fix it.
public class SimpleReport_Step01 {
public SimpleReport_Step01() {
build();
}
private void build() {
try {
report()//create new report design
.columns(//add columns
// title, field name data type
col.column("Item", "item", type.stringType()),
col.column("Quantity", "quantity", type.integerType()),
col.column("Unit price", "unitprice", type.bigDecimalType()))
.title(cmp.text("Getting started"),cmp.horizontalList().add(
cmp.hListCell(projectOverview()),
cmp.hListCell(projectStatus())
))//shows report title
.pageFooter(cmp.pageXofY())//shows number of page at page footer
.setDataSource(createDataSource())//set datasource
.show();//create and show report
} catch (DRException e) {
e.printStackTrace();
}
}
private ComponentBuilder<?, ?> projectOverview(){
HorizontalListBuilder hlb = cmp.horizontalList();
hlb.add(cmp.text("max")).newRow();
hlb.add(cmp.text("con")).newRow();
hlb.add(cmp.text("fex")).newRow();
return cmp.verticalList(cmp.text("PROJECT OVERVIEW"),hlb);}
private ComponentBuilder<?, ?> projectStatus(){
HorizontalListBuilder hlb = cmp.horizontalList();
hlb.add(cmp.text("")).newRow();
hlb.add(cmp.text("")).newRow();
hlb.add(cmp.text("")).newRow();
return cmp.verticalList(cmp.text("PROJECT STATUS"),hlb);}
private JRDataSource createDataSource() {
DRDataSource dataSource = new DRDataSource("item", "quantity", "unitprice");
dataSource.add("Notebook", 1, new BigDecimal(500));
dataSource.add("DVD", 5, new BigDecimal(30));
dataSource.add("DVD", 1, new BigDecimal(28));
dataSource.add("DVD", 5, new BigDecimal(32));
dataSource.add("Book", 3, new BigDecimal(11));
dataSource.add("Book", 1, new BigDecimal(15));
dataSource.add("Book", 5, new BigDecimal(10));
dataSource.add("Book", 8, new BigDecimal(9));
return dataSource;
}
}
I know this is a swing app and probably i can change it to run on the browser by using the usual jasper methods used like in this link

Primefaces addCallbackParam returns empty:false instead of actual object

I am trying to replace RichFaces components jsFunction and Poll with Primefaces' equivalents. Reason for this is that when I add p:dialog to .xhtml page I am getting some errors related to jQuery.
So much for the background.
I created simple bean like as follows:
#Named
#SessionScoped
public class PollableBean implements Serializable {
#Getter
private List<String> resultOfPolling = new ArrayList<>( Arrays.asList("abc","def","ghi"));
public CustomResult gimmeData(){
System.out.println(resultOfPolling);
List<String> resultButLocal = resultOfPolling;
PrimeFaces pf = PrimeFaces.current();
pf.ajax().addCallbackParam("customResult",resultOfPolling);
RequestContext context = RequestContext.getCurrentInstance();
context.addCallbackParam("saved", resultButLocal); //basic parameter
String[] sa = new String[]{"na1","na2","na3"};
int[] ia = {3,4,5};
CustomResult cr = CustomResult.builder()
.p1("name")
.v1(3)
.va1(ia)
.pa1(sa)
.pl1(Arrays.asList(sa))
.vl1(IntStream.of(ia)
.boxed()
.collect(Collectors.toList())
)
.build();
pf.ajax().addCallbackParam("event.data", cr);
return cr;
}
}
CustomResult class definition is this:
#Getter
#Setter
#Builder
public class CustomResult {
String p1;
int v1;
String[] pa1;
int[] va1;
List<String> pl1;
List<Integer> vl1;
}
My page that invokes polling is like bellow:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title>Facelet Title</title>
<h:outputScript name ="js/test.js"/>
</h:head>
<h:body>
<h:form>
<h:outputText id="txt_count" value="#{counterView.number}" />
<p:poll interval="10" listener="#{pollableBean.gimmeData()}" oncomplete="myFunc1(xhr,status,args)" />
</h:form>
<script>
myFunc2();
</script>
</h:body>
And here is my problem.
When I check in console what values I am actually receiving, I can see something like this:
{saved: {…}, customResult: {…}, event.data: {…}}
customResult:
empty: false
__proto__: Object
event.data:
p1: "name"
pa1: (3) ["na1", "na2", "na3"]
pl1: (3) ["na1", "na2", "na3"]
v1: 3
va1: (3) [3, 4, 5]
vl1: (3) [3, 4, 5]
__proto__: Object
saved:
empty: false
__proto__: Object
__proto__: Object
In regard to above my question is:
Why am I getting "empty: false" as content for private List ?
I am using Primefaces 6.2
UPDATE1:
As suggested I created another wrapper containing only List and tried to return it like before. I also added List to check whether my problem is only appearing with Strings.
Results are following:
#Getter
private List<String> resultOfPolling = new ArrayList<>( Arrays.asList("abc","def","ghi"));
private List<Integer> anotherPollRes = new ArrayList<Integer>();
public CustomResult gimmeData(){
System.out.println(resultOfPolling);
List<String> resultButLocal = resultOfPolling;
PrimeFaces pf = PrimeFaces.current();
RequestContext context = RequestContext.getCurrentInstance();
pf.ajax().addCallbackParam("customResult",resultOfPolling);
context.addCallbackParam("saved", resultButLocal);
CustomResult cr = prepCR();
pf.ajax().addCallbackParam("event.data", cr);
LSWrapper elsw = new LSWrapper();
pf.ajax().addCallbackParam("default wrapper", elsw);
LSWrapper lsw = new LSWrapper(resultOfPolling);
pf.ajax().addCallbackParam("wrapper", lsw);
pf.ajax().addCallbackParam("another", anotherPollRes);
return cr;
}
Wrapper class:
#AllArgsConstructor
#NoArgsConstructor
public class LSWrapper {
#Getter
#Setter
private List<String> onlyProp = new ArrayList<>(Arrays.asList("abc","def","ghi"));
}
Received JSON:
another: {empty: true}
customResult: {empty: false}
default wrapper: {onlyProp: Array(3)}
event.data: {pa1: Array(3), p1: "name", pl1: Array(3), va1: Array(3), vl1: Array(3), …}
saved: {empty: false}
wrapper: {onlyProp: Array(3)}
UPDATE 2:
Looking into network traffic with Chrome build-in tools gave me following result:
<?xml version='1.0' encoding='UTF-8'?><partial-response id="j_id1"><changes><update id="j_id1:javax.faces.ViewState:0"><![CDATA[-887312468948943065:-278897396377742194]]></update><extension ln="primefaces" type="args">{"saved":{"empty":false},"another":{"empty":true},"default wrapper":{"onlyProp":["abc","def","ghi"]},"wrapper":{"onlyProp":["abc","def","ghi"]},"customResult":{"empty":false},"event.data":{"p1":"name","pa1":["na1","na2","na3"],"pl1":["na1","na2","na3"],"va1":[3,4,5],"vl1":[3,4,5],"v1":3}}</extension></changes></partial-response>
I also tried to instatied some local list (with and without initial values) but result is the same, empty:false / empty:true (accordingly).
I even tried this with old version of Primefaces (5.2 iirc) and the same happened.
Is it possible that this is only my issue ?
Even it is then why the very same list is "ok" when it is returned as a field of POJO?
I am using Glassfish 4.1.
UPDATE 3:
I guess it is expected behaviour after all.
Documentation at:
https://www.primefaces.org/docs/api/6.2/org/primefaces/PrimeFaces.Ajax.html#addCallbackParam-java.lang.String-java.lang.Object-
states that currently supported objects are: POJOs, JSONObjects and JSONArrays.
To my knowledge generic classes implementing some interfaces are not POJOs.
And the reason why my CustomResult class was serialized correctly is (in my opinion) that it is plain old java object.

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']}"

Primefaces: Bind component value from valueExpression string

I read some articles here and they always say:
Don't create components programatically, all you can do by code is possible in xhtml too
So I have an interesting question.
I have component Calendar:
<p:calendar>
<f:attribute name="value" value="#{column.properties['from_value']}" />
</p:calendar>
Or you can simplify it:
<p:calendar value="#{column.properties['from_value']}" />
Properties
column is var of <p:columns> component
It has variable properties which is Map<String,String>
In properties I have key from_value and inside it I have String : "#{bean.object.dateFrom}"
My question is:
How can i convert this string to ValueExpression ?
Because when I run this code. Inside p:calendar is value "#{bean.object.dateFrom}" ... I need to set it as valueExpression and not String
What I get:
Calendar: #{bean.object.dateFrom}
What I want to achieve:
Calendar: 02.11.2017
-
Same code but Programmatically :
public ValueExpression createValueExpression(String valueExpression, Class<?> valueType) {
FacesContext context = FacesContext.getCurrentInstance();
return context.getApplication().getExpressionFactory().createValueExpression(context.getELContext(), valueExpression, valueType);
}
...
Calendar fromCalendar = new Calendar();
fromCalendar.setValueExpression("value", createValueExpression(properties.get("from_value"), Object.class));
Hope it's clear what I want to achieve.
Thank's for replies

Combobox created dynamically from database (JSF)

I wanted to create in JSF a combobox (selectOneMenu). I want to fill this combobox with all logins from one column from Database (SELECT logins FROM database).
Will be much gratefull from any help.
In your backing bean (YourBean in the example) you should have an array of Strings (or of objects with a getter method that returns the String you want). For instance lets assume you have the following code in your backing bean:
private ArrayList<String> logins; // read from DB
private String selectedLogin; // this will hold the selected value
// this method will be called by the JSF framework to get the list
public ArrayList<String> getLogins()
{
return logins;
}
public String getSelectedLogin()
{
return selectedLogin;
}
public String setSelectedLogin(String sl)
{
selectedLogin = sl;
}
In you Facelets page, assuming you are on JSF 2.x:
<h:selectOneMenu value="#{YourBean.selectedLogin}">
<f:selectItems value="#{YourBean.logins}" itemLabel="#{l}" itemValue="#{l}" var="l"/>
</h:selectOneMenu>
This will create a select menu with all the options in the array. Once the form is submitted the value will be set in the String value of your backing bean.