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.
Baig 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

How to: Adding Speech to Oracle Digital Assistant; Talk to me Goose

At Oracle Code One in October, and also on DOAG in Nurnberg Germany in November I presented on how to go beyond your regular chatbot. This presentation contained a part on exposing your Oracle Digital Assistant over Alexa and also a part on face recognition. I finally found the time to blog about it. In this blogpost I will share details of the Alexa implementation in this solution.
Typically there are 3 area's of interest which I will explain. Webhook Code to enable communication between Alexa and Oracle Digital AssistantAlexaDigital Assistant (DA) Explaining the Webhook Code The overall setup contains of Alexa, a NodeJS webhook and an Oracle Digital Assistant.
The webhook code will be responsible for receiving and transforming the JSON payload from the Alexa request. The transformed will be sent to a webhook configured on Oracle DA. The DA will send its response back to the webhook, which will transform into a format that can be used by an Alexa device. To code exposes two REST …

How to use node-red to interact with twitter

Recently I had to setup an application that was able to read twitter and, based on some predefined keywords,  had to reply to specific tweets. I decided to have a look at node-red to set this stuff up. It proofed to be rather straightforward and easy to implement. The hardest part was to get approval for a twitter developer account. In this post I describe how I used node-red and how I implemented the interaction with twitter.
What is node-red, and how to use it? Node-RED  (https://nodered.org/) is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways. It provides a browser-based editor that makes it easy to wire together flows using the wide range of nodes in the palette that can be deployed to its runtime in a single-click.  You can use node-RED in many ways, but for the purpose of this demo I decided to run it in a docker image. I used the way described here (https://hub.docker.com/r/nodered/node-red-docker/), as this is a no…

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 butto…