views:

87

answers:

1

I'm building grid component for my own needs with sortable columns, rows, etc. Existing ones either were not suiting my needs or were too heavy. I just started on resizable columns when realy unexpectedly WebKit has hit my with unexplainable anomaly. While table-layout:fixed; worked perfectly on all other browsers (even IE) Safari/Chrome gave me a headache.

Here is what I wrote so far: TSort Embriyo

As you can see it creates two tables - one for headers and one for body and some wrappers around them. Then it tries to make use of table-layout:fixed, since it better fits dynamical grid concept. For table-layout:fixed it is crucial for table to have a width, in addition to that all my cells (td/th) have overflow:hidden, white-space:nowrap and text-overflow:ellipsis to mimic grid appearance better.

Now the "bug" - both tables are constructed the same way, width of the cells and of the table is calculated and set by the same function. The "bug" is unexplainable because approach I use works as expected for top table but fails for bottom one. Basically it acts as if I had no width assigned to it. But you can see in Web Inspector that it definitely has the width... So... huh?

I tried everything, I swapped functions, I removed top table, I tried to built bottom table the way I build top table. But it keeps failing. However when I copy/paste generated table code into the page directly it starts to work. So my guess here is that it has something with dynamical nature of the table. But why it works on the top table then?

I was able to kinda get rid of this "bug" by creating table element with pre-assigned width. But it doesn't explain the weird behavior, does it?

+1  A: 

I found a fix - still not sure exactly what's going on.

Move:

self._addColElements(self.bd);

to the bottom of your construct function (and of course remove it from populate).

You might have noticed that in my previous test I added a 'data' option. I found that calling populate from _init with that data worked fine - unless I used setTimeout to delay the call - like the ajax get does - and then it too distorted the table. So it's timing related - perhaps WebKit is doing something interesting to optimise rendering.

EDIT

Ok, I have a theory ;)

When the table is created and rows are added all within the same function, css is applied at the end of the function call - and at that point the table-layout:fixed item will only apply if the table has a width.

If the table is created, and the css is applied to it (i.e. because control has returned to the browser via e.g. ajax or setTimeout), when it doesn't have a width, then the fixed layout has no effect. Subsequently adding items and even setting the width does not cause the css to be re-evaluated.

sje397
FYI, even with a delay of '0' in the `setTimeout` call the problem still happens.
sje397
Another option is to delay creating the second table until you populate it - here's a [minimal example of the problem](http://jsfiddle.net/m88ww/3/)
sje397
Wow... you went really far with your research! I think now that that's the case, although it still sounds to me as something that probably should not have been done in WebKit, since it's not what people would normally expect.
jayarjo
While delaying things often solves the things, I try to use this approach as last resort :) I was thinking what else I can do... and then it came to my mind that I know column widths prior to ajax response, so that actually nothing keeps me from calculating the width of the table before putting it into the DOM. My updated code will be here for some time (I moved first case to different place): http://infinity-8.me/tsort/ :)
jayarjo
@jayarjo - the first suggestion above is exactly that. By calling _addColElements for the body table at the end of `construct`, you add the column sizes and set the width of the table, before the ajax call returns.
sje397
Right :) the second suggestion caught and kept my attention in the end, though. Thank you for your time and efforts :) Great work!
jayarjo
@jayarjo - thanks for an interesting problem.
sje397