29 November 2011

APEX: Make a report row clickable in Report

When you create a "Report with Form", there will be an icon in the report which allows you to navigate to  the form page. Only when the user clicks the icon this navigation will take place. For the current project, this was not what they wanted. They wanted to click on the row instead of just the icon. This can be simply implemented using jQuery.
For this example we are going to use a "Report with Form" and modify it as described below.
All of our pages in the application have a page alias, the Report page alias is "EMP001" and the Form page has an alias "EMP002".
The default behaviour will appear in the page like the below screenshot, the cursor will turn into a small hand only when you move your mouse over the icon.

But we want to achieve the following: moving the cursor over the whole row changes the cursor to a small hand  indicating that the whole row is clickable. And not only that, also that the whole row is in fact clickable.
To achieve this we would need to "move" (or copy) the anchor to row-level.

When you look at the generated HTML code, it will look something similar to this:
The highlighted line in the picture is the icon which is shown in the Report page (alias: EMP001). As you can see in the image, the anchor (the "a" tag) has an href attribute which contains all the information it needs to navigate to the Form page (alias: EMP002). Even the page alias is in there, and this is what we will use to select the correct href.
Because the page alias is in the anchor, we can use the jQuery selector to get the appropriate element

$('a[href*="EMP002"]')

This will result in an array of anchor elements which we want to manipulate. For each of the elements in the array we want to retrieve the href attribute. The href attribute, we will keep in a local variable named "lnk". Now the code will look like:
$('a[href*="EMP002"]').each(function(index) { 
    lnk = $(this).attr('href');

});


This variable with the href attribute is going to be place at row level as a "data-href". From the current element we need to move up to the row level (tr) and add the attribute.

   $(this).parent()
          .parent('tr')
    .attr('data-href', lnk)

To make it clickable, we also need to add a click event to the row. This is where jQuery really shows its power, we can "chain" the click event to our selector. The code will grow slightly to the following:

 $(this).parent()
          .parent('tr')
    .attr('data-href', lnk)
    .click(function(){
      window.location=$(this).attr('data-href');
    })

To give the user the feedback that the row is clickable, we need to change the cursor to a little hand. Again we chain the mouseover event to the selector

$(this).parent()
          .parent('tr')
    .attr('data-href', lnk)
    .click(function(){
      window.location=$(this).attr('data-href');
    })
    .mouseover(function(){
      $(this).css('cursor', 'pointer');
    })

And because we also want to change the cursor back to default when the user move the cursor away from the rows in the report, the mouseleave event is also required

   $(this).parent()
          .parent('tr')
    .attr('data-href', lnk)
    .click(function(){
      window.location=$(this).attr('data-href');
    })
    .mouseover(function(){
      $(this).css('cursor', 'pointer');
    })
    .mouseleave(function(){
      $(this).css('cursor', 'default');
    })
Now that the jQuery code is complete, we can add this to the page
Double click at page level to open the page properties, and paste the jQuery code in the section labelled "Execute when Page Loads" and we are all set.


When you run the page you will notice that the whole row is clickable.
Inspecting the HTML after we add all the jQuery code will show that there is an anchor at the row level now, just what we wanted.

To make copy the code for your own use, the completed jQuery code will look like this
$('a[href*="EMP002"]').each(function(index) {
   lnk = $(this).attr('href');
   $(this).parent()
          .parent('tr')
    .attr('data-href', lnk)
    .click(function(){
      window.location=$(this).attr('data-href');
    })
    .mouseover(function(){
      $(this).css('cursor', 'pointer');
    })
    .mouseleave(function(){
      $(this).css('cursor', 'default');
    })
});
And to see this in action you can find a demo on apex.oracle.com

7 reacties:

  1. Very nice. See and learn jQuery in practice.

    What would be incredibly nice is also have the row hightlighted.
    Any idea how to incorporate that in the above solution?

    gr. Bart

    ReplyDelete
  2. Hi Bart,
    This is one way to highlight the row on when you move the mouse (which can be done with CSS):
    My report rows have a class attached called "highlight-row" (this can be seen in the screenshot of the generated HTML)
    At page level, place this CSS style in the section called HTML Header:

    <style type="text/css">
    tr.highlight-row:hover td
    {
    background-color: #d12421 !important;
    color: #ffffff;
    }
    </style>

    A better way is to place this CSS in the appropriate CSS file.

    Hope this helps.

    Alex

    ReplyDelete
  3. Hi,
    Its a good post however i have two links that open different pages howcan i accomplish this. thanks

    ReplyDelete
    Replies
    1. Hi Anonymous,

      The big question is: how do want it to work? How do you decide which link to open?

      Alex

      Delete
  4. nice post...it's what I'm looking for...
    but when I applied it to my application, it didn't work...
    I copied the jQuery code, then put it in 'Execute when Page loads' field with FORM09 as my form page.but nothing happen...
    can u tell me where is my mistake?

    thanks....
    Zee

    ReplyDelete
    Replies
    1. It's is quite hard to comment on where you made a mistake without being able to look "over your shoulder". There are many possibilities causing it "not to work". When you use a modern browser you might want to look what is going on "behind the scenes". In Firefox or Chrome you can use F12 to detect any errors in the console window.
      Is this application in a place where I can access it, like on apex.oracle.com? If that is the case, you might drop me an email and I'm willing to take a look at the way you implemented it.

      Delete
    2. the problem is solved. :)
      I changed :
      $('a[href*="FORM09"]')
      with :
      $('a[href*="9"]')
      where 9 is the page number, not an alias...

      thank you...

      Zee

      Delete