Resizeable table columns in HTML
How would I go about making the table columns resizeable?
In all my googling I've found nothing that mentions how to allow one to resize columns in a table (just like one would do in Excel, or other spreadsheet programs) after the table has been drawn. Any help would be greatly appreciated.
In all my googling I've found nothing that mentions how to allow one to resize columns in a table (just like one would do in Excel, or other spreadsheet programs) after the table has been drawn. Any help would be greatly appreciated.
0
Comments
As for resizeable columns having varied meanings . . . maybe these screenshots will illustrate what I'm saying.
These are from Excel. The first image is just Excel with some cells filled in. The second is my resizing Column 1 . . . just like I'd like to be able to do with an HTML table column.
To do it "on the fly.. ala Excel".. it's hunt for javascript/DHTML.
[php]width="*"[/php]
can be used for a Center column in a three column layout or a right column in a two column table define. Set up the other column or columns as absolutes, preferably percentages to allow for browser dynamic resizing. Grab the source of http://www.johndanielsonii.com/pctriage/pctriage_tmplt.html, or download it for a way to run dynamically variable table widths at a browser that any browser can resize as user changes width of browser Window. Left column is percentage defined, right column is free-form width with * as width parm.
If you need both fixed and relative sizing, try a frameset explicitily defined for vertical frame areas, and not defined horizontally, with html content defined same way for containing in the frameset. I technically did not need all the table feeds in my example template, except that hr tags are best used external to tables according to Tidy.
For a table that goes from a forum, I do NOT define widths at all, I let the forum feed code do that here. Look at my "GOOD News for Team Short-Media thread, and grab the source view of a message. I used SPAN instead of widths for title row, defined overall table width as a percentage, let browsers pick how they set width themselves. tr is ROW, put multiple cells in td pairs inside each tr for multiple cell width tables, let the dang browser calc cells from overall table width. This works if you feed font defs minus any sizing of font, let the browser choose size itself.
Another way, is to feed a .pdf file, which can be created from OOo.org as printer virtual driver output. Corel Draw 11 and up can also output .pdf files. Linux can natively create pdf compatible files also. So, alternative, if you are not looking for a dynamicly updated and embedded Excel feed, is to make a .pdf and feed that.
John D.
I appreciate the help, but I believe you have misunderstood my question. Having the browser decide the width of the columns is fine, but I also want the functionality of allowing the user to resize columns as can be done in Excel.
I've already got it partially working, but I've run into a couple of snags:
1. If the data in a cell that's being resized is very long, the contents of that cell "bleed" over past the limits of the column and into the next cell (looks bad).
2. The columns will not allow me to adjust the width any less than 320px (in Mozilla. work-arounds for IE haven't been implemented so it doesn't work).
I'm pretty sure I can get it to work; it's just a matter of how closely will Excel's behavior be mimicked.
Notice the "From" column. That is as small in width as I can get it, so there's something wrong there in my opinion--it should shrink more. Also, notice the next to last cell in the same column; see how the text bleeds over into the cell in the next column?
(Notice all the spam?
<style type="text/css"> .mouseOver { background-color: lightgrey; color: blue; font: bold 12px helvetica, tahoma, verdana, geneva, lucida, 'lucida grande', arial, sans-serif; } .mouseOut { background-color: beige; color: black; font: bold 12px helvetica, tahoma, verdana, geneva, lucida, 'lucida grande', arial, sans-serif; } tr { white-space: normal; } th { white-space: normal; } td { white-space: normal; } div { width: 98%; } </style> <script language="javascript" type="text/javascript"> var _startPosition = 0; var _diffPosition = 0; var _allowMove = false; var _resizerColumn = null; var _firstColumn = null; var _secondColumn = null; var _resizerColumnLeft = 0; var _resizerColumnWidth = 0; var _firstColumnLeft = 0; var _firstColumnWidth = 0; var _secondColumnLeft = 0; var _secondColumnWidth = 0; var _systemEvent = null; if (navigator.appName == 'Netscape') { document.captureEvents(Event.MOUSEMOVE | Event.MOUSEUP | Event.ONLOAD); } document.onmouseup = disableMouseMovement; document.onmousemove = setNewPosition; function setPosition() { // Called for OnMouseDown event // if (navigator.appName == 'Netscape') { // _startPosition = _systemEvent.clientX + _diffPosition; // } else { // _startPosition = _systemEvent.clientX + _diffPosition; // } _startPosition = _systemEvent.clientX; _allowMove = true; _resizerColumnLeft = findPosX(_resizerColumn); _resizerColumnWidth = _resizerColumn.style.width; _firstColumnLeft = findPosX(_firstColumn); _firstColumnWidth = _firstColumn.style.width; _secondColumnLeft = findPosX(_secondColumn); _secondColumnWidth = _secondColumn.style.width; window.status = "Starting position: " + _startPosition + " :: RCL " + _resizerColumnLeft + " :: FCL " + _firstColumnLeft + " :: SCL " + _secondColumnLeft + " :: RCW " + _resizerColumnWidth + " :: FCW " + _firstColumnWidth + " :: SCW " + _secondColumnWidth; return true; } function setResizeColumns(resizerColumn, firstColumn, secondColumn) { // Called for OnMouseOver event // resizerColumn is the actual object of the column that will be moved so that // firstColumn and secondColumn can be resized. // firstColumn will have its dimensions either grown or shrunk. // secondColumn will have the exact opposite done to it that firstColumn has. // If firstColumn is shrink by 60px, secondColumn is grown by 60px, the opposite also holds true. if (_allowMove == false) { _resizerColumn = resizerColumn; _firstColumn = firstColumn; _secondColumn = secondColumn; } window.status = "setResizeColumns() " + _resizerColumn.id + " :: " + _firstColumn.id + " :: " + _secondColumn.id; return true; } function disableMouseMovement(e) { // Called for OnMouseUp event window.status = "disableMovement() " + _resizerColumn.id + " :: " + _firstColumn.id + " :: " + _secondColumn.id; _allowMove = false; return false; } function setNewPosition(e) { // Called for OnMouseMove event // BEGIN_HACK so that setPosition() can work. if (navigator.appName == 'Netscape') { _systemEvent = e; } else { _systemEvent = event; } // END_HACK newPosition = _systemEvent.clientX; if (_allowMove) { _diffPosition = _startPosition - newPosition; document.testform.test4.value = newPosition; document.testform.test1.value = _diffPosition; document.testform.test2.value = _firstColumn.style.width; document.testform.test3.value = _secondColumn.style.width; // if (_diffPosition <= 200 && _diffPosition >= -600) { // _firstColumn.style.width = 200 - _diffPosition + "px"; // //_resizerColumn.style.width = "5px"; // _secondColumn.style.width = 600 + _diffPosition + "px"; // } else if (_diffPosition >= 200) { // _firstColumn.style.width = 200; // //_resizerColumn.style.width = 5; // _secondColumn.style.width = 600; // } else if (_diffPosition <= -600) { // _firstColumn.style.width = 600; // //_resizerColumn.style.width = 5; // _secondColumn.style.width = 200; // } // if ((_firstColumn.style.width - _diffPosition) < 50) return; // if ((_secondColumn.style.width + _diffPosition) > 450) return; // if ((_firstColumn.style.width + _diffPosition) > 450) return; // if ((_secondColumn.style.width - _diffPosition) < 50) return; var tpos1 = (parseInt(_firstColumnWidth) - parseInt(_diffPosition)) + "px"; var tpos2 = (parseInt(_secondColumnWidth) + parseInt(_diffPosition)) + "px"; _firstColumn.style.width = tpos1; _secondColumn.style.width = tpos2; window.status = " FCW Old: " + _firstColumnWidth + " FCW New: " + _firstColumn.style.width + " SCW Old: " + _secondColumnWidth + " SCW New: " + _secondColumn.style.width + " Start P: " + _startPosition + " SP - DP: " + tpos1 + " SP + DP: " + tpos2; } return true; } function findPosX(obj) { var curleft = 0; if (obj.offsetParent) { while (obj.offsetParent) { curleft += obj.offsetLeft obj = obj.offsetParent; } } else if (obj.x) curleft += obj.x; return curleft; } function findPosY(obj) { var curtop = 0; if (obj.offsetParent) { while (obj.offsetParent) { curtop += obj.offsetTop obj = obj.offsetParent; } } else if (obj.y) curtop += obj.y; return curtop; } </script> </head> <body> <table id="tblList" style="table-layout: fixed; width: 750px; left: 5; top: 5;"> <thead id="tblHead"> <tr> <th id="tblSelect" style="width: 75px;" class="mouseOut" onmouseout="className='mouseOut';" onmouseover="className='mouseOver';">Select <input type="checkbox"></th> <th id="tblSelectResize" style="width: 2px; background-color: lightgrey;" onmouseover="style.cursor='e-resize';setResizeColumns(this, document.getElementById('tblSelect'), document.getElementById('tblFrom'));" onmousedown="setPosition();"></th> <th id="tblFrom" style="width: 200px;"><input name="btnFrom" type="button" value="From" onClick="sortColumns(2);" onMouseOver="className='mouseOver';" onMouseOut="className='mouseOut';" class="mouseOut" style="width: 100%;"></th> <th id="tblFromResize" style="width: 2px; background-color: lightgrey;" onmouseover="style.cursor='e-resize';setResizeColumns(this, document.getElementById('tblFrom'), document.getElementById('tblDate'));" onmousedown="setPosition();"></th> <th id="tblDate" style="width: 200px;"><input name="btnDate" type="button" value="Date" onClick="sortColumns(3);" onMouseOver="className='mouseOver';" onMouseOut="className='mouseOut';" class="mouseOut" style="width: 100%;"></th> <th id="tblDateResize" style="width: 2px; background-color: lightgrey;" onmouseover="style.cursor='e-resize';setResizeColumns(this, document.getElementById('tblDate'), document.getElementById('tblSubject'));" onmousedown="setPosition();"></th> <th id="tblSubject" style="width: 200px;"><input name="btnSubject" type="button" value="Subject" onClick="sortColumns(4);" onMouseOver="className='mouseOver';" onMouseOut="className='mouseOut';" class="mouseOut" style="width: 100%;"></th> </tr> <tbody id="tblBody"> <tr class="mouseOut" onmouseout="className='mouseOut';" onmouseover="className='mouseOver';"> <td style="text-align: center;"><input type="checkbox"></td> <td id="tblmiddle1" style="width: 2px; background-color: beige;" rowspan=5></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">Pet Supplies <eSlam@28.moosq.com></div></div></td> <td id="tblmiddle2" style="width: 2px; background-color: beige;" rowspan=5></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">Thu, 25 Mar 2004 17:26:09 -0800 (PST)</div></div></td> <td id="tblmiddle3" style="width: 2px; background-color: beige;" rowspan=5></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">Coupon for pet needs. Order online.</div></div></td> </tr> <tr class="mouseOut" onmouseout="className='mouseOut';" onmouseover="className='mouseOver';"> <td style="text-align: center;"><input type="checkbox"></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">TGT Survey <aaaaa@gegm14.com></div></div></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">Thu, 25 Mar 2004 20:11:40 EST</div></div></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">Win a Dell Computer with a flat panel or $1000.00 Cash</div></div></td> </tr> <tr class="mouseOut" onmouseout="className='mouseOut';" onmouseover="className='mouseOver';"> <td style="text-align: center;"><input type="checkbox"></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">"Avery Colon" <AITWMZLVKYGTYV@msn.com></div></div></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">Fri, 26 Mar 2004 01:50:03 +0300</div></div></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">cc: get rid of all those pimples</div></div></td> </tr> <tr class="mouseOut" onmouseout="className='mouseOut';" onmouseover="className='mouseOver';"> <td style="text-align: center;"><input type="checkbox"></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">Johnnie Walker <qomzrmaaaztappn@rlegmennng.interactivemarketingcorporation.com></div></div></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">Thu, 25 Mar 2004 19:47:04 -0600 (CST)</div></div></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">Correction: San Francisco: Johnnie Walker Private Event</div></div></td> </tr> <tr class="mouseOut" onmouseout="className='mouseOut';" onmouseover="className='mouseOver';"> <td style="text-align: center;"><input type="checkbox"></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">Success Kit <SweetOffers@44.moosq.com></div></div></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">Thu, 25 Mar 2004 09:53:40 -0800 (PST)</div></div></td> <td style="overflow: hidden;"><div id="junk" style="overflow: hidden;"><div style="white-space: nowrap;">Dave did it, so can you</div></div></td> </tr> </tbody> </table> <form name=testform> newPosition: <input type=text name=test4><br> diffPosition: <input type=text name=test1><br> firstColumn: <input type=text name=test2><br> secondColumn: <input type=text name=test3> </form> <input name="btnChange" type="button" value="Coords" onClick="showCoords();">// Edit: I don't want to take full responsibility for this code. I found the major portion of the implementation on another site. Functionality has been augmented to allow for more than two columns, though, and a few other tweaks here and there. I don't recall the site off-hand, but if I can find it again I'll post a link here.
Here's the link: resizing tables
Here's who is given credit for authoring it: skiboy825
BTW, IE prefers a server gened refeed of this kind of thing, a refresh\reload event followed by new resized table feed. Mozzie can handle the dynamics with Java 2 support very nicely. IE actions are based on J++script, not Javascript of completely Sun kind, and recalcs things too much.
For reasons of being sued by Sun (and having the embarrassment of Sun winning), Microsoft is having to remove Sun stuff from "J++Script" and the Windows Scripting Host and Windows per se-- they declined to pay Sun for code use on a continuing basis, DID pay damages for refusing to pay those fees earlier. So, they came up with .NET and aspx, which relies on server-side stuff more and more-- like reload events and refeeds instead of dynamic in-window recalcing of position. STATIC Opera will work more like IE than Mozzie, also (Static opera is SANS Java 2-- yes, there are TWO Opera subforks).
John D.
I suppose I COULD grab the source, stick it in Quanta Gold 3.6+, and view it or take it and save it and view it here, BUT....
John D.
Unfortunately this forum wont allow the header style sheets, so the divs dont break down inside here like they should, look at the attachment ..
<html> <head> <style> <!-- .0 {cursor:"e-resize";} .1 {text-overflow: clip; overflow: hidden;} //--> </style> <script language="JavaScript"> var minwidth = 10; function dragResize(dragEvent,pageobj) { if (navigator.appName == "Microsoft Internet Explorer"){mX = event.clientX;} else {mX = e.pageX;} newWidth = dragEvent.x; if(newWidth<minwidth)newWidth=minwidth; CellData = document.getElementsByName(pageobj); for(var i = 0; i < CellData.length; i++) {CellData[i].style.width = newWidth;} } </script> </head> <body> <table border=1> <tr> <td><img class="0" height="20" src="1.gif" onDrag="dragResize(event,this.name);" name="A"></td> <td><img class="0" height="20" src="1.gif" onDrag="dragResize(event,this.name);" name="B"></td> <td><img class="0" height="20" src="1.gif" onDrag="dragResize(event,this.name);" name="C"></td> </tr> <tr> <TD><div class="1" id="A">blah1</div></td> <td><div class="1" id="B">blah2</div></td> <td><div class="1" id="C">blah3</div></td> </tr> <tr> <TD><div class="1" id="A">blah1</div></td> <td><div class="1" id="B">blah2</div></td> <td><div class="1" id="C">blah3</div></td> </tr> <tr> <TD><div class="1" id="A">blah1</div></td> <td><div class="1" id="B">blah2</div></td> <td><div class="1" id="C">blah3</div></td> </tr> </table> </body> </html>I'll take a look and see what all you did.
( sorry i dont know netscape very well, perhaps someone could add browser detection/differences into the code and re-post )
As mentioned before, the CSS classes wont work in the forum, so the text wont collapse in here as it will in the attachment. -- DreX
<html> <head> <style> <!-- .0 {cursor:"e-resize";} .1 {text-overflow: clip; overflow: hidden;} // --> </style> <script language="JavaScript"> <!-- var minwidth = 10; var startX; var originalWidth; function resizeCol(pageobj) { newWidth = event.clientX - startX + originalWidth; if(newWidth<minwidth) {newWidth=minwidth;} CellData = document.getElementsByName(pageobj); for(var i = 0; i < CellData.length; i++) {CellData[i].style.width = newWidth;} } function startpos(pageobj) { startX = event.clientX; originalWidth = document.getElementById(pageobj).width; } //--> </script> </head> <body> <table border=1> <tr> <td><img height="20" width="10" src="/images/blank.gif" id="1"><!-- the Image to the right is to drag, the one to the left is to size --><img class="0" src="/images/divider.jpg" ondrag="resizeCol(1);" onmousedown="startpos(1);"></td> <td><img height="20" width="10" src="/images/blank.gif" id="2"><img class="0" src="/images/divider.jpg" ondrag="resizeCol(2);" onmousedown="startpos(2);"></td> <td><img height="20" width="10" src="/images/blank.gif" id="3"><img class="0" src="/images/divider.jpg" ondrag="resizeCol(3);" onmousedown="startpos(3);"></td> </tr> <tr> <TD><div class="1" id="1">blah1</div></td> <td><div class="1" id="2">blah2</div></td> <td><div class="1" id="3">blah3</div></td> </tr> <tr> <TD><div class="1" id="1">blah1</div></td> <td><div class="1" id="2">blah2</div></td> <td><div class="1" id="3">blah3</div></td> </tr> <tr> <TD><div class="1" id="1">blah1</div></td> <td><div class="1" id="2">blah2</div></td> <td><div class="1" id="3">blah3</div></td> </tr> </table> </body> </html>As far as not being seen in IE or Mozilla. I loaded it into Firefox just now and it works as well as it did two years ago. Unfortunately I had not done a great deal of work on it since then so the most recent version I have isn't much better. I have a few more projects to complete before I can get back to that, and who knows, by the time I get back to it I might find an already working version I can use. Seems like I had seen something in Bindows that worked like I had wanted, but I can't be certain.
The scripts described on the link below work with both IE and Mozilla/FireFox etc
http://methvin.com/jquery/splitter/default.html