Skip to main content

ADF 11g : Using the ActiveRowKey property

In ADF 11g Release 2, the ADF Table component has a property called 'ActiveRowKey'. According to documentation, this represents the row that is currently active on the client. In click-to-edit mode, the active row will be made editable and is brought into view (if not already visible). Upon initial display, the click-to-edit component defaults the active row to the first visible row.

In this post I will show you how to use the activeRowKey programmatic.

Use Case.

Imagine the following use case: I have a 'click-to-edit' table and I added a 'filter' field with a button in the surrounding panel collection. User enters (in this case) a last name and pushes the button. The table scrolls to the first row that matches the criteria, and the row is active to edit.

Implementation.

I create an ADF table based on ADF business components for the Employees table.
It's a clickToEdit table with singleSelection. After creating it I bind it to a bean. I'll show later why I need to do that. The table code looks like this:
1:        <af:table value="#{bindings.Employees1.collectionModel}" var="row"  

2: rows="#{bindings.Employees1.rangeSize}"
3: emptyText="#{bindings.Employees1.viewable ? 'No data to display.' : 'Access Denied.'}"
4: fetchSize="#{bindings.Employees1.rangeSize}"
5: rowBandingInterval="0"
6: selectionListener="#{bindings.Employees1.collectionModel.makeCurrent}"
7: rowSelection="single" id="t1" editingMode="clickToEdit"
8: selectedRowKeys="#{bindings.Employees1.collectionModel.selectedRow}"
9: binding="#{pageFlowScope.empsBean.empTable}">
10: <af:column ............................


Next I surround it with a panel collection and I turn off a lot of features (also new in R2) of the panel collection. In the toolbar facet I add an inputText component and a commanfbutton. The inputtext will hold the search value, and the button invokes logic to scroll the table and make to row active.

1:       <af:panelCollection id="pc1" featuresOff="viewMenu detach" >  

2: <f:facet name="menus"/>
3: <f:facet name="toolbar">
4: <af:toolbar id="t2">
5: <af:group id="g1">
6: <af:inputText label="enter last name" value="#{pageFlowScope.empsBean.searchValue}" id="it11"/>
7: <af:commandToolbarButton text="goto employee" id="ctb1"
8: actionListener="#{pageFlowScope.empsBean.gotoPressed}"/>
9: </af:group>
10: </af:toolbar>
11: </f:facet>


In the actionListener I first get a hold of the RowSetItetator. For each and every row in the rowSetIterator, I check if it matches the entered search string. I do that in a separate method called matchFound() (see line 8).

1:   public void gotoPressed(ActionEvent actionEvent) {  

2: // Add event code here...
3: DCIteratorBinding it = ADFUtils.findIterator("Employees1Iterator");
4: RowSetIterator rsi = it.getRowSetIterator();
5: RowKeySet oldSelection = empTable.getSelectedRowKeys();
6: if (rsi.first() != null) {
7: Row r = rsi.first();
8: while (rsi.hasNext() && getKey() == null && (!matchFound(r,oldSelection))) {
9: r = rsi.next();
10: }
11: }
12: }


In the matchFound() method I compare the value of the LastName attribute with the value entered by the user (see line 7). If it is a match there are two more things I need to do. First I add the key of the row found to be the activeRowKey (see line 11). Finally I need to make the row current. If I dont do this, it will still work, but by making the row current, it just looks a lot nicer. The trick I use here (see line 13) is a method (line 18) that I borrowed from Frank Nimphius' blog.

1:   private boolean matchFound (Row r,RowKeySet oldSelection){  

2: setKey(null);
3: ArrayList lst = new ArrayList(1);
4: RowKeySetImpl newSelection = new RowKeySetImpl();
5: Key key = null;
6: String rowValue = (String)r.getAttribute("LastName");
7: if (rowValue.toString().contains(searchValue)) {
8: System.out.println("now setting key to " + key);
9: key = r.getKey();
10: lst.add(key);
11: empTable.setActiveRowKey(lst);
12: newSelection.add(lst);
13: makeCurrent(empTable, newSelection, oldSelection);
14: return true;
15: }
16: return false;
17: }
18: private void makeCurrent(RichTable empTable, RowKeySet newCurrentRow, RowKeySet oldCurrentRow) {
19: //To make a row current, we need to create a SelectionEvent which
20: //expects the following arguments: component, unselected_keys,
21: //selected_keys. In our example, we don't have unselected keys and
22: //therefore create an empty RowSet for this
23: SelectionEvent selectionEvent =
24: new SelectionEvent(oldCurrentRow, newCurrentRow, empTable);
25: selectionEvent.queue();
26: AdfFacesContext.getCurrentInstance().addPartialTarget(empTable);
27: }


