In ADF 10g, table component was working only with pagination support, in ADF 11g table component was improved greatly and now it works with scrollable support. However, time to time we hear customer requests to provide pagination support for ADF 11g table, as it was in ADF 10g. There are different requirements, when table pagination would work much better comparing to scrollable functionality. Ideally, ADF 11g table should support both options - pagination and scrollable functionality. While pagination is not supported, we can implement our own custom table component. This post implements it as a task flow, in my future posts I will publish ADF reusable component based on similar approach.
Download sample application with custom table implementation - CustomLayoutADFIterator.zip.
Custom table is implemented using af:iterator tag. This tag allows to render collection of data, just the same as af:table tag renders. Same as af:table tag, af:iterator can be based on table binding available in page definition. It iterates over data collection and renders data rows - this allows to generate table view:
Value property of af:iterator is binded to collection model from ADF bindings declaration. Number of visible rows at one time (on one page) is set to 10, initial row to render is set from first row 0:
Next or previous page of rows is rendered by changing first row indicator, last page is calculated as well. Good thing, we dont need to store indicator for current page in the memory, we can always calculate it:
af:iterator tag points to ADF bindings table declaration, it gets same collection model as af:table tag:
Here is example of custom table from provided sample application. You can change layout, add more functionality - its all standard ADF components:
It always displays 10 rows (configurable) on the page, provides buttons to navigate between pages and shows current page number. If user is moves to second or third page, navigation buttons for previous page become enabled:
If we navigate to the last page, navigation buttons for next navigation become disabled:
This table provides option to click either on First Name or Last Name and open editable pop-up for current row:
User hits OK button, changes are saved and our custom table current page is refreshed with changed data:
With af:iterator tag, we can't get current row as we are used to do with af:table. This can be resolved by declaring JSF attribute for command link component, and retrieving this attribute inside managed bean method. Attribute value is used to set current row for editable pop-up:
Download sample application with custom table implementation - CustomLayoutADFIterator.zip.
Custom table is implemented using af:iterator tag. This tag allows to render collection of data, just the same as af:table tag renders. Same as af:table tag, af:iterator can be based on table binding available in page definition. It iterates over data collection and renders data rows - this allows to generate table view:
Value property of af:iterator is binded to collection model from ADF bindings declaration. Number of visible rows at one time (on one page) is set to 10, initial row to render is set from first row 0:
Next or previous page of rows is rendered by changing first row indicator, last page is calculated as well. Good thing, we dont need to store indicator for current page in the memory, we can always calculate it:
af:iterator tag points to ADF bindings table declaration, it gets same collection model as af:table tag:
Here is example of custom table from provided sample application. You can change layout, add more functionality - its all standard ADF components:
It always displays 10 rows (configurable) on the page, provides buttons to navigate between pages and shows current page number. If user is moves to second or third page, navigation buttons for previous page become enabled:
If we navigate to the last page, navigation buttons for next navigation become disabled:
This table provides option to click either on First Name or Last Name and open editable pop-up for current row:
User hits OK button, changes are saved and our custom table current page is refreshed with changed data:
With af:iterator tag, we can't get current row as we are used to do with af:table. This can be resolved by declaring JSF attribute for command link component, and retrieving this attribute inside managed bean method. Attribute value is used to set current row for editable pop-up:
Is it possible to do this using a table instead of an iterator?
ReplyDeleteI know it turns out to be the same, but some clients just have to have their windows looking table on the page!
I was testing same with af:table, but no matter what values are set for FetchSize or Rows properties, it looks like always still fetching all available rows. I will continue to look into this, but at this stage I didnt found option to restrict number of returned rows with af:table. Its why I was using af:iterator.
ReplyDeleteAndrejus
Yes, I was having the same issue. The table just seems to ignore the settings.
ReplyDeleteI'm kind of new to ADF, so I thought maybe I was just missing something, but it seems not.
Is it possible to use the column operations like sorting?
ReplyDeleteThis can be implemented, but not supported by default.
ReplyDeleteAndrejus
Hi Andrejus, can you kindly let me know if it is possible to replace the first 25 rows of an ADF read-only table with the next 25 rows on clicking a command button named Next.
ReplyDeleteNo its not, you need to build your custom component, as per this blog post.
ReplyDeleteOr you can use Trinidad table, it provides table pagination.
Andrejus
is it possible to implement row selection in this example?
ReplyDeleteit would be great if you provide a example for it
I think it would be possible only with checkbox per each row.
ReplyDeleteAndrejus
Hi,
ReplyDeleteUsing this link i was able to do pagination for table.
http://codeplay.net/2011/04/21/simple-adf-traditional-pagination-2-with-business-component/
Your example is using Range Paging. Combination of Range Paging and ADF UI table will not work, in case you will have LOV, or choice lists inside table rows.
ReplyDeleteAndrejus
Hi,
ReplyDeleteI am trying to implement the similar functionality. however when i am trying the build the expression using the expression builder for the switcher's facet name , i am not able to create the expression.for example : if i try to create the facet name as #{item.panelBoxRendered}, I am getting only item under the implicit jsp objects. But When i try to do it in the sample project provided in this post, there i can see methods under the item object.
Do we need to include any specific jar file or is it something to do with version of adf/jdev. Currently i am using jdeveloper 11.1.2 for development.
In your app, where points "item" object, where it is binded?
ReplyDeleteAndrejus
Hi, I am able to implemnet the pagination as you have explained in example. I need to add link on one colum on each row. The link should execute one action for navigating to detail page. When I add link to one column with an action then it's not executing the commandlink action. It is just refreshing the same data. Why the command link action inside af:iterator is not working but if I place the command link with same action outside the af:iterator then I am able to navigate to requied page. Could you please help here?
ReplyDeleteThanks
Chandra
Try to add programmatic Action method and see if its invoked?
ReplyDeleteAndrejus
Is it possible for you to send me sample application with this problem for review?
ReplyDeleteAndrejus
The action was not invoking when I set the 'CacheResults' property set to 'false' for the iterator executable. It is working fine with property value 'true'. I am not sure why action is dependent on this property.
ReplyDeleteI am also trying to sort colums when user clicks on column header. You said that sorting is posible in your comment. Is it posible to share sample code for sorting?
Thanks,
Chandra
I am able to implement sorting also.
ReplyDeletepublic void sortFleetGroups(ActionEvent actionEvent){
String property = (String)actionEvent.getComponent().getAttributes().get("sortProperty");
boolean flag = true;
List list = this.getFgIterator().getSortCriteria();
for(SortCriterion item : list){
if(item.getProperty().equals(property)){
flag = item.isAscending()?false:true;
}
}
list = new ArrayList();
list.add(new SortCriterion(property, flag));
this.getFgIterator().setSortCriteria(list);
}
This is quite cool.
ReplyDeleteAndrejus
I am also checking if there is any support for filter functionality. Please let me know how to achive filter functionality here.
ReplyDeleteI think one way is e-executing binding with filter criteria. Is there any other way to filter out within results instead of re-executing the service call. If there is no support in the service call for required filter criteria then need to filter with in results only.
ReplyDeleteI think you can execute the same criteria, as af:table invokes.
ReplyDeleteAndrejus
Tried but not able to find solutions. Could you please let me know links to samples or code snippet?
ReplyDeleteI don't have links, I will need to look into it.
ReplyDeleteAndrejus
Hi,
ReplyDeleteThanks for the sample example on pagination, this is realy helpfull
I want one help on this,
If there are no primary key in the table, then how can i edit the details and save the changes. Instead of binding empId for an attribute, how can i use the composite primary key for editing the details and saving them. Or even without using composite PK is that possible to edit proper details and save them
Please help me out on this.
Hi Andrejus,
ReplyDeleteCan the pagination be customised to some thing line << 1,2,3,... >> instead of the FIRST, PREV, NEXT, LAST options.
Thanks
Ashwin
Yes - I think it can be, quite easily. Should work. Just change logic in the bean to handle it.
ReplyDeleteAndrejus
It is very useful to me.
ReplyDeleteHere my problem is it taking long time when we click next button .The table have more than 3000 records. Is there any better solution for this.My requirement is when we click next button it will take 100 records and then print 20 records per page for eachtime when we click next. After complete these 100 records, it will take another 100 reccords and do same process at end of the records
Hi Andrejus,
ReplyDeleteIs it possible with this approach to get the row highlight and mark the row as currentrow after row click? Same as to what af:table provides.
Thanks,
Valon
Hi Andrejus, is it possible to replace the first few columns of an ADF read-only table with the next few columns on clicking a command button named Next. And also 1st column being as it is, and next columns replaces on click of next. Suggest me if it can be achieved with any other way with declarative component or with custom component.
ReplyDeleteThanks.
Hi,
ReplyDeleteI am using af:table and i did settings as above, but table is fetching all available rows. Please let me know if you find any solution.
Thanks,
Subbu