• Post Reply Bookmark Topic Watch Topic
  • New Topic

Dynamic datatable in jsf  RSS feed

 
venkateswara rao ravinuthala
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

I have a list of Transactions class objects which is dynamically generated so it can have n number of Transaction class objects.

While displaying i need to show that in datatables.

How to generate dynamic datatables.

Please help me in this.


[color=darkblue]Map groups = new HashMap();
for (Iterator it = trans.iterator(); it.hasNext();)
{
DisplayTransaction t = (DisplayTransaction) it.next();
Number rid = t.getResolutionId();
Resolution res = ResolutionDAO.getResolution(new Long(rid.longValue()));
groups.put(rid, new DisplayFollowup(res.getResolutionTxt()));
}
List result = new ArrayList();
result.addAll(groups.values());
DataModel dataModel = new ListDataModel(result);


in jsp using that dataModel for displaying transactions.

<t:dataTable id="trans" var="queueColumnValue" value="#{display.dataModel}" >

<t:columns ....
...>
..>

 
Tim Holloway
Bartender
Posts: 18715
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the JavaRanch!

What precisely do you mean by "dynamic datatable"? People often use that when they want to be able to change the number and types of columns, but as far as I can tell, you're only looking at a variable number of rows. A variable (dynamic) number of rows is automatically done for you and you don't need to do anything more.

Helpful hint: when publishing samples of formatted text (java code, XML, and so forth), we have a special tag that preserves the format and makes it easier to read. You can insert this code tag by clicking on the "Code" button of our forum message editor.
 
venkateswara rao ravinuthala
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tim,

(A)one list - one dataTable scenario

I have a list object 'result', using that i am creating one DataModel object as follows:
DataModel dataModel = new ListDataModel(result);

In UI i am displaying as follows which is working well and good.
<t:dataTable id="trans" var="queueColumnValue" value="#{display.dataModel}" >

<t:columns ....
...>
..>

(B) one list object holding multiple lists - multiple dataTable scenario

I have a list object 'multiList' which has no of list objects

multiList = [list1, list2, list3, list4] -------> here no of list objects will be dynamically added so n no should be supported
DataModel multiDataModel = new ListDataModel(multiList);

in UI i am expecting a result of multi datatables to be displayed
<t:dataTable id="trans" var="queueColumnValue" value="#{display.multiDataModel}" >

<t:columns ....
...>
..>
i am getting all the data in rows in a single dataTable

I would want to display each list as a seperate dataTable (dynamically n no of datatables to be displayed )

Thanks for your support and I appreciate your help


 
Tim Holloway
Bartender
Posts: 18715
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
OK. I hope I understood. Sometimes it takes me a while.

If you want a "table of tables", you can define an outer dataTable which contains an inner dataTable definition. That only works when you're stacking them vertically, and there are problems with reconciling model objects when they are selected.

If you want a "table of tables" where the layout of the tables is done horizontally or free-form, use the Facelets ui:repeat tag as the outer table to contain the inner dataTables.

Each dataTable requires its own unique dataModel, since the JSF DataModel contains context for that particular View. However, since the DataModel wraps the actual data without actually modifying it, the underlying data for the table can be shared between multiple dataModels if that's what you want.
 
venkateswara rao ravinuthala
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tim,

Yes i want the multiple datatables displayed vertically.

How can i set n no of lists in dataModel object, how can i display it in the UI. (as i do not know how many no of lists being generated on runtime)

It would be very helpfull if you can provide me an example.

Thanks for your help.


 
Tim Holloway
Bartender
Posts: 18715
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
DataModel wraps a Collection or Array. The number of rows in your displayed table will therefore automatically be the number of rows in the model. Or less, if you use the "windowing" attributes of the dataTable tag to display a limited number of rows from your model.

You can handle a vertical stack of tables in one of 2 ways.

A) You can use the ui:repeat to enumerate a List of DataModel objects and have it wrap the h:dataTable element that prototypes the nested tables.

B) You can use an outer h:dataTable to define a 1-column table that wraps the inner h:dataTable element that prototypes the nested tables.

The tricky part is that JSF in its present form doesn't make it easy to tell exactly which row of which table you selected when you clicked on a commandButton or commandLink from within the inner table. I've had to violate my general rule of keeping Model and View separate to pull the actual xhtml id of the target row from the submitted data and parse it. Not very pretty or simple.

