View Full Version : Scrolling to Nth row in a table
jason_kelly
06-28-2012, 02:49 PM
Hi All,
Thanks to the wonderful and dedicated work of jscheuer1, I was able to implement the click, arrow keys and a seperate go to row function for the coding below. Although this works great and does what it should, how can I move the scroll position of the div to the Nth selected row in a table? It seems that if I execute the goto function, by clicking on the "Go" button it does not scroll and move to the selected position?
I'm thinking it would be best to integrate into the ChangeColor function
I had to use a paste bucket because the file was so large:http://www.pastebucket.com/2485
Thank you all for your help and support in advance.
Cheers,
Jay
jscheuer1
06-28-2012, 03:43 PM
Additions, changes highlighted:
var currow;
var color = "#E1E0D7"
var mstr = document.getElementById("mstrTable");
var rows = mstr.getElementsByTagName("tr");
var n = rows.length;
var bgcs = [];
for(var i=0; i<n; ++i) bgcs[i] = rows[i].style.backgroundColor;
function changeColor(e) {
if(!e) e = window.event;
var o = e.target? e.target: e.srcElement;
while(o.tagName && o.tagName.toLowerCase()!="tr") o = o.parentNode;
for(var i=0; i<n; ++i) {
rows[i].style.backgroundColor = bgcs[i];
if(rows[i]==o) {
currow = i;
rows[i].style.backgroundColor = color;
mstr.focus();
mstr.parentNode.scrollTop = rows[i].offsetTop - rows[0].offsetHeight;
}//end of if
}//end of for
}//end of function
window.gotoRow = function(num){
changeColor({target: rows[num], type: 'click'});
};
if(document.addEventListener && (window.opera || !window.attachEvent)){
for(var i=0; i<n; ++i) rows[i].addEventListener("click", changeColor, false);
document.addEventListener('keydown', function(e){
if(e.keyCode == 38){if(currow > 1)changeColor({target: rows[--currow]});e.preventDefault();}
if(e.keyCode == 40){if(currow < n - 1)changeColor({target: rows[++currow]});e.preventDefault();}
}, false);
}
else {
for(var i=0; i<n; ++i) rows[i].attachEvent("onclick", changeColor);
document.getElementById('mstrTable').attachEvent('onkeydown', function(){
if(event.keyCode == 38){if(currow > 1)changeColor({target: rows[--currow]});event.returnValue = false;}
if(event.keyCode == 40){if(currow < n - 1)changeColor({target: rows[++currow]});event.returnValue = false;}
});
}
}//end of onload
jason_kelly
06-28-2012, 04:19 PM
Works like a charm.
Thanks so much!
Cheers,
jscheuer1
06-28-2012, 07:46 PM
Glad you like it. I started to think though that things were jumping around more than required, so I came up with this variation:
function changeColor(e) {
if(!e) e = window.event;
var o = e.target? e.target: e.srcElement;
while(o.tagName && o.tagName.toLowerCase()!="tr") o = o.parentNode;
for(var i=0; i<n; ++i) {
rows[i].style.backgroundColor = bgcs[i];
if(rows[i]==o) {
currow = i;
rows[i].style.backgroundColor = color;
mstr.focus();
if(mstr.parentNode.scrollTop + mstr.parentNode.offsetHeight - rows[0].offsetHeight < rows[i].offsetTop + rows[i].offsetHeight ||
rows[i].offsetTop < mstr.parentNode.scrollTop + rows[0].offsetHeight)
mstr.parentNode.scrollTop = rows[i].offsetTop - rows[0].offsetHeight;
}//end of if
}//end of for
}//end of function
It test to make sure the row isn't already fully viewable before shifting.
jason_kelly
07-03-2012, 05:31 PM
Thanks again for your awesomely amazing help John.
Is there a way to make the scroll position in the middle, as opposed to the top?
This level of coding, is being my capable head.
All the thanks and appreciation for your help.
Cheers
Jay
jscheuer1
07-04-2012, 02:50 AM
Change:
mstr.parentNode.scrollTop = rows[i].offsetTop - rows[0].offsetHeight;
to:
mstr.parentNode.scrollTop = rows[i].offsetTop - mstr.parentNode.offsetHeight / 2;
Just remember, if the row is already in full view, there will be no change in the scroll state. And that, if there aren't enough rows either above or below the selected row, it cannot be scrolled to the middle.
jason_kelly
07-04-2012, 05:08 PM
Worked like a charm John!!!!
Thanks so much again for the marvelous help
You truly are a genious.
Cheers and have an awesome day!
Jay
jason_kelly
07-21-2012, 12:09 AM
Hi John,
I need your help again with this one again.
I am wanting to move away from the Window.Onload method of loading my table and transfering functionality to a seperate function after my table is seperatly compiled. (Which is what I should have done in the first place, now everything is a mess).
I am having a heck of time trying to seperate them.
How could I have one function after the table is created that would still keep my click and arrow scrolling as opposed to just loading every on window.onload?
/*window.onload = function() {
...a whole lot of HTML for tables.
/create the table..this part is ok =)
*/
document.getElementById("p1").innerHTML = html
var currow;
var color = "#E1E0D7"
var mstr = document.getElementById("mstrTable");
var rows = mstr.getElementsByTagName("tr");
var n = rows.length;
var bgcs = [];
for(var i=0; i<n; ++i) bgcs[i] = rows[i].style.backgroundColor;
function changeColor(e) {
if(!e) e = window.event;
var o = e.target? e.target: e.srcElement;
while(o.tagName && o.tagName.toLowerCase()!="tr") o = o.parentNode;
for(var i=0; i<n; ++i) {
rows[i].style.backgroundColor = bgcs[i];
if(rows[i]==o) {
currow = i;
rows[i].style.backgroundColor = color;
mstr.focus();
mstr.parentNode.scrollTop = rows[i].offsetTop - rows[0].offsetHeight;
}//end of if
}//end of for
}//end of function
window.gotoRow = function(num){
changeColor({target: rows[num], type: 'click'});
};
if(document.addEventListener && (window.opera || !window.attachEvent)){
for(var i=0; i<n; ++i) rows[i].addEventListener("click", changeColor, false);
document.addEventListener('keydown', function(e){
if(e.keyCode == 38){if(currow > 1)changeColor({target: rows[--currow]});e.preventDefault();}
if(e.keyCode == 40){if(currow < n - 1)changeColor({target: rows[++currow]});e.preventDefault();}
}, false);
}
else {
for(var i=0; i<n; ++i) rows[i].attachEvent("onclick", changeColor);
document.getElementById('mstrTable').attachEvent('onkeydown', function(){
if(event.keyCode == 38){if(currow > 1)changeColor({target: rows[--currow]});event.returnValue = false;}
if(event.keyCode == 40){if(currow < n - 1)changeColor({target: rows[++currow]});event.returnValue = false;}
});
}
}//end of onload
- Frustrated.
Thanks so much for all your help,
Jason
jscheuer1
07-21-2012, 05:09 AM
I'm not really clear on what you're saying here. I agree that there's a lot to be desired visa vis how all of this is being done. All that code to make a table is unnecessary, loops can condense it a lot. There's really no need for an onload event. The reason to use that is to make sure the page is ready before adding the table and events. It's ready before onload though. It's ready as soon as the HTML is parsed by the browser. We can separate things out quite a bit. But to what end? Organization and/or modularity are the only two possibilities that come to mind. Here I've gone for organization. Modularity brings with it global exposure, which always risks conflicts with other scripts that might be on a given page that's using this code. We've already globally exposed the gotoRow function. We can take that back. Still not ideal, but much improved by my way of looking at things:
<html>
<head>
<meta http-equiv="Content-Language" content="en-ca">
<title>Scrolling Data Grid</title>
<style>
/* ==================================================================== */
/* SCROLLING DATA GRID */
/* ==================================================================== */
DIV.scrollingdatagrid {
overflow-x:auto;
overflow-y:auto;
position:relative;
padding:0px;
}
DIV.scrollingdatagrid TABLE {
width : 98.7%; /* Make room for scroll bar! */
margin:0px;
border:0px;
border-collapse:separate;
}
DIV.scrollingdatagrid TABLE TR .locked, DIV.scrollingdatagrid TABLE THEAD TR, DIV.scrollingdatagrid TABLE TFOOT TR {
position:relative;
}
/* OffsetParent of the TR is the DIV because it is position:relative */
DIV.scrollingdatagrid TABLE THEAD TR {
top:expression(this.offsetParent.scrollTop);
}
/* Make the z-index values very clear so overlaps happen as expected! */
DIV.scrollingdatagrid TD, DIV.scrollingdatagrid TH { z-index:1; }
DIV.scrollingdatagrid TD.locked, DIV.scrollingdatagrid TH.locked { z-index:2; }
DIV.scrollingdatagrid THEAD TR, DIV.scrollingdatagrid TFOOT TR { z-index:3; }
DIV.scrollingdatagrid THEAD TR TH.locked { z-index:4; }
#mstrTable {table-layout: fixed; font-family: arial; font-size: 9pt; border-spacing: 0;}
#mstrTable th, #mstrTable td {margin: 0; padding: 0; color: rgb(102,102,102);}
#mstrTable th {border: 1px solid #fff; border-bottom-color: rgb(128,128,128); border-right-color: rgb(128,128,128); padding-left: 5px; width: 110px; background-color: rgb(212,208,200);}
#mstrTable th.locked {text-align: center; height: 30px; width: 20px; padding: 0;}
#mstrTable .lastcolumn {border-right-width: 0;}
#mstrTable td {border: 1px solid rgb(128,128,128); border-top-width: 0; border-left-width: 0; padding-left: 5px; white-space: nowrap; overflow: hidden;}
#mstrTable td.locked {height: 20px; text-align: center; padding: 0;}
</style>
</head>
<body>
<p> </p>
<div id="p1" class="scrollingdatagrid" style="width:850px;height:200px;border:1px solid rgb(128,128,128);"></div>
<br>
<table border="0" cellpadding="0" cellspacing="0" width="109">
<tr>
<td>
<table style="border:1px solid #808080;" cellpadding="0" cellspacing="0" width="73">
<tr>
<td style="font-family: arial; font-size: 9pt; border-right:1px solid #808080; color: #666666; background-color: #D4D0C8; text-align: center; height: 18px; width:34px">
Go to</td>
<td style="width: 36px;">
<input style="padding-left: 4px; font-family: arial; font-size: 9pt; width: 35px; height: 15px; border: none" type="text" name="row" id="row" maxlength="4"></td>
</tr>
</table>
</td>
<td width="29">
<input
style="color: #666666; height: 20px; font-family: arial; font-size: 9pt; border:1px solid #808080;"
type="button" value="Go" id="go"
></td>
</tr>
</table>
<script type="text/javascript">
(function(){
var color = "#E1E0D7", currow, mstr, rows, n, bgcs = [], row, i;
function createTable() {
var numRows = 13, numCols = 16, i = 0, j, html = ''
html += '<table id="mstrTable" cellpadding="0" cellspacing="0">\n'
html += '<thead>\n'
html += '<tr>\n'
html += '<th class="locked">#</th>\n';
while(++i < numCols){
html += '<th> COLUMN' + i + '</th>\n';
}
html += '<th class="lastcolumn""> COLUMN' + i + '</th>\n';
html += '</tr>\n'
html += '</thead>\n'
html += '<tbody>\n'
i = 0;
while(++i < numRows + 1){
html += '<tr>\n';
html += '<td class="locked">' + i +'.</td>\n';
j = 0;
while(++j < numCols){
html += '<td>DATA</td>\n';
}
html += '<td class="lastcolumn">DATA</td>\n';
html += '</tr>\n';
}
html += '</tbody>\n';
html += '</table>\n';
return html;
}
function changeColor(e) {
e = e || event;
var o = e.target || e.srcElement, i = -1;
while(o.tagName && o.tagName.toLowerCase()!="tr") {o = o.parentNode;}
while((row = rows[++i])) {
row.style.backgroundColor = bgcs[i];
if(row==o) {
currow = i;
row.style.backgroundColor = color;
if(mstr.parentNode.scrollTop + mstr.parentNode.offsetHeight - rows[0].offsetHeight < row.offsetTop + row.offsetHeight ||
row.offsetTop < mstr.parentNode.scrollTop + rows[0].offsetHeight){
mstr.parentNode.scrollTop = row.offsetTop - mstr.parentNode.offsetHeight / 2;
}
}//end of if
}//end of for
}//end of function
function gotoRow(num){
mstr.focus();
changeColor({target: rows[num]});
};
i = -1;
document.getElementById("p1").innerHTML = createTable();
mstr = document.getElementById("mstrTable");
rows = mstr.getElementsByTagName("tr");
n = rows.length;
while((row = rows[++i])){bgcs[i] = row.style.backgroundColor;}
if(document.addEventListener && (window.opera || !window.attachEvent)){
for(var i=0; i<n; ++i) rows[i].addEventListener("click", changeColor, false);
document.addEventListener('keydown', function(e){
if(e.keyCode == 38){if(currow > 1)changeColor({target: rows[--currow]});e.preventDefault();}
if(e.keyCode == 40){if(currow < n - 1)changeColor({target: rows[++currow]});e.preventDefault();}
}, false);
document.getElementById('go').addEventListener('click', function(){gotoRow(document.getElementById('row').value);}, false);
}
else {
for(var i=0; i<n; ++i) rows[i].attachEvent("onclick", changeColor);
document.getElementById('mstrTable').attachEvent('onkeydown', function(){
if(event.keyCode == 38){if(currow > 1)changeColor({target: rows[--currow]});event.returnValue = false;}
if(event.keyCode == 40){if(currow < n - 1)changeColor({target: rows[++currow]});event.returnValue = false;}
});
document.getElementById('go').attachEvent('onclick', function(){gotoRow(document.getElementById('row').value);});
}
})();
</script>
</body>
</html>
mannagod
08-23-2012, 05:42 PM
Hi John. Could you please help me. I have a table that dynamically highlights a row based on javascript that locates that row based on today's date. I would like to also be able to scroll to that row dynamically. Could you possibly help me do this? The page is http://www.itsmyturnnow.com/HWC/BRP/08.htm. Thanks John.
bernie1227
08-23-2012, 08:37 PM
This (http://stackoverflow.com/questions/10628701/javascript-change-table-row-class-based-on-date) link here may help you for highlighting the date.
keyboard
08-23-2012, 11:33 PM
Warning: If you have a new question, start a new thread!
Powered by vBulletin® Version 4.2.2 Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.