Changing the order of columns in a JSF Table Component -in the client, at run-time, by the end user

The Rich UI components (see ADF Faces Rich Client Components – Marrying JSF and AJAX together) that the ADF Faces library will contain with the JDeveloper 11g release – and hopefully before that moment – will allow end-users to do all sorts of manipulations with Tables. They will be able to resize columns an drag & drop columns to change the order – much like you can do in Spreadsheet applications like Excel. However, those components are not yet available to us. Yesterday my customer asked me if he could have offer the option to re-order columns in a table to his end users. That means that in any table component, the user can decide which column should be displayed first, which one second and which one last. It happened to be the same customer who was after the feature to show/hide columns at run-time, a challenge easily resolved in a previous article: Having the end-user hide and display columns in a JSF Table Component.

In this article, we will see how we can implement this feature: have the end-user specify the order of the columns in the table. I have used ADF Faces for this demonstration, but any JSF implementation will do.

The starting point for the implementation of the reorder feature is a simple Table Component, created by hand, using ADF drag & drop or JHeadstart generation. It shows all columns from the EMP table (SCOTT sample schema), with Deptno and Mgr represented by Dropdown Lists based on the underlying Foreign Keys to table DEPT and EMP respectively.

The steps to implement the reorder columns feature are these:

Add a panelBox with Shuttle-Order-Only element

Add a command button and bind its action to a method on a backing bean

Implement the action method on the backing bean – updating the table’s children based on the settings in the Shuttle

Configure the tableBean as managed bean in the faces-config.xml

And putting it altogether turns out to be surprisingly simple, thanks to the component nature of JSF and the ease of using Expression Language.

Step 1 – Add a panelBox with the Shuttle-Order-Only element

The panelBox component is positioned next to the table, separated from it using an objectSpacer. All three elements are wrapped in a panelHorizontal (table, spacer and panelBox). Inside the panelBox, there is a selectOrderShuttle element, whose selectItems represent the columns in the table. To make a match between the selectItems in the shuttle and the columns in the table, the value of the selectItems needs to correspond with a property on the columns; I have picked the sortProperty property on the columns.

Note that the Shuttle’s value is bound to a managed bean – tableBean – more specifically to the columns property in that bean – a String[]. When the form is submitted, the bean’s columns property is updated with the current value.

The action property on the commandButton is bound to the ill-named method commandButton_action on bean tableBean. We have to implement that method next.

Step 3 – Implement the action method on the backing bean – updating the table’s children based on the settings in the Shuttle

The action method commandButton_action in the tableBean should do several things: it has to read the value of the shuttle (the ordered list of column references), get hold of the list of table children (the CoreColumn objects) and rearrange the latter based on the sequence of the former. It can use the columns property in the bean that is linked to the value property of the Shuttle Component.

If we set the Shuttle as shown above and press the commandButton, the column headers will be redisplayed in this order:

And beyond – combining showing/hiding and re-ordering columns

It is now a very simple step to combine two features discussed in recent articles: the re-ordering of columns as demonstrated in this article and the showing/hiding of column as demonstrated in a prior piece. If we change the shuttle from orderOnly to select and order, we can both select the column to display and order them in the same component:

The change in the code for this shuttle component is subtle, real subtle. See if you can spot it:

Well, I will tell you: the property reorderOnly is changed from true to false. That is it!

The implementation olf the tableBean will be slightly extended, to provide for a Map based on the columns property, that can be used by the af:column elements to determined their visibility. First the bean:

Note: the initialization of the columns property of the tableBean has now gained some significance: any column not included in the initial value of columns is initially invisible in the table. However, it will be available from the shuttle for subsequent selection and displayal. The following managed bean configuration can be used:

This EL expression specifies that the column is visible in the client if the columnsMap property (a HashMap) on the tableBean contains an entry with the same String used for sortProperty of the Column used for a key and the Boolen static true as value. The columnsMap is directly derived from the columns property: any entry in the columns array will be in the columnsMap.

The result of the initialization of the managed bean tableBean and the binding of the rendered attribute is something like this for the initial screen:

It is easier than simple to go from the picture above to the one below:

Thanks for your very kind words. And you got it right: it takes a lot of thinking upfront and trying out to arrive at what turns out to be a very simple solution. I was pleasantly surprised to find out how easy it really was.

And unfortunately no – I do not have additional insights into the release date of the ADF Faces Rich Client libraries. I will try to harras some people during OOW to find out. Once I do, it will be on the blog, so keep reading.

Hi Lucas, I’m impressed….. It is an example of how extended knowledge can result in very usable solutions that are, in the end, actually very simple to implement. Don’t get me wrong here, I know how that works. It takes days to find the solution and then all at once….. "Eureka". Do you have any inside information on the release date of the new ADF faces library ? As I said, I’m impressed, and you guys deserve, as so often, my credits for another very usable solution. Thanks. Luc Bors

Lucas Jellema

Lucas Jellema, active in IT (and with Oracle) since 1994. Oracle ACE Director for Fusion Middleware. Consultant, trainer and instructor on diverse areas including Oracle Database (SQL & PL/SQL), Service Oriented Architecture, BPM, ADF, JavaScript, Java in various shapes and forms and many other things. Author of the Oracle Press books: Oracle SOA Suite 11g Handbook and Oracle SOA Suite 12c Handbook. Frequent presenter on conferences such as JavaOne and Oracle OpenWorld. Presenter for Oracle University Celebrity specials.

Follow us on Twitter

meta

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 323 other subscribers

Email Address

About

AMIS is internationally recognized for its deep technological insight in Oracle technology. This knowledge is reflected in the presentations we deliver at international conferences such as Oracle OpenWorld, Hotsos and many user conferences around the world. Our AMIS Technology Blog, the most referred Oracle technology knowledge base outside the oracle.com domain. However you arrived here, we appreciate your interest in AMIS. Link to our Google+ Profile AMIS