Skip to main content

Clicking in a Row

First of off, consider my recent absence a summer vacation of sorts, without the vacation part. It's been hectic since my last post, which was about, wow - ODTUG. We had over 100 people in our training sessions there, and most of the feedback was great! We hope to do it again next year, if not sooner.

The reason for my absence was largely due to the fact that we recently moved, and pretty much everything that you can think of and then some, went horribly awry.

In any case, I was recently asked how to make an entire row in a report "clickable", so that when anywhere in a row is clicked, the user will be taken to a form to edit that record.

In order to achieve this, you need to create a new Named Column Report Template. This means that you will have to define each column that you want to have manually in the template itself. Hardly a scalable solution, but it's not too difficult to implement and expand on.

I am only going to use one Row Template to keep things simple. For Row Template #1, I entered the following HTML:
<tr style="cursor: hand; cursor: pointer;" onmouseover="row_mouse_over(this, 1)" onmouseout="row_mouse_out(this, 1)" #HIGHLIGHT_ROW# onClick=window.location="f?p=&APP_ID.:2:&SESSION.::::P2_EMPNO:#EMPNO#">
<td class="t15data" #ALIGNMENT#>#EMPNO#</td>
<td class="t15data" #ALIGNMENT#>#ENAME#</td>
<td class="t15data" #ALIGNMENT#>#SAL#</td>
</tr>
In my example, I am only using three columns from EMP: EMPNO, ENAME & SAL; to add more columns, you would simply add more <td>'s to your template.

To explain what each line does:
style="cursor: hand; cursor: pointer;"
This will cause the cursor to change to the pointer finger. Two directives are needed since MSIE & Firefox work slightly differently when changing cursors.

onmouseover="row_mouse_over(this, 1)" onmouseout="row_mouse_out(this, 1)" #HIGHLIGHT_ROW#
The onMouseOver and onMouseOut will highlight the row that the cursor is hovering over. This functionality is built in to Row Templates, but since we are using a Named or Column template, we have to hard-wire it manually.

onClick=window.location="f?p=&APP_ID.:2:&SESSION.::::P2_EMPNO:#EMPNO#" Here's what makes it work; we set an onClick event in the <tr> tag that when clicked, we re-direct to page 2, passing in the current value of EMPNO to the APEX item P2_EMPNO. This is where you would alter the target URL, should you find yourself building an application that does not use the EMP table...
Next, you will need to add a few more components to the Report Template. I kept the Column Headings simple and just copied over what was in the Standard Report Template:
<th class="t15header" #ALIGNMENT#>#COLUMN_HEADER#</th>
You will need to add both some HTML and JavaScript to the Before Rows section:
<script type="text/javascript">
var rowStyle = new Array(15);

var rowActive = new Array(15);
var rowStyleHover = new Array(15);

for (var n = 0; n < 15; n++)
{
rowStyle[n]='';
rowStyleHover[n]='';
rowActive[n]='N';
}
function row_mouse_over(rowNode,currentRowNum)
{
rowActive = 'Y';
for( var i = 0; i < rowNode.childNodes.length; i++ )
{
if (rowNode.childNodes[i].tagName=='TD')
{
rowStyleHover[currentRowNum] = rowNode.childNodes[i].style.backgroundColor;
rowNode.childNodes[i].style.backgroundColor = '#cfe0f1';
}
}
}

function row_mouse_out(rowNode,currentRowNum)
{
rowActive = 'N';
for( var i = 0; i < rowNode.childNodes.length; i++ )
{
if (rowNode.childNodes[i].tagName=='TD')
{
rowNode.childNodes[i].style.backgroundColor = rowStyleHover[currentRowNum];
}
}
}

</script> <table class="t15standard" summary="Report">
The JavaScript was lifted from an APEX application that used a Generic Columns Report Template; as I mentioned before, this is hard-wired into that type of report template, but not into the Named Column Report Template; thus, we have to do it ourselves. The last line simple opens the table and assigns it a class, so that it matches the rest of the reports in our theme.

