views:

1724

answers:

5

I am pulling back a large amount of tabular data that I wish to display using a table. The only caveat is that I would like to be able to "lock" a few of the columns (fname/lname/email) so that when users scroll horizontally those columns always stay "locked" in place and are visible. I have done something similar to this before but that was back in the frameset days so that approach is no longer valid.

I was thinking about doing something clever with laying tables on top of each other but so far I have had no success with making this work. Anyone have any clever suggestions?

A perfect example of what I am trying to do is here: http://www.google.com/squared/search?q=world+leaders

+3  A: 

Found this related question

http://stackoverflow.com/questions/1100835/scrollable-html-table-with-top-row-and-left-column-frozen

Peter Bailey
Ahh this is exactly what I am looking for, thank you for pointing this post out!
Nicholas Kreidberg
Unfortunately the solutions posted there aren't up to par. The javascript that is the "accepted solution" slows to a crawl with even a small number of table rows. I am only working with 500 and its unusable.
Nicholas Kreidberg
A: 

If I understood correctly what you want, you can have a container div with position: relative, overflow: auto and fixed width. Inside of it, you separate the part you want to be locked, from the other one, into say, two different divs. The div containing the "locked" part should have position: absolute and left: 0.

It's just the big picture but you should be able to accomplish what you want this way.

treznik
A: 

The code below should be pretty self-explanatory. You can add/remove rows from TBODY while THEAD remains perfectly static. This is what TBODY and THEAD exist for ;)

<style type="text/css" media="screen">
  .myTable
  {
    border:1px solid #000;
    border-spacing:0px;
    width:300px
  }

  .myTable thead td
  {
    background-color:#000;
    color:#FFF;
  }

  .myTable tbody
  {
    height:300px;
    overflow-y:auto;
    overflow-x:hidden;
  }
</style>

<table class="myTable">
  <thead>
    <tr>
      <td>Fname</td>
      <td>Lname</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Lior</td>
      <td>Cohen</td>
    </tr>
    <tr>
      <td>Lior</td>
      <td>Cohen</td>
    </tr>
    <!-- put more rows here -->
  </tbody>
</table>
Lior Cohen
I am a little confused, how does keep things "locked" in place? I will have several items I need in <thead> but I only want a couple of them (for the purpose of this example lets just say one of them, so first name) to stay "locked". Real world example = http://www.google.com/squared/search?q=world+leaders -- notice how the names never move.
Nicholas Kreidberg
Sorry, I misunderstood your problem then. I thought you meant a table with a static headers row and a scrollable body content. I will update this post tmw with a solution that covers a locked left column as well (unless you no longer require an answer since you already got one).
Lior Cohen
No actually I do still require a solution, still haven't found anything I am happy with.
Nicholas Kreidberg
That still holds true now :P
Nicholas Kreidberg
A: 

Something like this should work:

You are going to have to play with it a little so that you don't have the horizontal scroll bar as well, but you get the idea.

Of course, this didn't work in IE7. It may work in 8, but as always YMMV. Good luck. I hope this gets you started in the right direction.

<html>
  <head>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
      $(document).ready(function() {
        var body = $('#table-body');
        for (var i = 0; i < 100; i++) {
          var row = $('<tr />');
          var fname = $('<td />')
            .text('FirstName' + i);
          var lname = $('<td />')
            .text('LastName' + i);
          var email = $('<td />')
            .text('FirstLast' + i + '@example.com');
          row
            .append(fname)
            .append(lname)
            .append(email);
          body.append(row)
        }
      });
    </script>
    <style type="text/css">
      #table-body {
        height: 150px;
        overflow: auto;
      }
    </style>
  </head>
  <body>
    <table>
      <thead>
        <td>First Name</td>
        <td>Last Name</td>
        <td>Email</td>
      <thead>
      <tbody id="table-body">
      </tbody>
    </table>
  </body>
</html>
Stephen Delano
A: 

Were you able to find a solution for this after all? I am having the same issue with the speed and have been looking to update to something more efficient.

lizkim270
Believe it or not I still haven't found a perfect solution to this problem. We "side-stepped" the issue somewhat but I would still like to find an elegant and efficient solution to this.
Nicholas Kreidberg