Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Scrolling to Nth row in a table

  1. #1
    Join Date
    Oct 2011
    Posts
    46
    Thanks
    6
    Thanked 0 Times in 0 Posts

    Default Scrolling to Nth row in a table

    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

  2. #2
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Additions, changes highlighted:

    Code:
    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
    Last edited by jscheuer1; 06-28-2012 at 04:19 PM. Reason: problem scrolling by arrow keys if not first thing on page
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  3. The Following User Says Thank You to jscheuer1 For This Useful Post:

    jason_kelly (07-04-2012)

  4. #3
    Join Date
    Oct 2011
    Posts
    46
    Thanks
    6
    Thanked 0 Times in 0 Posts

    Default

    Works like a charm.

    Thanks so much!

    Cheers,

  5. #4
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Glad you like it. I started to think though that things were jumping around more than required, so I came up with this variation:

    Code:
    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.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  6. The Following User Says Thank You to jscheuer1 For This Useful Post:

    jason_kelly (07-04-2012)

  7. #5
    Join Date
    Oct 2011
    Posts
    46
    Thanks
    6
    Thanked 0 Times in 0 Posts

    Default

    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

  8. #6
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Change:

    Code:
    mstr.parentNode.scrollTop = rows[i].offsetTop - rows[0].offsetHeight;
    to:

    Code:
    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.
    Last edited by jscheuer1; 07-05-2012 at 12:09 AM. Reason: English usage
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  9. The Following User Says Thank You to jscheuer1 For This Useful Post:

    jason_kelly (07-04-2012)

  10. #7
    Join Date
    Oct 2011
    Posts
    46
    Thanks
    6
    Thanked 0 Times in 0 Posts

    Default

    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

  11. #8
    Join Date
    Oct 2011
    Posts
    46
    Thanks
    6
    Thanked 0 Times in 0 Posts

    Default

    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?

    Code:
    /*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

  12. #9
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    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:

    Code:
    <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>&nbsp;</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>
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  13. #10
    Join Date
    Aug 2012
    Posts
    1
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Scrolling to highlighted table row

    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.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •