Oracle ADF: set focus to input field in data table

At my current client we had the first user acceptance test of a new Oracle ADF application. We have a lot of data entry pages in our application, where database records are presented in editable tables. Each table has a tool bar, with a “Create new record” button on it. One of the things the users noticed during the test, is that when they created a new record, the new record showed up in the table and was selected, but the first input field in the record didn’t have the input focus. I looked for a setting in ADF to set the input focus after creating a new record, but didn’t find anything. So I created my own solution…

I found a blog post by Lucas Jellema that shows how to set the focus on a particular field in an input form. That’s nearly what we want, except that in my case the input field is inside a data table. And that makes it a bit more difficult. In a form, it is simple to give an input component an ID and refer to that ID to give it the focus, as outlined by Lucas on his blog. But in a data table, an input component gets a dynamically generated ID, since we can only define an ID at column level, but on runtime there are typically many rows in a table.

With the use of FireBug, I figured out that an ID of an input component in an <af:table> typically looks like this: pt1:pc4:table3:15:it1. This string can be split up in the following parts:

  • pt1:pc4:table3 – This is the client ID of the data table. This is the ID we gave the table in our JSPX, prepended with the IDs of naming containers of which the table is a child.
  • 15 – This identifies the row within the table. Due to sorting and other things, this number is not related to the number of rows for a new record, as you might have expected.
  • it1 – This is the ID we gave to the input component at column level in our JSPX.

So to set the focus to our input component, we have to find a way to determine this client side ID at runtime, on the server side. I came up with the following Java code:

Now we have our ID, we can use the same “piggy back” method that Lucas described on his blog to set the focus to the component with that ID. Our action listener method now could look like this:

Note that we use the special findComponent() method from the ADF JavaScript API to find the component by it’s ID. At the TODO comment at the top of the method we have to insert code to create a record. If you’re using ADF Bindings, you can do it like this:

This assumes you’ve defined a CreateInsert operation in your ADF Bindings pageDef. And that’s it. To top it off, here’s a small example of how to use this in a page:

The most important thing to notice here is that the button doesn’t call an ADF Bindings method directly, but delegates that task to the action listener method in our bean.