Scrolling a table with multiple fixed table headers - javascript

Before I attempt to reinvent the wheel (via jQuery plugin or similar), I'm trying to see if there is an easier way to do this or an existing plugin that users may know of. What I'm looking to do is scroll the body of a table that contains multiple table headers. For example, imagine something of this structure:
<table>
<thead>
<tr>
<td colspan="2"></td>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
<thead>
<tr>
<td colspan="2"></td>
</tr>
</thead>
<tbody>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td></td>
<td></td>
</tr>
</tbody>
</table>
Honestly, I haven't tried out the above syntax to even see if its valid. The actual markup I have does not currently use thead/tbody and instead scrolls the whole parent div (seen below).
What I want to achieve is scrolling of the whole table such that the header of the most relevant section is viewed on top. Currently the header scrolls out of view is there are enough rows.
I know the various techniques used to scroll a table with one header, but what about multiple? Are there any existing ways to achieve this? I'm open to different ideas, but right now I'm thinking of simply displaying the most relevant table header for the content on top.

A few months ago, I wrote some code that did exactly that where I wanted the headers to perform similar to section headers on iOS.
Utilising a Jquery, the solution I ended up with involved creating an onScroll (and onResize for window resizing) event listener that ran a check through all $('table thead') and checked their $(this).position() on the page.
The check was whether the thead had a position which was above the top of the current viewport.
Once I had found the most relevant header (the bottommost thead that was above the viewport), I created a new table, with position: fixed at (0, 0) and copied into it a new column for each column of the headers rows and manually set its width properties to match the original table.
I have put together a Proof of Concept which shows how this all works.
Here is some pseudo-code of how it works:
Check the table is visible
Get a list of all thead sections in the table
Reverse the list
Find the first thead in the array with a top position less than scrollTop of the body element
If we found one:
Create deep copy of the thead
Make a container table
Copy attributes from the original table so the styles get copied
Position the container at [0, originalTable.left]
Set the width equal to the outerWidth of the original table
Set the width of every td found to the width of the matching td from the original table
Add it to the DOM
If none found, remove the existing container from the DOM if there was one
There are some other edge case details that made this even nicer too:
Instead of (0, 0), the origin point for the fixed row was altered based upon whether the "real" header row for the tbody below the one with the fixed header should be pushing it away.
Ensure that previous header rows are deleted before making a new one
Don't recreate the header row if the header you'd be making is the same as what is already there
This approach worked a lot better others I tried such as trying to position:absolute an object due to the fact that Firefox and IE aren't incredibly fast at running the onScroll handler so you tend to see 'juddering'. I also tried mucking with the position attribute of the theads, this just ended in the table column widths jumping about and not matching the data.
thead nodes aren't strictly required for this solution as you can use some other selector to determine which rows are headers etc.
Update: Added example code and pseudo-code
Update: Dropbox changed their system, replaced example with jsfiddle URL

Related

HTML table headers with different widths than cells

I'm trying to make an HTML table where the <th>'s have a different width than the <td>'s, yet still be aligned. I'm wondering if that's possible to do with CSS/JavaScript. Also, I'm using the DataTables jQuery plugin to create my HTML since I need fixed headers/first column.
Here's how the table currently looks: (see first image in the album)
I want to squish the td's together, but the table headers are too wide. If I just squish the td's together without doing anything to the th's, then the table loses alignment. (I know it looks horrible with the border, it just helps show the misalignment)
I changed the width by altering the width calculated by the DataTables/FixedColumns plugin. Trying to change the width of the headers doesn't give me the effect that I want.
(see second image in the album)
Finally, this is an example of pretty much what I'm looking for. See how the table headers overlap with each other?
(see final image in the album)
I was wondering if this is possible to do with CSS/JavaScript? Sorry for not posting links to the individual images, I'm new to the site and I don't have enough reputation to post more than two links. Thanks a lot, everyone!
Image album: http://imgur.com/a/9uXs5
A quick search and I found this: https://web.archive.org/web/20131227124521/http://s-church.net/Blog/Entry/464
Looks like exactly what you want:
HTML code -
<table>
<thead>
<tr>
<th colspan=3>Values (Type A)</th>
</tr>
<tr>
<th colspan=3>Values (Type B)</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td><td>2</td><td>3</td>
</tr>
<tr>
<td>4</td><td>5</td><td>6</td>
</tr>
</tbody>
</table>
CSS code -
th {
background-color: #4072B4;
}
td {
background-color: #608DC9
}
http://jsfiddle.net/CLvD2/
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td#Attributes

Resize column of html table

I have this simple html table
<table id="tablex">
<tr>
<th>col1</th>
<th>col2</th>
</tr>
<tr>
<td>data1</td>
<td>data2</td>
</tr>
</table>
and I tried to make it's columns resizable with colResizable
but the problem is when I resize a specific column of the table, the next column to the resizable one is affected because the full width of the table is fixed.
I have tried another solution posted here and other one here but the same problem was present.
Is there an other way to make columns resizable using one of jquery libraries or javascript function?
you can use colResizable 1.5, it allows two different methods of resizing the table: fixed and non-fixed.
By default, it is fixed, which means that when you resize a column, the next one shrinks or expands to fit the whole table. In fixed mode table width does not change at all.
I think you are asking for the non-fixed mode. In non fixed mode you can resize each column independently, so if you change the width of a column the others remain in the same state (but the table will increase its size by the same amount as the column does).
You can check some examples on its website: http://www.bacubacu.com/colresizable
but I guess that you are looking for something like this:
$("#nonFixedSample").colResizable({fixed:false, liveDrag:true});
I had the same question: Resizable table columns with jQuery (table wider than page)
My solution was to place contents of my column headers <th>s inside another tag- I used links (<a>s).
Instead of doing anything with the <th> I had to set the style of the <a>s to display: block
Then just $('th a').resizable({handles:'e'});
See http://jsfiddle.net/u32a1ccL/
This uses jQuery and jQuery UI

