Reputation: 2084
I have an accordionPanel
as following :
<p:accordionPanel value="#{bean.list}" var="entry"
dynamic="true" cache="true">
<p:tab title="#{entry.alias}">
<h:panelGrid columns="2" cellpadding="10">
<h:outputText value="#{entry.text}" />
</h:panelGrid>
</p:tab>
</p:accordionPanel>
And in my Managed Bean I initialise two lists :
public void init(){
acceuil = 1;
salles = salleService.listSalles();
appareils = appareilService.list();
}
I'm using the acceuil
variable so when I have it set to 1
I'll use the salles
list in my accordionPanel
in the other hand, if I have it set to 2
I'll use the appareils
list in my accordionPanel
(notice that appareil and salle objects have the same attributes alias
and text
but they dont have a commun class where they extend from).
So in my jsf page I want to do something like this :
value="#{bean.acceuil == 1 ? bean.salles : bean.appareils}"
How can I do this ?
Upvotes: 1
Views: 3534
Reputation: 2797
So in my jsf page I want to do something like this :
value="#{bean.acceuil == 1 ? bean.salles : bean.appareils}"
How can I do this ?
One way would be exactly how you mentioned. There is nothing wrong with this approach. If this does not work for you, then something else must go wrong here. You are even able to switch between the two list "at runtime". See the example below:
JSF form:
<h:form>
<h:outputText value="foobar is: #{myBean.foobar}" />
<p:accordionPanel value="#{myBean.foobar == 1 ? myBean.fooList : myBean.barList}"
var="entry" dynamic="true" cache="true">
<p:tab title="#{entry.foo}">
<h:panelGrid columns="2" cellpadding="10">
<h:outputText value="#{entry.bar}" />
</h:panelGrid>
</p:tab>
</p:accordionPanel>
<p:commandButton actionListener="#{myBean.toggle()}" update="@form"/>
</h:form>
Backing Bean:
@Named
@ViewScoped
public class MyBean implements Serializable {
@Getter private List<Foo> fooList = new ArrayList<>();
@Getter private List<Bar> barList = new ArrayList<>();
@Getter private int foobar;
@PostConstruct
private void init() {
foobar = 1;
fooList.add(new Foo());
fooList.add(new Foo());
fooList.add(new Foo());
barList.add(new Bar());
barList.add(new Bar());
}
public void toggle() {
if(foobar == 1) {
foobar = 2;
} else {
foobar =1;
}
}
}
POJOs:
@Data
public class Foo {
String foo = "Foo: Foo";
String bar = "Foo: Bar";
}
@Data
public class Bar {
String foo = "Bar: Bar";
String bar = "Bar: FOO";
}
Outcome:
After clicking the button:
However, I would prefer a solution like it is suggested in the other answer by @XtremeBiker as well. You should reduce logic in the presentation to a minimum. But such small things might be ok if you are not allowed or able to write proper code here.
Upvotes: 2
Reputation: 31651
A clean solution would be to provide an interface which is implemented by Sale
and Appareil
classes. This way you restrict them to a contract:
public interface AliasAndText{
public String getAlias();
public String getText();
}
Then in your managed bean, use a single list, while you provide a proper action method to change the value for the acceuil
field. Comparing with your given code, this method calls a single service method each time, minimizing the performance impact:
private List<AliasAndText> list;
private int acceuil = 0;
public void init(){
//Initialize with the default acceuil value
loadList();
}
private void loadList(){
if (acceuil == 0){
list = appareilService.list();
}
else{
list = salleService.listSalles();
}
}
public void actionSwitch(){
acceuil = acceuil == 0 ? 1 : 0;
loadList();
}
public List<AliasAndText> getList(){
return list;
}
Upvotes: 1