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
Very nice. See and learn jQuery in practice.
ReplyDeleteWhat would be incredibly nice is also have the row hightlighted.
Any idea how to incorporate that in the above solution?
gr. Bart
Hi Bart,
ReplyDeleteThis 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
Hi, Alex.
DeleteI was searching the web for a way to highlight a row in a classical or Interactive report on my Apex 4.1 page and then stumbled across this post.
I really like the way you clearly explained, step-by-step, how to use JQuery selectors to make an entire report row "clickable". That is so cool and useful.
I also see your suggestion on how to highlight a row using css. I tried out your code and it works great.
However, I need a way to keep the report row highlighted as users navigate to other regions on the same page. The highlighted row serves as "context" to tell users which row is the currently "active" row.
Would you know how to accomplish this and, simultaneously, make this highlighted row "clickable".
Thank you for any help.
FYI: When I click the "Reply" link on this blog using IE9.x, nothing happens. I had to open the blog in Firefox 15.x in order to get this "Reply" dialogue box to appear.
Thanks, again.
Elie
Hi Elie,
DeleteThank you for your nice comments.
Yes, it's possible to keep the highlighted row as context. See an example here: http://apex.oracle.com/pls/apex/f?p=47888:EMP09:0::NO::
1) Create a hidden item to store the clicked EMPNO
2) Add the following javascript code at page level:
$(function(){
clicked_empno = $("#P9_EMPNO").val(); $('a[href$="P9_EMPNO:'+clicked_empno+'"]').parent().parent().children().addClass('highlight-employee') ;
});
This will add css classes (named highlight-employee) to all elements for the value stored in the hidden item
3) Add a CSS rule to do the actual highlighting: .highlight-employee{background-color: blue !important;}
4) In the link (column level), set the value for the hidden item
Well, IE... what can I say :)
Alex
Wasn't sure if the steps above was enough information that I decided to write a short note about it: http://nuijten.blogspot.nl/2013/01/apex-highlight-record-in-report.html
DeleteHi,
ReplyDeleteIts a good post however i have two links that open different pages howcan i accomplish this. thanks
Hi Anonymous,
DeleteThe big question is: how do want it to work? How do you decide which link to open?
Alex
nice post...it's what I'm looking for...
ReplyDeletebut 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
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.
DeleteIs 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.
the problem is solved. :)
DeleteI changed :
$('a[href*="FORM09"]')
with :
$('a[href*="9"]')
where 9 is the page number, not an alias...
thank you...
Zee
Hey!
ReplyDeleteGreat code and it works, until you use pagination to go to page 2 in your report.
Any suggestions?
Thanks in advance!
Yvonne
Ah yes, good point... this is what you can do (not saying it's the best way, but... )
Delete1) move the code that's in the "Execute when Page Load" section to the "Function and Global Variable Declaration" section
2) before the code add: function rowClick(){
3) after the code add: }
With steps 2 and 3 you create a function which can be used (almost) everywhere.
4) in the "Execute when Page Load" section add: rowClick();
That's the name of the function created in steps 2 and 3
5) add a Dynamic Action (Advanced type)
Event: After Refresh
Selection Type: Region
Region: Employees
True Action: Execute Javascript Code
Code: rowClick();
That should do it.
Not yet working :(
DeleteWe're working on it.
Maybe it's because we use an Javascript call as our link..?
$('a[href*="ShowDetail"]')
The jQuery that you post is the selector, not a link. This selector means: find me all anchors which have ShowDetail in the link somewhere. The way I used the selector is to find the page-alias (which would be ShowDetail in your case).
DeleteI created a new page, as described in my earlier reply: http://apex.oracle.com/pls/apex/f?p=47888:10:330414103723501:::::
check it out, using Firebug or Chrome..
This comment has been removed by the author.
ReplyDeleteWorks like a charm.
ReplyDeleteThe only thing I needed to do was change the page-alias (EMP002)
Thanks for this post - over the past year I've ran all sorts of places with this as a starting point.
ReplyDeletenice post. some more details for general use in older versions (3.2 or <4). place the final code in jQueries function block in page html header:
ReplyDelete(script block)
$(function() { [source] }});
(/script block)
most important part about "EMP002" is that its not page alias nor region id, its a jQueries search string for the url content. if your "pencil" was linking to javascript:editLine(xxx), then use "editLine" as search keyword in source (or some other distinct value to separate your region from others). if you got some unique parameters - try using them as search keywords.
last bit that is still missing - cant hide the "pencil" column. whatever I try, href content is not found by jQuery.
added $(this).css('display', 'none'); as a last line in the "a" loop and its done.
DeleteThe javascript stops working after using search on an interactive report. Any solution to this?
ReplyDeleteYes, the "Execute when Page Load" is not the right place to put the javascript... This will cause it to only execute when the page loads (hence the name :)). It would probably be better to execute the javascript after refresh of the report region.
DeleteHi Alex
ReplyDeleteI'm pretty new to Apex and I have to do the same thing: Make a report row clickable. Now, before the actual code there is this on your example:
apex.jQuery( document ).ready( function() {
(function(){apex.widget.report.init("R1698825128352646793",{"styleChecked":"#ccc","internalRegionId":"1698825128352646793"});})();
I understand that the long number is the Page ID. But what about the other, like "styleChecked", "#ccc", "internalRegionId"? From where did you get them?
Thanx
Sara
Hi Sara,
DeleteSorry for the late reply (vacation :))
The long number in your code is the Region ID, not the page ID.
I'm not sure where that came from, possibly because the application is using an "old" theme.
You don't need that code for it to make the row clickable (just tried it out on apex.oracle.com).
Are you using Page Aliases? And for navigation as well?
Alex
Hi Alex,
Deletehope you had an amazing vacation..
Well at first I tried your code from above, but somehow there was no reaction, then I went over your example using the Page source, where I saw this long number "Region ID" and I was wondering if this was my problem, but it wasn't. Yet I don't know what the problem there was, but I found another solution instead. I put the code in the "HTML Header" field. In the beginning this didn't work either, because the usual Javascript opening wasn't enough in Apex 5 (in Apex 4.2 it works well with that), I had to put another code before. It took me a while to figure that out, but now it works just fine.
Thanx anyway for your answer, I appreciate it.
Sara
P.s. I of course us Apex 5.0, but this shouldn't be the problem that it's not working..
ReplyDeleteHi Alex, as usual a great post!
ReplyDeleteThe code works as expected but I have a apex.item.checkbox as the first column in my row and when checking this it also triggers the row-click, is there any way to exclude the checkbox or prevent the checking of the box also to trigger the row-click?
kind regards Anders
DeleteFound the solution my self.
juast add .children('td:not(:first)') on the parent selection as below.
$(this).parent()
.parent('tr').children('td:not(:first)')
cheers
Anders
This comment has been removed by the author.
ReplyDeleteHi Alex, please how can I access the steps to highlighting a report row without actually submitting the page? The highlighted row should be based on the value in a hidden page item. i can see you have a demo called KEEP HIGHLIGHTED 2 but I cannot see the steps you took to achieve that.
ReplyDeleteRegards
Trix
Hi Alex,
ReplyDeletePlease how can I access the steps to highlighting a report row without actually submitting the page? The highlighted row should be based on the value in a hidden page item. i can see you have a demo called KEEP HIGHLIGHTED 2 but I cannot see the steps you took to achieve that.
Regards
Trix