Tie DIV element to overflow scrollbar

I'm trying to create a datagrid table that will allow me to fix the header. I have placed the table within two DIV elements and fixed the THEAD portion of the table. I populate the table dynamically and there can be a different number of columns and may have different widths each time.
<DIV style="position: relative; width="500px">
<DIV style="height:105px; overflow: auto;">
<TABLE width="502px">
<THEAD>
<TR style="left:-1px;top: 0;position: absolute;">
... header content ...
</TR>
</THEAD>
<TBODY>
... data columns ...
</TBODY>
</TABLE>
</DIV>
</DIV>
The solution works well for the vertical overflow. However, I'm struggling with the horizontal overflow. Because I fixed the THEADs TR element, if my table exceeds the DIV width, the horizontal scrollbar appears and I can scroll the data horizontally, but the titles are static and don't scroll.
I was thinking that I might be able to somehow scroll the table header using jQuery if I could get the id/name of the dynamically created scrollbar, but I don't know if this is the right solution or if it is even possible.
A ton of people have tried to make fixed headers and left columns for tables using html and css, that stay put while you scroll, and unfortunately it doesn't work.
Your only option is to use javascript to manipulate the table as it scrolls. I have no specific code to recommend, but do some google searches.

How can we freeze first column and header(which have multiple rows) in html table

I have tried so many solutions to freeze first column and header(which have multiple rows) but in every solution i have to user custom css (css according to solutions).
In my case I cannot change my previous css. I want code in which on div scroll I can freeze my table(which is dynamic).
Please provide solution.
I've done this like this:
<table style="table-layout: fixed">
<tr>
<td><div style="width:100px; position:fixed;">Frozen Header text</div></td>
</tr>
<tr>
<td>Some data</td>
</tr>
<table>
I am not sure how to get the first column frozen as well, but I suppose you can attempt to use the same strategy, as well as formatting using the <col> tag, similar to this:
<col style="width:100px; position:fixed;" />
Try that, and please let us know how you go.
To achieve what I comets jquery and css use. Here the plugin:link
This is a jQuery plugin that can make table rows and columns not scroll.
It can take a given HTML table object and set it so it can freeze a given number of columns or rows or both, so the fixed columns or rows do not scroll.
The rows to be frozen should be placed in the table head section.
It can also freeze rows and columns combined with using colspan or rowspan attributes.
Fix header is relative simple and easy to implement. and column is a different thing.
for example:
<table>
<tr class="header"><td>header</td></tr>
<tr><td>body</td></tr>
</table>
You have to monitor onscroll envent, and detect if the header is out of view.
When it's out of view, retrieve tr.header's size parameters (also include TDs inside), and its clientX and clientY by using getBoundingClientRect(). make a clone of tr.header by using cloneElement(true) and place it in the same table. then assign size parameters to its TDs, and make this cloned element fixed to screen.
This solution won't not affect your table's styles or layout, while it is complex indeed.

Tiny-MCE plugin for setting column width in table

We are using Tiny-MCE in our CMS, and our users would like to have the ability to change the width of a column in a table. Now, I know that from an HTML point, there is no such entity "column", but in the Moodle editor, HTMLAREA, there is a plugin that does that - allows to set a width (only in percents) to a column:
Sorry it's in Hebrew, I couldn't find a version in English...
does anyone know of a plugin to Tiny-MCE that could do that? Or have an idea how I would go about writing such a plugin?
Isn't that what the HTML option is for? :)
Another choice is the styleprops (edit Css Style), not sure how this works completely, but there is an option on the box tab that will let you set a width. I have removed it to avoid shenanigans!
Alternatively you could create several styles which have a width defined and then with the cursor focused on the cell by choosing the style width20percent the box goes 20%.
#Lea Cohen: I found this plugin for TinyMCE -- http://sourceforge.net/tracker/?func=detail&aid=2800315&group_id=103281&atid=738747 -- which sounds like it should do what you wish, perhaps even in a more "user friendly" way than making the user enter widths manually:
Adds the ability to resize a tables' cell borders by dragging the mouse ..
The way I see it working is resizing the first cells acting as the "column" headings which should see subsequent cells in that column inheriting the width settings, e.g.
<table>
<tr>
<td width="300">Col 1</td>
<td width="200">Col 2</td>
</tr>
<tr>
<td>Width 300</td>
<td>Width 200</td>
</tr>
</table>
Update
If that plugin doesn't work for you, you should also have a look at the Table plugin which seems to have options for controlling rows/cells as well: http://tinymce.moxiecode.com/wiki.php/Plugin:table
I found the answer I was looking for. It's an enhancement of the cell dialog box, that adds an option in the select box on the bottom:
The only thing is that you have to make sure you're in the top most cell in the column, as the JS updates only the next cells in the column, and not the previous ones. But other than that - it's just what we needed.

Categories

Resources