You can find discussions on this problem by searching this forum.
 
venkateswara rao ravinuthala
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ok. Thanks Tim.

I will try out using ui:repeat.

Thank you very much for your support.
 
venkateswara rao ravinuthala
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tim,

Display wise its working fine as expected multiple tables.

But now facing a problem when i click on a commandLink from within the inner table not able to pick the exact row which i am clicking.

Can you please help me in that.
 
Tim Holloway
Bartender
Posts: 18715
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's a nasty little problem that was discussed here: http://www.coderanch.com/t/520612/JSF/java/getting-object-instance-inside-nested#2362880

And I spent a lot of time arguing that it shouldn't have to be this hard. Well, it shouldn't, but it turned out that it is. I hope someone fixes that in the next version of JSF.

When I ended up having to manage nested datatables soon after this thread, I had to do some awkward things. First of all, I had to capture the row number of the selected inner table using a listener:


The architecture of this view is such that the inner object's ID is in the form "formId:outerTableId:outerRowNum:innerTableId:innerRowNum", which is where the "[4]" comes from. When I split between the ":" separators, the value I want will be the 5th element in a string array indexed starting at 0.

I know things are bad when I have to implement a Listener and it has to dig into View properties. That adds View dependency to the backing bean, and that's never good.

Now, having captured the inner row number, I reference it in the action method:



blendRow gives me the DataModel row object for the selected inner table, which is itself a DataModel. I then obtain the actual row, using the row index that my listener captured before the action method was invoked.

Yuck.
 
venkateswara rao ravinuthala
Greenhorn
Posts: 7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tim,

My issue got fixed.
Thank you very much for your valuable responses.

 
Vivek Bejawar
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Venkat,
How your issue got fixed..? Could you please explain..?

Hi Tim,
I too have the same problem.
The IDs were not in that order as you mentioned.
The ID of components of inner table were like "formIduterTableId:innerTableId:innerRowNum".
There was no outer row number being set. That's where the duplicate IDs for each of the inner data table and when I change something in one text field of an inner table, it is being set to another component of having same id. Please help in this regard.

thanks
Vivek
 
Tim Holloway
Bartender
Posts: 18715
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If there's no outer row number in the generated ID, take a closer look at the tags, because it's quite likely that the inner table was put into the outer table's header or footer instead of an outer table row!
 
theresa silva
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
venkateswara rao ravinuthala wrote:Hi Tim,

Display wise its working fine as expected multiple tables.

But now facing a problem when i click on a commandLink from within the inner table not able to pick the exact row which i am clicking.

Can you please help me in that.


hi! how did you make it work? :-)
 
Tim Holloway
Bartender
Posts: 18715
71
Android Eclipse IDE Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The other day, I believe pompously declared that I'd never used an actionListener in JSF.

Which only goes to show that:

1. I'm senile

2. I'm an idiot

ActionListeners are used far too often in places where they only make the app more complicated than it should be. But there are times when the simpler solution can't do the trick, and this, alas, is one of them.

JSF2 doesn't provide support for resolving rows within nested tables. Only the outermost table will return a valid rowData object and a valid rowIndex. They really need to fix that.

In the mean time, we have to do something nasty. Since JSF won't resolve the inner row on its own, we have to do it the hard way, peeking into the forbidden innards of the JSF component tree and coding stuff that's directly UI-dependent.

Here's an example:


What this little horror does is obtain the ID attribute of the commandButton or commandLink that fired it and shred the ID string, picking out the outer and inner table indexes. It assumes that that ID will be in the form "formId:outerTableId:ix1:innerTableId:ix2", where ix1 and ix2 are zero-based row numbers. This method ONLY extracts those indexes and captures them as internal backing bean properties - I don't want to mix UI and business logic. The business logic is in a plain old action method that is also fired by the same event:


Note that this method uses ix1 and ix2, as set previously by the listener. I've subclassed the normal DataModel for convenience. It adds the "getData()" method, which allows typesafe access to the underlying rowData and it provides the "recalc" method that recalculates table totals so that they may be fetched and displayed in the table footer. There are actually 2 subclasses of DataModel here. One of them is the "sourceBlends" model, which is the DataModel for the outerTable, and one is the inner SourceBlend class, which has multiple instances, one for each inner table.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!