JDeveloper: Info about the clicked cell in an af:table

JDeveloper allows to easily create tables with the af:table component. The table allows easy access to the selected row or rows. However, if you are interested in which cell of a table has been clicked, ADF needs some tweaking. This blog is about how to tweak an af:table to get exactly this info.

Use Case

You like to know which cell in an af:table a user has clicked, e.g. to get some detailed information about the clicked item or cell in the selected row. The sample I show get the information about the current row, and column of the cell and the value of the cell clicked. The final sample will show the info like

How to do it?

The normal af:table component doesn’t give information about the cell a user has clicked on. The ADF pivot table offers this but is complex to use.

We use JavaScript in form of a clientListener to intercept the click on a cell and a serverListener to call a bean method to get more data on the cell. This article 011. ADF Faces RC – How-to use the Client and Server Listener Component shows how to use clientListener and serverListener in detail.

As we are interested in the selected cell, we add a clientListerer to each af:outputText which shows the column value in the af:table which fires on the click event. The clientListener calls a JavaScript method. In the JavaScript method, we build a payload of the UIComponent which is used to show the column value and the column name of the cell. To get this information we have several possible ways:

  1. We can use our knowledge of the DOM tree and get the column via the parent of the component which fired the event. The parent component should be the af:column.
  2. We add a client attribute to the component which shows the cell value adding the column name from the af:column as EL

In this sample, we choose the second solution. With this information, we call the serverListener from the JavaScript method. The serverListener method is implemented in a request scope bean and uses the information passed to get the details about the clicked cell we show in the UI.


The sample uses the HR DB schema and only needs one table, Employees in this case. We create a simple page with the table in read-only mode, sortable and filterable. As you see in the image above the table is just build be dragging the Employees VO onto the page and drop it as a read-only table.

Now we add a clientListener and a serverListener to each outputText component which is used to show the cell value

In the image above we see the listener for two columns. In addition, we add an af:clientAttribute with the name ‘columnName’ which we pass the EL of the af:column headerText property.

Next, we add an af:resource component to the af:document where we specify the JavaScript for the clientListener method ‘clientCellSelectionCall’. We use a JavaScript file to code the method. We could have added the method to the page directly, but if we want to reuse the pattern, it’s better to use a JavaScript file

The file is located in the public_html folder (Web Content) in a subdirectory ‘javascript’

The method code is

The click event on the af:outputText component triggers a call to the javascript method ‘clientCellSelectionCall’ (via the clientListener) with the source of the event, the af:outputText component. The method reads the clientAttribute added (line 3) and calls the serverListener of type ‘cellSelection’. This event is defined by the af:serverListener on the af:outputText. The component which triggered the event and the column name added as client attribute are passed to the serverListener.

The serverListener is a bean method defined in a request scope bean on the af:outputText component as


In the bean, the method looks like

