Sunday, March 2, 2014

Improving ADF UI Table CRUD Functionality with Auto Focus

Improving and tuning ADF applications performance, doesn't mean only ADF framework technical parameters tuning. Performance tuning could be applied to application UI behaviour. I will use ADF Faces table example in this post, by default when new row is inserted - focus for the new row column is not set, user needs to do one extra click to set focus and start entering data. There is a way to eliminate this extra click and set focus automatically for a column in ADF table row. I will describe generic method to achieve such functionality.

Let's see first, how it works. We have regular ADF Faces table:


Press Create button to insert a new row:


By default, when new row is inserted - focus in the new row column is not set, user needs to do one extra click and set focus by himself. This is improved in my sample application - ADFTableFocusApp.zip, focus in the new row column is set automatically after Create button is pressed (it is configured to set focus in the first column):


It is important to understand, while setting focus for ADF UI table row columns, each row in HTML is assigned with certain ID. This ID is appended to the original inputText component ID, basically the same inputText component is created as many times, as there are rows in the table. Here you can see, new row was assigned with index 25, this is index is not related to row number:


Focus ID - inputText component ID in the first column of a new row. This points to a region, panelCollection, table, row ID and inputText component ID's.

I create one more row:


Focus is set automatically:


This time, row ID was different - I will describe below, how such ID can be retrieved in generic method:


From implementation point of view, there is Create button with JSF attributes. One of the attributes, sets ID of inputText for the focus, second provides action name to be executed. Focus is set through JavaScript function:


There are few changes needed for ADF UI table properties. Make sure to set contentDelivery="immediate" and displayRow="selected" properties, this is needed to ensure focus will be set correctly every time, even when user scrolls through the table:


Sample application implements generic action lister, it reads method to execute from component attribute, as well as UI component ID to apply auto focus. We are locating table binding automatically, getting Client Row Key (this is row ID, I was mentioning in the example above) and constructing final ID to use for the focus. As you can see, method action is executed first, and auto focus code afterwards (we need to have new row inserted initially):


At last, JavaScript method is invoked from Java, to set focus in the row identified by row ID number.

18 comments:

  1. Hi Andrejus, the only concern I have with this is that you need to hard code the input text's ID. Oracle should provide this out of the box to focus on new created row. Regards. Leon.

    ReplyDelete
  2. This is just an example. No need to hardcode, you could identify field to focus in more sophisticated ways, all depends on the use case and requirements. For example, through custom property, etc.

    Andrejus

    ReplyDelete
  3. Thanks Andrejus, works like a charm!

    ReplyDelete
  4. Hi, I use Jdev 11.1.1.7. I tried the same in my application and for chrome and firefox it works. But the only issue that i have is, if i browse any other tabs/files in my pc after clicking on the commandlink i dont see my cursor and if have my application open always and if don't browse anything then it works fine.

    In IE, its not working. When i press the button then the cursor is not going to the expected field but i could see the tooltip getting displayed.

    Any Advice?

    ReplyDelete
  5. Saved My Day.

    Thanks.

    ReplyDelete
  6. After migrating to 12.2.1.1 this code is still working and the focus is placed in the correct field. HOWEVER after filling in the EmployeeId and hitting the TAB-key, the input focus is lost, and not placed into the next input-item. It seems that ADF 12.2.1.1 does something strange with the focus management.

    ReplyDelete
  7. Dear @Jo in de Walvis

    I am having same issue. Do you find any solution for it.

    ReplyDelete
  8. Same reproduced on my side in 12c. No solution at the moment.

    Andrejus

    ReplyDelete
  9. @Umer Farooq, @Jo in de Walvis, @Andrejus,

    We too are facing the same issue, Focus is lost on hitting the tab-key, while attempting to move to next column.

    An SR with Oracle didn't help much, as they claim the WAG 2.0 guidelines require to press F2 to make the table a tab-stop.
    But in this case, we have to cycle through all the editable elements from Row 1 to reach current editable row.

    Do let us know if there is any workaround.

    Regards,
    Vishwanath S K

    ReplyDelete
  10. Yes, we had same reply.

    I found there is a bug related to focus. It works to set focus programmatically in client component for ADF form, but doesnt work if input component is located in the table. Going to update SR with this issue. It must be issue with ADF table and focus in 12c. This is the reason, why focus is not moving anymore - after it was set by calling JS from the bean.

    Regards,
    Andrejus

    ReplyDelete
  11. Dear Andrejus,

    Is there any solution for the focus lost on TAB key. Hope you file SR. Any update from Oracle.

    ReplyDelete
  12. SR was logged, but no solution. Oracle support says - this is how it supposed to be :)

    Andrejus

    ReplyDelete
  13. Dear Andrejus,
    Any solution found for the focus lost issue to Tab-Press. or any work around.

    Umer Farooq

    ReplyDelete
  14. Hi,
    We have found the solution.
    Please check it out on this OTN thread(page 2):
    https://community.oracle.com/thread/4007524

    ReplyDelete
  15. This comment has been removed by the author.

    ReplyDelete
  16. Hi Andrejus

    my UI design is like following

    jsff page---->Popup---->panel header---->panel collection----->table.

    in this scenario I tried the code but absolute id i got is wrong(obviously).What I should do
    to get the absolute id of the input text ?

    Thanks

    ReplyDelete