Wednesday 2 February 2011

selectRow with JQeuryUI interface and JSP

This is a select row example with JQuery and JSP.

JQueryUI interface is used.


...
...
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
oTable = $('#myTable').dataTable({
"bJQueryUI": true,
"sPaginationType": "full_numbers"
} );
} );
</script>
...
...
The table is populated with JSP using an array.
...
...
<%
String[] items = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"};
String item = items[0];
%>
...
...

and
...
...
<tbody>
<%
for (int i = 0, oddEv = 0;;) { //for all the elements of the data
%>
<tr>
<TD onclick='SelectRow(<%=(i + 1)%>)' id='cell_<%=i + 1%>,1'>
<%= i%></TD>
<TD onclick='SelectRow(<%=(i + 1)%>)' id='cell_<%=i + 1%>,2'>
<%= item.toString()%></TD>
</tr>
<%
i++;

try {
item = items[i];
} catch (java.lang.ArrayIndexOutOfBoundsException _e0) {
break;
}
} //for all the elements of the data
%>
</tbody>

...
...

The basic logic of selecting a row is:
onclick to a row the selectRow jscript function works. Its parameter carries the current row. It changes the BG color of that row and checks if there was a previously changed row. If yes, it takes the previous color of that row from a variable and restores it. Hence it sets the color of the new row to highlight and resets the previous row's color. The code of this previous version is this:
...
...
function SelectRow(newRow)
{
//oTable.fnDraw(true);
for(var j=1;j<3;++j) {
//alert('curRow='+currentRow+' newRow='+newRow)
var cell=document.getElementById('cell_'+newRow+','+j);
if (j==1) newRowCellStyleBG_1 = cell.style.backgroundColor;
if (j==2) newRowCellStyleBG_2 = cell.style.backgroundColor;
cell.style.backgroundColor='#A3D0F7';

var oSettings = oTable.fnSettings();
if((currentRow!=-1) &&
(currentRow >= oSettings._iDisplayStart) &&
(currentRow <= oSettings._iDisplayStart + oSettings._iDisplayLength))
{
var cell=document.getElementById('cell_'+currentRow+','+j);
if (j==1) cell.style.backgroundColor = curRowCellStyleBG_1;
if (j==2) cell.style.backgroundColor = curRowCellStyleBG_2;
}
}
currentRow=newRow;
curRowCellStyleBG_1 = newRowCellStyleBG_1;
curRowCellStyleBG_2 = newRowCellStyleBG_2;
}
</script>
...
...

The problem is: When you change pages with the JQueryUI interface, once you click
on a row on the new page you can not set the color of the row left on the previous page. But you have the row number ond color of the row on the previous page. So, what I did is: I kept these values in dedicated variables.

It worked BUT:The problem is; you may change 3 or more pages, so you need an array to keep track of the previously selected row number and the BGcolors. The solution is:

When you change pages it first shows the previously selected row as if you have been
working on that page and after you click a new row it sets its original row BG color.
Here is the final complete working code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="shortcut icon" type="image/ico" href="DataTables-1.7.5/media/images/favicon.ico" />

<title>DataTables example</title>
<style type="text/css" title="currentStyle">
@import "DataTables-1.7.5/media/css/demo_page.css";
@import "DataTables-1.7.5/media/css/demo_table_jui.css";
@import "DataTables-1.7.5/examples/examples_support/themes/smoothness/jquery-ui-1.8.4.custom.css";
</style>
<script type="text/javascript" language="javascript" src="DataTables-1.7.5/media/js/jquery.js"></script>
<script type="text/javascript" language="javascript" src="DataTables-1.7.5/media/js/jquery.dataTables.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
oTable = $('#myTable').dataTable({
"bJQueryUI": true,
"sPaginationType": "full_numbers"
} );
} );
</script>
<script type='text/javascript'>
var currentRow=-1;
var curPageRow= new Array(-1,-1,-1);
var curRowCellStyleBG = new Array();
var newRowCellStyleBG = new Array();
var curPageCellStyleBG = new Array();
var pageArray = new Array();
var curDisplayStart;
var newDisp = 0; var curDisp=0;