public void handleTableCellSelection(ClientEvent event) {
  // get payload which is the ui component which fired the event
  UIComponent ui = (UIComponent)event.getParameters().get("payload");
  // get the column from the event which is sent too
  String column = (String)event.getParameters().get("column");
  RichOutputText rt = (RichOutputText)ui;
  // get current row key
  DCBindingContainer bindingContainer = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
  DCIteratorBinding binding = bindingContainer.findIteratorBinding("EmployeesViewIterator");
  Row currentRow = binding.getCurrentRow();
  Key key = currentRow.getKey();
  // compile info about clicked cell
  String out = "Payload:" + ui + "
  column: "+ column + "
  val: " + rt.getValue() + "
  key: "+key.toString();

Here we get the component which triggered the event (as payload) and the name of the column. Using this information we can get e.g. to the value of the column (via the UI component). The row of the cell we get via the current row of the iterator. With this information, we get the key of the row. We can get much more information here, like historical data about the current employee’s salary, if the salary cell was clicked.

We just create a string from the information which we show in the UI to the user

Here are some images of different cells clicked in the UI:


You can download the sample, which was built using JDeveloper, from GitHub BlogTableCellSelection. The sample uses the HR DB schema.


JDeveloper: Prevent Navigation from Field on Failed Validation

This post shows how to implement a use case where you don’t want the user to leave a field which has a validation error. ADF does a good job enforcing that all validations are checked at the time you submit the data. However, if you want the user to correct an error in a field directly, you have to implement it yourself.

Use Case

A validation error can be a mandatory field which the user has not filled in or a where the user has filled in wrong data. In such a case you want that the user must correct the error before she/he is allowed to move to the next field.


We start with a fragment whihc holds two af:inputText components. One we use to simulate a mandatory input text and the other for a normal input text field.


The ‘Test’ button is used to submit the form. If we hit the Test button without any data in the fields we get


as hte ID field is marks required. One you enter something into this field you can successfully submit the form


That is the normal behavior ADF gives you out of the box. The use case  we implement here requires, that the user can’t leave the field once an error is shown for the field. So if the user sets the cursor to the ID field he can’t navigate away from it until he fixes the error. He can’t even click hte button. ADF would allow the user to leave the ID field to enter some value into the Name field.

So how do we prevent the user leaving the field by clicking in another field or clicking on a button?

We use an af:clientListener which listens for the ‘blur’ event checking if the field contains a value. If not, we set the focus back to the component and cancel the ongoing even. Setting the focus back to the component is essential as the blur event tell us that we loose the focus. This only happens if the user navigates away from the field.

 function setFocusWhenValidateFail(event) {
   var element = event.getSource();
   var val = element.getValue();
   var cid = element.getClientId();
   console.log("Value=" + val);
   if (val == null) {

The JavaScript function above shows this. This function is called via an af:clientListener we added to the af:inputText component

 <af:inputText label="ID (mandatory)" id="it1" required="true" 
     value="#{bindings.myId1.inputValue}" autoSubmit="true">
   <af:clientListener method="setFocusWhenValidateFail" type="blur"/>

This is it. But wait, what if we like to check if the value entered by the user is valid?

Now, this add another complexity. For this we need to either code the validation in JavaScript or we have to call a bean method which can do the complex check on hte server side model. For easy checks it’s no problem to implement them in JavaScript in the ‘else’ part of the function above.

To call a server side method we need to add an af:serverListener which calls a bean method

 <af:inputText label="ID (mandatory)" id="it1" required="true" 
     value="#{bindings.myId1.inputValue}" autoSubmit="true">
   <af:clientListener method="setFocusWhenValidateFail" type="blur"/>
   <af:serverListener type="validateServerListener" 

and we change the JavaScript function

 function setFocusWhenValidateFail(event) {
   var element = event.getSource();
   var val = element.getValue();
   var cid = element.getClientId();
   console.log("Value=" + val);
   if (val == null) {
   else {
     console.log("call server with " + cid + " and " + val)
     //call bean method validateServerListener
     AdfCustomEvent.queue(element, "validateServerListener", 
         fcid : cid, fvalue : val
       }, false);

Note that we add two parameters to the call to the bean method. The first parameter fcid is the client id of the component which calls the bean method. The second parameter fvalue is the value the user has entered into the field. We see why we need the parameters when we talk about the bean method.

In the bean we implement the custom validateServerListener method. First we get the two parameters from the ClientEvent and log them to the console. At this point we can e.g. call an application module method with the parameter  we got. In this simple same we just check the value for a specific value, in this case ’88’. When the value is ’88’ we add a  FacesMessage to the component with the clientId we got as second parameter.

However, just adding the FacesMessage wont be enough. At this point he focus has already shifted out of the component and the message would not displayed until the component is selected again. The event.cancel() in the JavaScript function does not prevent that the focus is shifted out of the component. The solution is to reset the focus to the component from the bean again. For this we add JavaScript code which will be executed after the event has finished. The JavaScript searches for the component by it’s Id and then calls component.focus()  to set the focus back to this component.

   public void handleValidationEvent(ClientEvent ce) {
        // get client id from event
        Object obj = ce.getParameters().get("fcid");
        String clientId = "";
        if (obj != null) {
            clientId = obj.toString();

        // get field value from event     
        String val = "";
        Object obj2 = ce.getParameters().get("fvalue");
        if (obj2 != null) {
            val = obj2.toString();
        logger.info("client id =" + clientId + " value=" + val);
        // do a check if hte value if OK
        // here we check against 88 to keep it simple. You can check against other model values here too!
        if ("88".equals(val)) {
            // check failed -> add message to the component and set the focus back to the component
            FacesContext facesContext = FacesContext.getCurrentInstance();
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error", "Wrong vlaue");
            facesContext.addMessage(clientId, msg);
            // javascript to set focus to component identified by it's clientId
            String script = "var t=document.getElementById('" + clientId + "::content');t.focus();";

    //generic, reusable helper method to call JavaScript on a client
    private void writeJavaScriptToClient(String script) {
        FacesContext fctx = FacesContext.getCurrentInstance();
        ExtendedRenderKitService erks = null;
        erks = Service.getRenderKitService(fctx, ExtendedRenderKitService.class);
        erks.addScript(fctx, script);

Sample Application

You can download the sample application from GitHub BlogNoNavigationValidation. The sample doesn’t use a model layer, so no DB connection is needed.


JDeveloper: Execute Bean Method on Hitting Enter in af:inputText Component

This blog article describes a common use case. A user enters some value into an field on the page and his enter. This should trigger a method on the server (e.g. a bean method).

Use case
Hitting ENTER on a af:intputText component should trigger an action (e.g. executing a bean method).

The sample we implement in this blog shows a page with a splitter component. On the left side we see an input text component which is used to enter a value. On the right side we see the result of the search as a table of countries from the HR schema. The search condition used is to show all countries which names starting with the value entered in the input text component.

Sample Application

Sample Application

As you see there is no button ot other command component to execute the search. The search is triggered by hitting enter in the input text field on the left side of the splitter.

Filtered Output after hitting Enter

Filtered Output after hitting Enter

To implement this we need to use JavaScript af:clientListener to handle the keyboard input. The javascript method then queues a server action using a af:serverlistener.

<af:inputText label="Country" id="it1" value="#{bindings.SelCountryName1.inputValue}" autoSubmit="true">
    <af:clientListener method="handleEnterEvent" type="keyPress"/>
    <af:serverListener type="EnterEvent" method="#{SendEnterBean.handleEnterEvent}"/>

The af:clientListener listens for keyPress event and in the JavaScript method checks weather the key pressed was the enter key or not. If it was the enter key it queues an event for a server side method in a bean. The method name is given in the af:serverListener type=”EnterEvent” method=”#{SendEnterBean.handleEnterEvent}”. The method listen for the event type send from the client AdfCustomEvent.queue(comp, “EnterEvent”, {fvalue:comp.getSubmittedValue()}, false);. This type is defined in the serverListener as type property.

<af:resource type="javascript">
    function handleEnterEvent(evt) {
      var _keyCode = evt.getKeyCode();
      //check for Enter Key
      if (_keyCode == AdfKeyStroke.ENTER_KEY ){    
          var comp = evt.getSource();
          AdfCustomEvent.queue(comp, "EnterEvent", {fvalue:comp.getSubmittedValue()}, false);

The server side method now calles the “executeWithParams” method on the courntries iterator which filters the countries table for countries starting with the value given by the input field.

    public void handleEnterEvent(ClientEvent ce) {
        _logger.info("Got event " + ce.getType());
        // get the binding container
        BindingContainer bindings = BindingContext.getCurrent().getCurrentBindingsEntry();
        // get an Action or MethodAction
        OperationBinding method = bindings.getOperationBinding("ExecuteWithParams");
        if (method == null) {
        _logger.info("Method ExecuteWithParams not found in current bindings");

        // get the parameter from the event
        String message = (String) ce.getParameters().get("fvalue");
        //This can be used too if one doesn't like to send the parameter to the method
        // get an ADF attributevalue from the ADF page definitions
        //AttributeBinding attr = (AttributeBinding)bindings.getControlBinding("SelCountryName1");
        //String v = (String)attr.getInputValue();

        //Set the parameter
        Map params;
        Map map = method.getParamsMap();
        map.put("bindName", message);

        // check for errors
        if (!method.getErrors().isEmpty()){
            Exception ex =(Exception) method.getErrors().get(0);
            _logger.warning("Error: " + ex.getLocalizedMessage());

        // PPR refresh a jsf component

The missing part is how the countries table get filtered. For this in the model layer we created a ViewObject “CountriesView” for the COUNTRIES table of the HR schema. Then we define a ViewCriteria “CountriesByNameVC”:

ViewCriteria CountriesByNameVC

ViewCriteria CountriesByNameVC

In the data model of the application module we use the view object instance CountriesView1 and select the ViewCriteria as query.

Edit View Instance CountriesView1 to use ViewCriretia CountriesByNameVC

Edit View Instance CountriesView1 to use ViewCriretia CountriesByNameVC

Now in the ViewController project we only need to store the value entered by the user in the af:inputText field and add add a method binding for the “executeWithParams” method which we use in the bean method to filter the table.

Final pageDef

Final pageDef

and the source for the pageDef file:

<pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel" version="" id="BSE2BPageDef" Package="de.hahn.blog.sendenter2bean.view.pageDefs">
    <variableIterator id="variables">
      <variable Name="SelCountryName" Type="java.lang.String"/>
    <iterator Binds="CountriesView1" RangeSize="25" DataControl="BSE2BAppModuleDataControl" id="CountriesView1Iterator"/>
    <tree IterBinding="CountriesView1Iterator" id="CountriesView1">
      <nodeDefinition DefName="de.hahn.blog.sendenter2bean.model.dataaccess.CountriesView" Name="CountriesView10">
          <Item Value="CountryId"/>
          <Item Value="CountryName"/>
          <Item Value="RegionId"/>
    <attributeValues IterBinding="variables" id="SelCountryName1">
        <Item Value="SelCountryName"/>
    <action IterBinding="CountriesView1Iterator" id="ExecuteWithParams" RequiresUpdateModel="true" Action="executeWithParams">
      <NamedData NDName="bindName" NDValue="#{bindings.SelCountryName1.inputValue}" NDType="java.lang.String"/>

You can download the sample, which is build using JDeveloper and uses the HR schema, from ADF Sample Source Code Repository