Finally, simply enter the following for After Headers to close the HTML table:
</table>
That should do it for the template. All that remains is to create your APEX application that contains a report on page 1 based on the ENAME, EMPNO & SAL columns of EMP and a form on page 2 based on the EMP table.

The resulting report should look something like this:

Clicking anywhere on the row would be the equivalent of clicking on an edit icon.

Comments

Carl Backstrom said…
Nice example.

One Pet Peeve you have onClick="....." in camel case and it should be onclick="" in all lowercase.


Carl
Anonymous said…
Hello Scott,

Nice, and interesting, to read from you again :)

I have a minor comment on your template code. It seems like some of the built-in substitution strings for the standard report templates, like #ALIGNMENT# or #COLUMN_HEADER# are not supported in the Named Column Report Template. You can see it in your own example, in which the SAL column is aligned to the left (and not to the right as it should be). We discussed this issue in the following - http://forums.oracle.com/forums/thread.jspa?forumID=137&threadID=513665 .

Best Regards,
Arie.
Scott said…
Interesting point, but it kinda does make sense...

I suppose if you're already hard-coding the column names, you can just go the extra mile and put in the attributes as well.

Thanks,

- Scott -
Anonymous said…
Scott,
What do you mean when you say
"you can just go the extra mile and put in the attributes as well".
Scott said…
I meant that since the named column report does not use the #ALIGNMENT# tag, that you can just add a class or style to handle the alignment of columns & column header.

Thanks,

- Scott -

Popular posts from this blog

Custom Export to CSV

It's been a while since I've updated my blog. I've been quite busy lately, and just have not had the time that I used to. We're expecting our 1st child in just a few short weeks now, so most of my free time has been spent learning Lamaze breathing, making the weekly run to Babies R Us, and relocating my office from the larger room upstairs to the smaller one downstairs - which I do happen to like MUCH more than I had anticipated. I have everything I need within a short walk - a bathroom, beer fridge, and 52" HD TV. I only need to go upstairs to eat and sleep now, but alas, this will all change soon... Recently, I was asked if you could change the way Export to CSV in ApEx works. The short answer is, of course, no. But it's not too difficult to "roll your own" CSV export procedure. Why would you want to do this? Well, the customer's requirement was to manipulate some data when the Export link was clicked, and then export it to CSV in a forma

Refreshing PL/SQL Regions in APEX

If you've been using APEX long enough, you've probably used a PL/SQL Region to render some sort of HTML that the APEX built-in components simply can't handle. Perhaps a complex chart or region that has a lot of custom content and/or layout. While best practices may be to use an APEX component, or if not, build a plugin, we all know that sometimes reality doesn't give us that kind of time or flexibility. While the PL/SQL Region is quite powerful, it still lacks a key feature: the ability to be refreshed by a Dynamic Action. This is true even in APEX 5. Fortunately, there's a simple workaround that only requires a small change to your code: change your procedure to a function and call it from a Classic Report region. In changing your procedure to a function, you'll likely only need to make one type of change: converting and htp.prn calls to instead populate and return a variable at the end of the function. Most, if not all of the rest of the code can rem

Logging APEX Report Downloads

A customer recently asked how APEX could track who clicked “download” from an Interactive Grid.  After some quick searching of the logs, I realized that APEX simply does not record this type of activity, aside from a simple page view type of “AJAX” entry.  This was not specific enough, and of course, led to the next question - can we prevent users from downloading data from a grid entirely? I knew that any Javascript-based solution would fall short of their security requirements, since it is trivial to reconstruct the URL pattern required to initiate a download, even if the Javascript had removed the option from the menu.  Thus, I had to consider a PL/SQL-based approach - one that could not be bypassed by a malicious end user. To solve this problem, I turned to APEX’s Initialization PL/SQL Code parameter.  Any PL/SQL code entered in this region will be executed before any other APEX-related process.  Thus, it is literally the first place that a developer can interact with an APEX p