function SelectRow(newRow) {
var oSettings = oTable.fnSettings();
newDisp = oSettings._iDisplayStart / oSettings._iDisplayLength;
//alert('current page='+ curDisp)

for(var j=1;j<3;++j) {
//if (j==1) alert("newRow="+ newRow+" currentRow="+ currentRow+" curPageRow="+ curPageRow);
if ((currentRow!=-1) &&
((currentRow < oSettings._iDisplayStart) ||
(currentRow > oSettings._iDisplayStart + oSettings._iDisplayLength)) &&
j ==1) //a new page has been clicked
{
//alert('row out of page');
pageArray[curDisp] = curRowCellStyleBG.slice()
if (curPageRow[newDisp] != -1){ //the new page was visited previously
//alert('newPageRow='+curPageRow[newDisp]);
var x = currentRow; //currentRow from the last page
currentRow=curPageRow[newDisp]; //the last row accessed previously
curRowCellStyleBG = pageArray[newDisp].slice();
curPageRow[curDisp]=x; //the last row accessed on the last page is recorded
}
}
//alert('curRow='+currentRow+' newRow='+newRow)
var cell=document.getElementById('cell_'+newRow+','+j);
newRowCellStyleBG[j] = cell.style.backgroundColor;
cell.style.backgroundColor='#A3D0F7';

if((currentRow!=-1) &&
(currentRow >= oSettings._iDisplayStart) &&
(currentRow <= oSettings._iDisplayStart + oSettings._iDisplayLength))
{
var cell=document.getElementById('cell_'+currentRow+','+j);
cell.style.backgroundColor = curRowCellStyleBG[j];
}
else {
//if (j==1) alert('row at the prev page='+ currentRow);
curPageRow[curDisp]= currentRow; //save the row pos at the prev page
}
}
currentRow=newRow;
curDisp=newDisp;
//curRowCellStyleBG = [];
curRowCellStyleBG = newRowCellStyleBG.slice();
}
</script>
</head>
<body id="dt_example">
<%
String[] items = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m"};
String item = items[0];
%>
<div id="container">
<div class="full_width big">
<i>dinamic DataTable</i> with jQuery UI themes example
</div>
<div id="demo_jui">
<table cellpadding="0" cellspacing="0" border="0" class="display" id="myTable">
<thead>
<tr>
<th>First Column</th>
<th>Second Column</th>
</tr>
</thead>
<tbody>
<%
for (int i = 0, oddEv = 0;;) { //for all the elements of the data
%>
<tr>
<TD onclick='SelectRow(<%=(i + 1)%>)' id='cell_<%=i + 1%>,1'>
<%= i%></TD>
<TD onclick='SelectRow(<%=(i + 1)%>)' id='cell_<%=i + 1%>,2'>
<%= item.toString()%></TD>
</tr>
<%
i++;

try {
item = items[i];
} catch (java.lang.ArrayIndexOutOfBoundsException _e0) {
break;
}
} //for all the elements of the data
%>
</tbody>

</table>
</div>
</div>
</body>
</html>

A final word:
Although this has been a good exercise for me to understand JQuery working with JSP,
this could be done much simply. The basic solution could be: reset the BGcolors to
their original values whenever the selectRow is called and before the new row color
is set to highlight. This requires that YOU set the colors of the JQueryUI tbody
elements.

An other solution could be to chandle clicked paging buttons and first reset the
previous pages selected row and then continue. This can be done for the 'two button'
interface using: (table name + '_paginate)

...
...
//to handle next prev first last buttons (it does not handle paging buttons
//on the 'full_numbers' interface

$('#myTable_paginate').click( function() {
alert('paginate click handler');
} );
...
...

or
$('#myTable_paginate next').click( function() {
alert('paginate click handler');
} );

or
$(.next).click( function() {
alert('paginate click handler');
} );
I spent quite some time to find out the names for the paging buttons but could not find it yet. Any assistence would be warmly wellcome.

Once again the correct solution is: To find the colors or set the colors for the datatableUI and use them as in the first solution.