Thursday, September 06, 2007

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.

5 comments:

Carl Backstrom said...

Nice example.

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


Carl

Arie 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 -