Click and drag to resize table columns

Subscribe to Click and drag to resize table columns 22 posts, 5 voices

Oscar's Friend Scriptwright

Hi,

There's some really neat javascript I found here:

http://bz.var.ru/comp/web/resizable.html

that allows the user to resize table columns by dragging the bar between the columns in the header. Someone with the appropriate skillz (not me I'm afraid) should be able to do something like this, so that it will work with any table on any page, and I guess with table rows as well. This could be useful for sites that insist on having a narrow column of text down the centre of the page, for instance, with ads and various other annoying stuff down the side, taking up all the room. There are probably other uses to. The ability to delete rows and columns would also be useful. I've not been able to find a script that does this already, but maybe I haven't looked hard enough.

Anyone up to it?

BTW: It's my first post here. Also, I just posted my first script, yay!: http://userscripts.org/scripts/show/26587

 
Mikado Scriptwright

You are supposed to grab resizable-tables.js they provide and use functions from it. What else do you want?

 
Oscar's Friend Scriptwright

Yes, I know. It still needs some modification, though. (It's meant for use in writing your own pages, not to be used with greasemonkey -- and my js is rather rusty, as I haven't really done any for well over 5 years.) Plus, I couldn't get it to work when I tried. I downloaded the whole page, script, css stuff, and it just wouldn't work for me. I know the js file was running, because I put an alert() at the beginning to test it out, but it just wouldn't resize at all. This was using a copy of the original (the original itself works fine).

EDIT: Just to make it clear what I tried. I went to the above page, and did "save page as" from the file menu. This then saves the html file, and creates a directory with the js and css files in it. Opening this in firefox, I can see the page, and the css file is working, but it won't resize. I suspected that it might not be finding the js file, so I put a simple alert('test'); at the beginning of the js file, and the alert worked when I refreshed the page, but it still won't resize. I just can't see why it won't work when making a duplicate of the page.

 
Oscar's Friend Scriptwright

OK, I think I figured out what was going wrong. I think an add-on for firefox was modifying the html page, and the saved out copy was broken. I temporarily disabled the plugin, and now it works. I'll have a play around with the script now I've got it working, and see what I can come up with.

 
Oscar's Friend Scriptwright

The source code I am working from can be found here:
http://bz.var.ru/comp/web/resizable-tables.js

I've got it in greasemonkey now. But I get the following error: "Component is not available", which comes from this line (about 200 lines down, just above where the ResizableColumns() function is declared):

dragColumns[i].firstChild.firstChild.onmousedown = this.startColumnDrag;

In order to get this far, I had to disable the code right near the bottom of the file for getting the script to run. And replaced it simply with a call to the ResizableColumns() function. But otherwise the script is as in the above link (don't want to post it as it's quite long). I'm trying it with a copy of the original html file above, but with the javacript part commented out.

Any ideas where to go next?

 
Osias Scriptwright

I don't know why "Component is not available", but something.onmousedown doesn't work inside greasemonkey, you must use addeventlistener

 
Oscar's Friend Scriptwright

Thanks for that. I'm not quite sure how to do that. I tried replacing:

dragColumns[i].firstChild.firstChild.onmousedown = this.startColumnDrag;

with:
dragColumns[i].firstChild.firstChild.addEventListener("onmousedown",this.startColumnDrag,false);

and it didn't throw up any error messages, but it also didn't work.

 
Osias Scriptwright

try

dragColumns[i].firstChild.firstChild.addEventListener(
"onmousedown",
function() { this.startColumnDrag()} ,
false);

 
Oscar's Friend Scriptwright

Hi. Thanks for that, but it doesn't seem to work either. Also, note that the problem doesn't appear to be the this.startColumnDrag() function. As replacing this with alert('something') doesn't work either. With:

dragColumns[i].firstChild.firstChild.addEventListener("onmousedown",alert('something');

the alert appears when the page loads, but not when I click on column dividers in the header. With:
dragColumns[i].firstChild.firstChild.addEventListener(
"onmousedown",
function() { alert('something')} ,
false); 

nothing happens at all. In both cases there are no error messages.

 
Osias Scriptwright

are you sure is firstChild.firstChild? can you add the event to dragColumns[i]? or any other element?

 
dob Scriptwright

It's not called "onmousedown", but "mousedown", same as not "onclick", but "click".

onsomething is just an html attribute.

 
Oscar's Friend Scriptwright

Osias, I tried that and it didn't work. dob, yes it is onmousedown, and it is html. [EDIT: OK, sorry, I guess this is wrong, I misunderstood.] Just above that line in the code it creates some html, then the above line is used to set the onmousedown parameter (or whatever you call it) part of the tag (presumably because the function is called with "this"). I should also add that the code works perfectly outside of greasemonkey.

Thanks for your help, but I think I'm going to have to leave it at that, as my js is not up to scratch, and I don't really have the time to figure it all out. I was hoping that it wouldn't be too difficult to adapt the above code -- but I guess it is more complicated than that.

I kind of liked the idea of being able to edit html documents on the fly (I mean click and dragging stuff), just to tidy away any annoyances. I use Stylish, but that's only really any good for altering pages you visit regularly. (There's another plugin for firefox called aardvark, which sort of lets you delete things -- but not resize them.) Since this is a requests forum, I guess I'll just have to repeat my request. Anyone feel it's worth while rewriting this script, and maybe building on it to maybe allow the user to click and drag things in general around the page, or delete them?

 
gollum Scriptwright

Dob told you what was wrong...there is no ON prefix in the DOM Level 2 W3C model "addEventListener" arguments.

addEventListener("mousedown", functionREF, useCapture)

 
Oscar's Friend Scriptwright

OK, thanks. You and dob are right -- sorry for the misunderstanding. But it still won't work. I changed the line to read:

dragColumns[i].firstChild.firstChild.addEventListener("mousedown",function() { this.startColumnDrag()},false);

Which gives me the error: "this.startColumnDrag is not a function." I presume this is because of the "this", and I don't know how to get around this.

As I said, I just don't know enough javascript to do this by myself -- which was why I posted this in the "ideas and requests" forum rather than the "script development" forum -- working on the principle that if someone who knows what they are doing thinks it's a good idea and worth doing, then they will. If not, then so be it. I really do appreciate all your help here, but I don't think there is anyway I am going to be able to hack someone else's 200+ line script to work in greasemonkey, without either dedicating a lot of time and effort to (re)learning javascript -- something I don't really have the time to do -- or wasting other peoples' valuable time here walking me through the code line by line. I've written a few short greasemonkey scripts, without too much difficulty, but this is just way beyond me at this moment in time.

 
Osias Scriptwright

Oscar, you don't need to give up now. You won't need to rewrite the other guy script, just change the events.

try that:
dragColumns[i].firstChild.firstChild.addEventListener("mousedown",this.startColumnDrag,false);

I think it'll work cause startColumnDrag is a function.

Also, read that: http://www.oreillynet.com/pub/a/network/2005/11...
it's a little long but it'll make you understand fully why you are struggling and why the struggle won't last much past the events part.

 
Oscar's Friend Scriptwright

Thanks, Osias. I tried that first, and it also doesn't work:

Error: [Exception... "Component is not available"  nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)"  location: "JS frame :: file:///home/oscarsfriend/.mozilla/firefox/kjsdfh7.default/extensions/%7Be4a8a97b-f2ed-450b-b12d-ee082ba24781%7D/components/greasemonkey.js :: anonymous :: line 511"  data: no]
Source File: file:///home/oscarsfriend/.mozilla/firefox/kjsdfh7.default/extensions/%7Be4a8a97b-f2ed-450b-b12d-ee082ba24781%7D/components/greasemonkey.js
Line: 511

Thanks for the link, I've added it to my reading list.

 
Osias Scriptwright

This is the kind of thing I'll have to check carefully. I also intend to use the script. The only problem is I'm leaving for vacations today, and I don't know if there (after monday) I'll have good internet conection. If so, I'll try to play with that.

Meanwhile, I suggest to use unsafeWindow experimentally, doing what GM 0.3 used to do: append a "script" tag with src=http://bz.var.ru/comp/web/resizable-tables.js

As you'll see in that text, that's not nice, cause the sites you're adding the script can detect. They, can, but most don't. Try to do that in sites you know aren't trying to spy on you, and you'll see if the script works, at least. Then we can incrementally doing it work "inside" greasemonkey.

 
gollum Scriptwright

Yeah should have also mentioned what you've already found out ... your rewrite hurdle is the out of scope "this" in your function call
dragColumns[i].firstChild.firstChild.addEventListener("mousedown",this.startColumnDrag,false);

I like the idea you've suggested, as soon as I have my current project out of the way, I'll do some investigating on a rewrite (if no one else has done so)

 
gollum Scriptwright

http://userscripts.org/scripts/show/26900

 
Oscar's Friend Scriptwright

Good work, gollum! But it doesn't do very much as it stands. However, removing this line (right near the end):

if (tables[i].className.match(/resizable/)) {

and it's matching close brace, means it should work with any table on any page. I tried it out with that fix here, and even had some success in shrinking down the side bar at the BBC news website.

 
gollum Scriptwright

Oscar's Friend making it global for any site with tables is a bad idea - really screws up some sites. Instead, you could create a trigger script and restrict the @include's to sites of interest...i.e.

A demo script http://userscripts.org/scripts/show/26926

 
Oscar's Friend Scriptwright

Thanks, for that. You make a good point, but as I only intent to use the script on sites I rarely use (otherwise I'll use Stylish/GM to fix things up properly), I'll enable and disable the script by hand when I want to resize something.

Cross
Presentational HTML allowed.
Use <code> for inline code and <pre> for code blocks. Use &lt; and &gt; for literal < and >.
We help break paragraphs and link your links.
or cancel