The works.

Start the application, type some searchText, push the button and of you go.


The row is found, and immediate available for edit.


Resources.

ADF Code Corner Oracle JDeveloper OTN Harvest

A copy of the workspace for this post can be downloaded here.

Comments

Timo said…
Nice work!
Hint for uploading the workspace (which I use on wordpress):
zip it, rename it to .jpg and upload it as image

Timo
Luc Bors said…
Thanks Timo, I'll try that trick for uploading the workspaces
giovanni said…
The property is very interenting, can you send me your test wkj?

thank Gio.
Zee said…
Nice post luc. You can host your apps at code.google.com like i do

http://code.google.com/p/orclsamples
Luc Bors said…
This comment has been removed by the author.
Luc Bors said…
Thanks for the tip. I think google code can be an excellent place to host my workspaces. I'll try that soon.
Luc Bors said…
I decided to host my workspaces at google code. The workspace for this post is now available at http://adfsamplecode.googlecode.com/files/activeRowKey.zip
Anonymous said…
Hi, could you explain the need to use key to null at the first step of matchFound
Anonymous said…
setActiveRowKey does not work in 11.1.1.6.

Has anyone tried it?

Popular posts from this blog

ADF 12.1.3 : Implementing Default Table Filter Values

In one of my projects I ran into a requirement where the end user needs to be presented with default values in the table filters. This sounds like it is a common requirement, which is easy to implement. However it proved to be not so common, as it is not in the documentation nor are there any Blogpost to be found that talk about this feature. In this blogpost I describe how to implement this. The Use Case Explained Users of the application would typically enter today's date in a table filter in order to get all data that is valid for today. They do this each and every time. In order to facilitate them I want to have the table filter pre-filled with today's date (at the moment of writing July 31st 2015). So whenever the page is displayed, it should display 'today' in the table filter and execute the query accordingly. The problem is to get the value in the filter without the user typing it. Lets first take a look at how the ADF Search and Filters are implemented by...

ADF 11g Quicky 3 : Adding Error, Info and Warning messages

How can we add a message programatically ? Last week I got this question for the second time in a months time. I decided to write a short blogpost on how this works. Adding messages is very easy, you just need to know how it works. You can add a message to your faces context by creating a new FacesMessage. Set the severity (ERROR, WARNING, INFO or FATAL ), set the message text, and if nessecary a message detail. The fragment below shows the code for an ERROR message. 1: public void setMessagesErr(ActionEvent actionEvent) { 2: String msg = "This is a message"; 3: AdfFacesContext adfFacesContext = null; 4: adfFacesContext = AdfFacesContext.getCurrentInstance(); 5: FacesContext ctx = FacesContext.getCurrentInstance(); 6: FacesMessage fm = 7: new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, ""); 8: ctx.addMessage(null, fm); 9: } I created a simple page with a couple of buttons to show the result of setting the message. When the but...

ADF 12c : Using Jasper Reports en JasperSoft Studio 6.1; What Libraries do you need?

Over the last couple of years, or better in the last decade I have implemented several reporting solutions with Jasper Reports in ADF. I did that in ADF 10g, ADF 11.1.1.x, ADF 11.1.2.x and ADF 12.1.x I also used several version of Jasper Reports. There is a whole lot of documentation, blogposts and presentations available. So when today I got a request from one of my customers to make a setup for the implementation of Jasper Reports 6.1 in ADF 12.1.3 I did not expect any problems. Boy was I wrong. Here is the Story With all the knowledge from the past, I decided to follow the known steps. 1) Download iReport Designer, 2) Build a report in iReport 3) Create an ADF application 4) Add the necessary libraries to use the report 5) Call the report from a button via a Managed Bean Step 1 In the past I used iReport designer to build the reports. When you go to the download site of iReport designer you now see an interesting message. So I took this serious and decided not to u...