is it possible to have dynamic DataTables with a single Managed bean

Hallo everyone,

I am new to the JSF technology and implementing it for a Dynamic web application. I have a question regarding DataTable component. Is it possible to have a single managed bean to control different DataTables (containing data of different database tables) on different PanelTabs?

I have a tabbed pane with tabs generated dynamically. Now, I want to place different DataTables in each PanelTab (these DataTables contain data of dynamic database tables).

Initially, before displaying to the front-end, I can be able to define and asssign values to the DataTables (though they are binded to the same managed bean). Later, while rendering, all DataTables are having the same contents.

I have noticed that there is a binding problem, as all the generated DataTables are binded to the same managed bean. I can't bind different managed beans for different DataTables as I don't know how many and what tables can exist in the database.

Can somebody help me out of this, please.

If my explanation of the problem is not clear or seems to be complicated, then I can post some sample code for better understanding.

Thank you

[1179 byte] By [veerathua] at [2007-10-3 2:22:14]
# 1
Just use different bindings.<h:dataTable binding="#{myBean.dataTable1}" /><h:dataTable binding="#{myBean.dataTable2}" />// etc
BalusCa at 2007-7-14 19:21:12 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 2

Hallo BalusC,

Thanks for a quick response.

Unfortunately, your tip doesn't help me, as I don't know how many DataTables have to be generated during runtime. In the database, the tables are generated dynamically and therefore I think the logic for adding the DataTable components has to be embedded in a single method.

If I use different bindings for different DataTables then I have to write the corresponding methods before hand. I have no idea about how many tables can exist / added / deleted, after the server is up and running.

I use the following method to add DataTables to different PanelTabs:

public class DataModelTest {

...

private DataModel dataModel;

String tableName;

public DataModelTest() {

// If the database table content retrieval is not embedded here then the DataTables on every tab are blank as the tableName is null.

}

public DataModel getDataModel() {

return dataModel;

}

// returns a PanelTab with the DataTable

public HtmlPanelTab getHtmlPanelTab(int id) {

HtmlPanelTab htmlPanelTab = new HtmlPanelTab();

htmlPanelTab.setLabel(getTableName());

htmlPanelTab.setId("panelTab"+ id);

HtmlDataTable ioDataTable = new HtmlDataTable();

ioDataTable.setId("dataTable" + id);

ioDataTable.setBorder(1);

// add ValueBinding

FacesContext facesContext = FacesContext.getCurrentInstance();

Application app = facesContext.getApplication();

ExternalContext ext = facesContext.getExternalContext();

ExpressionFactory elFactory = app.getExpressionFactory();

ELContext el = facesContext.getELContext();

ValueExpression vExp;

vExp = elFactory.createValueExpression(el, "#{datamodeltest.dataModel}", DataModel.class);

ioDataTable.setValueExpression("value", vExp);

ioDataTable.setVar("item");

// The columns are also dynamically generated depending on

// the "tableName". As an example I have defined them as follows:

UIColumn colFirstName = new UIColumn();

HtmlOutputText headerComponent = new HtmlOutputText();

headerComponent.setValue("First Name");

headerComponent.setStyleClass("columnheaderStyle");

colFirstName.setHeader(headerComponent);

HtmlOutputText colFirstNameValue = new HtmlOutputText();

vExp = elFactory.createValueExpression(el, "#{item.FIRSTNAME}", String.class);

colFirstNameValue.setValueExpression("value", vExp);

colFirstNameValue.setRendererType("javax.faces.Text");

colFirstName.getChildren().add(colFirstNameValue);

ioDataTable.getChildren().add(colFirstName);

// further columns and text are added ...

htmlPanelTab.getChildren().add(ioDataTable);

return htmlPanelTab;

}

...

}

This method is called from a "FOR" loop in the TabbedPaneBean.

The HtmlPanelTab returned is added to the HtmlPanelTabbedPane as shown below.

public HtmlPanelTabbedPane getTabbedPane(){

HtmlPanelTabbedPane htmlPanelTabbedPane = (HtmlPanelTabbedPane) FacesContext.getCurrentInstance().

getApplication().createComponent(HtmlPanelTabbedPane.COMPONENT_TYPE);

// iterate over the tablenames

for (Iterator iter = tableNames.iterator(); iter.hasNext();) {

String currName = (String) iter.next();

// I set the "tableName" variable in the DataModelTest class

// with the current table name

setTableName(currName);

DataModelTest dataModelTest = new DataModelTest();

htmlPanelTabbedPane.getChildren().add(dataModelTest.getHtmlPanelTab(id));

}

}

Here is a part of the faces-config.xml ...

...

<managed-bean>

<managed-bean-name>tabbedpanebean</managed-bean-name>

<managed-bean-class>TabbedPaneBean</managed-bean-class>

<managed-bean-scope>session</managed-bean-scope>

</managed-bean>

<managed-bean>

<managed-bean-name>datamodeltest</managed-bean-name>

<managed-bean-class>DataModelTest</managed-bean-class>

<managed-bean-scope>session</managed-bean-scope>

</managed-bean>

...

The JSF page contains the following tag...

<%-- Display a TabbedPane with each tab corresponding

to a different table in the database--%>

<t:panelTabbedPane binding="#{tabbedpanebean.tabbedPane}"

bgcolor="#EBEEF8" width="90%" cellspacing="1" />

Well, I get the TabbedPane with the tab names corresponding to the database tables. If there are four database tables, I get four tabs rendered on the HTML page but the contents of the DataTables in every tab are the same. (There are no DataTables if I have the logic embedded in the DataModelTest default constructor)

I wish the tabs to have the corresponding table data.

I hope you can understand.

Eagerly, looking out for some help.

Thank you!

veerathua at 2007-7-14 19:21:12 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 3
"#{datamodeltest.dataModel}"Where do you load the corresponding dataModel? How does the datamodel getter know which data have to be loaded?If you don't have such a logic, try using f:attribute with a datamodel ID in it, for example.
BalusCa at 2007-7-14 19:21:12 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 4
Hallo BalusC,That was the problem I have.Thank you for the idea to use <f:attribute />. I will try with it.RegardsSreekanth
veerathua at 2007-7-14 19:21:12 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 5

In getHtmlPanelTab (int id)

method I write the logic or call a method that sets the DataModel with the corresponding table data(table is known from the passed id

).

I have a plan to load the complete DataTable whenever the user clicks on the respective tab. I think this leads to a huge degradation in performance as each table might have more than 40,000 records and a minimum of four tabs exist.

Your comments are welcome.

Thanks

veerathua at 2007-7-14 19:21:12 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...
# 6

You got it working with f:attribute?

And about the performance: well, the tabbedpanel uses CSS to display/hide the tab contents. So all the data is loaded in once indeed ..

One solution is to write or build your own components or pieces of HTML implementing form actions behind a tab. So each tab should act as a form and invoke the managed bean when clicked.

I despitely don't know other easy ready-to-use solutions.

BalusCa at 2007-7-14 19:21:12 > top of Java-index,Enterprise & Remote Computing,Web Tier APIs...