S1LENT WARRIOR
S1LENT WARRIOR

Reputation: 12204

Displaying the correct datatable out of a group of datatables

Referring to this post on primefaces forum.
Has someone got any idea how can we use multiple datatable on the same page but only display the correct one?
My problem is that i have a view-Scoped bean whose properties contain data from different tables from a database. I have multiple datatables for data of each database table. Now i want to display the datatable on the basis value selected from <p:selectOneMenu> (encircled in red color).
this screenshot would explain a bit further.

image

Upvotes: 0

Views: 1288

Answers (2)

S1LENT WARRIOR
S1LENT WARRIOR

Reputation: 12204

By the grace of God. After lots of struggle! i finally achieved this!
For this i pay bundles of thanks to BalusC for his expert tips
So i would like to share my solution with all.
So here is what i did in my xhtml file:

<p:selectOneMenu value="#{dbmBean.selectedTable}" style="height:27px" >
    <c:forEach items="#{dbmBean.tableNames}" var="table">
        <f:selectItem itemLabel="#{table.value}" itemValue="#{table.key}"/>
    </c:forEach>
</p:selectOneMenu>
<p:commandButton value="Go" action="#{dbmBean.goToTable}" ajax="false" />
...
<p:dataTable binding="#{dbmBean.table}" var="row" rowIndexVar="index">
<f:facet name="header"/>
<p:columns value="#{dbmBean.columns}" var="column" columnIndexVar="colIndex" >  
        <f:facet name="header">  
            #{column.header}  
        </f:facet>
        <h:outputText value="#{row[column.property]}"/>
    </p:columns>
</p:dataTable>

and in the backing bean:

public class DatabaseManagerBean implements Serializable {
    private List<ColumnModel> columns; // Column model is a simple class with two string properties: header, property
    ...    
    public void goToTable() {
        int tableIndex = new Integer(this.selectedTable);
        switch (tableIndex) {
            case 1:
                 Players tempPlayers = new Players(); //the class which get data from a database table
                 this.players = tempPlayers.getAllPlayers();
                 this.columnNames = tempPlayers.getColumnNames();
                 for (String colName : columnNames) {
                    columns.add(new ColumnModel(colName.toUpperCase(), colName));
                 }
                 table.setRendered(true);
                 table.setValue(this.players);
                 break;
                 ...
                 default:
                 table.setRendered(false);
         } //end of switch statement
    } //end of goToTable() method
} //end of DatabaseManagerBean

This code snippet would work exactly as i wanted in this screenshot! :-)

image

Also if someone find something left unexplained or missing, please write a comment.
And again hats off to BalusC. Because without his hints, i won't be able to achieve this objective. :-)
I would also like to say thanks to Optimus Prime and the PrimeFaces team to create such wonderful Faces. :-)
i would also pay my thanks to the Stackoverflow team, for providing us such a wonderful platform for such discussions! :-)
thank you all! :-)

Upvotes: 0

BalusC
BalusC

Reputation: 1108632

The basic approach would be to let the rendered attribute of the tables depend on the selected item of the menu.

<p:selectOneMenu value="#{bean.table}">
    <f:selectItem itemValue="players" itemLabel="Players" />
    <f:selectItem itemValue="jobs" itemLabel="Jobs" />
    <f:selectItem itemValue="business" itemLabel="Business" />
    ...
    <p:ajax update="tables" />
</p:selectOneMenu>

<h:panelGroup id="tables">
    <p:dataTable value="#{bean.players}" rendered="#{bean.table == 'players'}">
        ...
    </p:dataTable>
    <p:dataTable value="#{bean.jobs}" rendered="#{bean.table == 'jobs'}">
        ...
    </p:dataTable>
    <p:dataTable value="#{bean.business}" rendered="#{bean.table == 'business'}">
        ...
    </p:dataTable>
    ...
</h:panelGroup>

This is easy to implement, but you end up with a lot of code in the view (which can of course be split over <ui:include> files). The more advanced and reuseable approach would be to let the value of the single table depend on the selected item of the menu and use <p:columns> to generate columns dynamically.

<p:selectOneMenu value="#{bean.table}">
    <f:selectItems value="#{bean.tables}" />
    <p:ajax listener="#{bean.changeModel}" update="table" />
</p:selectOneMenu>

<p:dataTable id="table" value="#{bean.model}" var="item">
    <p:columns value="#{bean.columns}" var="column">
        <h:outputText value="#{item[column]}" />
    </p:columns>
</p:dataTable>

with something like:

public void changeModel() {
    model = populateModelBasedOn(table);
    columns = populateColumnsBasedOn(table);
}

This only allows less fine-grained control whenever you want to add more specialized columns. You'd probably want to work with tag files instead.

Upvotes: 2

Related Questions