Renaud is Not Bill Gates
Renaud is Not Bill Gates

Reputation: 2084

Display a JSF value depending on a condition

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

Answers (2)

stg
stg

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:

enter image description here

After clicking the button:

enter image description here

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

Aritz
Aritz

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

Related Questions