how to loop through rows in datatable?
Hi,
I have a datatable component with a few columns bound to a database table but I have also added a new textfield column to the datatable. The purpose of this datatable is to present the user with a list of products from the database and then allow the user to enter a quantity value into the textfield for each product (ie datatable row).
This all works fine until i need to capture the quantity values the user has entered. It seems the datatable component can only provide the current row details. However what I want to do is when the user finishes entering the quantities for all the products they click a button and then I loop through each row in the datatable from start to end and find out what quantities were entered for each product.
I can find no documentation or threads on how to do this. It seems like a very basic concept but perhaps is not possible to achieve. Can anyone help?
Also I entered a default value of "0" in the value expression (ie text) property of the new textfield in the datatable but this value never appears (ie the textfields are always empty). However the text property seems to work ok for normal textfield components not within a datatable. Any ideas?
Thanks.
# 1
I do something very similar to this in this sample project: http://blogs.sun.com/divas/entry/table_component_sample_project
# 2
thanks, I am able to iterate through the datatable rows now and get the values, however I still have one (actually two) big problem...
1. I cannot get the textfields to be prepopulated with a value when the page first loads. I have the text property of the textfield set to a value but this makes no difference, the textfields are always blank.
2. After a user enters values and clicks the button to calculate the page reloads and again all entered values are gone (ie the damn textfields are empty again). Is this normal behaviour for textfields within a datatable....surely not.
So, I added some code to my prerender method to specifically populate the textfields and although it loops through each textfield only the last textfield gets populated. I cannot work this one out. Datatables should be easy to work with, but like most things Creator turns an easy job into an impossible one.
Please help.
# 3
It would probably simplify your task dramatically if you bound your textfields to something. You can then manipulate the underlying property and not worry about the textfield.
# 4
Hi, that would be ideal however i'm not sure if its possible, here's why.
The value of the textfield will be different for each row in the datatable (ie each row represents a product and each textfield will store the quantity for each product). So the textfield would need to be bound to an array of quantity values (probably stored in a sessionbean) which is not possible because a textfield can only be bound to a single value. Furthermore, even if it could be bound to an array how would it know which array element to bind to each row in the datatable, the relationship is simple not there.
Perhaps you know of a different and/or better way?
Thanks.
# 5
I wrote a wiki page that describes (among other things) how to obtain the rownumber using binding. If you look in winston's blog and Tor's blog they show you how to do it from the page bean (using getValue()). Either technique will allow you to bind to an array (or list) and make life a lot simpler for you.
http://wiki.java.net/bin/view/Javatools/ExpressionLanguage
in general something like #{Page1.Array1[currentRow.tableRow.rowId]}
should work
# 6
Did you look at the sample table project that I gave the URL for? In that sample, the table has a column of text field for entering values, similar to what you want. Similar to what Yossarian suggested, the servings text field is bound to a method that sets the value for each row based in the rowid.
The text property for NbrServingsTF (the text field in the column) is bound to SessionBean1.nbrServings. The getter for that property is:
public Integer getNbrServings() {
TableRowDataProvider rowData = (TableRowDataProvider) getBean("currentRow");
if (rowData == null) {
return new Integer(1);
} else {
String rowId = rowData.getTableRow().getRowId();
Integer nbrServingsValue = (Integer) this.getNbrServingsMap().get(rowId);
if (nbrServingsValue == null) {
return new Integer(1);
} else {
return nbrServingsValue;
}
}
}
# 7
Jetsons: I downloaded your sample project and ran it on VWP. No issues except that the button on the detail page suffers from the IE7 bug.
I then modified the binding of the nbrServingsTF as follows:
<ui:textField binding="#{Page1.nbrServingsTF}" ....... text="#{SessionBean1.nbrServingsMap[currentRow.tableRow.rowId]}" ..... />
and commented out the getNbrServings() and setNbrServings(Integer) methods
The project runs fine like that. You decide which is simpler.
UCC: If you add a HashMap to your SessionBean called (say) mapHolder with standard getters and setters accepting and returning a Map (you can right click the sessionbean and choose add..) and then bind your textfield to #{SessionBean1.mapHolder[currentRow.tableRow.rowId]} that shold solve your problem. Attach an appropriate converter of course.
# 8
wow, you guys are great!
I've never used a hashmap before but that is exactly what i needed and it works perfectly now too. I feel inspired once again!
Thanks to both of you, i decided to go with jetsons solution as it allowed me to become more familar with the hashmap and therefore what i am doing. Perhaps down the line i may want to start streamlining things with EL, but until then, thanks!
# 9
Hey Yossarian! Always keeping me on my toes. Diva #1 has actually started writing a tutorial based on the sample app. I will tell her about your step saving alternative.Diva #2
# 10
Jetsons: ;-)Also the purists might also prefer a List instead of a Map as the keys are regular predictable Integers. Personally, I just use Maps for just about everything...Message was edited by: yossarian