37

I followed @koala_dev's code in this post to try to lock the first column s my table scrolls horizontally. The code unfortunately has no effect on my table. I was wondering if anyone could give me some pointers on what I have done wrong as I am new to programming.

This is my table: http://jsfiddle.net/mademoiselletse/bypbqboe/59/

This is the code I inserted in JS (line 121-133):

$(function() {
    var $tableClass = $('.table');
    // Make a clone of our table
    var $fixedColumn = $tableClass.clone().insertBefore($tableClass).addClass('fixed-column');

    // Remove everything except for first column
    $fixedColumn.find('th:not(:first-child),td:not(:first-child)').remove();

    // Match the height of the rows to that of the original table's
    $fixedColumn.find('tr').each(function(i, elem) {
      $(this).height($tableClass.find('tr:eq(' + i + ')').height());
    });
});

This is the CSS properties (line 36-47) I have inserted:

.table-responsive > .fixed-column {
   position: absolute;
   display: inline-block;
   width: auto;
   border-right: 1px solid #ddd;
}

@media(min-width:768px) {
    .table-responsive>.fixed-column {
        display: none;
    }
}

The only thing I deviated from the demo code was that I defined $('.table') as $tableClass instead of $table since I have previously defined var $table as $('#table') . Your help will be much appreciated!

Community
  • 1
  • 1
Vic
  • 617
  • 1
  • 8
  • 12
  • In your demo there is this line var `$tableClass = $('.table');` i.e. you are trying to get your table object with reference to class but you have given your `table` with `id` as `table` and not `className` as `table` – Guruprasad J Rao May 26 '15 at 03:44
  • Thanks for pointing it out! I referenced the table by ID instead but I got this: http://jsfiddle.net/mademoiselletse/bypbqboe/62/ Could you give me some hint on why that is? – Vic May 26 '15 at 04:15
  • your code is quite confusing!! Why are you cloning the `table` and why are removing all the `table data` and `table head` except first one?? – Guruprasad J Rao May 26 '15 at 04:25
  • because I want to lock the first column when the table scrolls to the right, since I have quite a lot of columns, just like what this person did: http://jsfiddle.net/4XG7T/3/ – Vic May 26 '15 at 04:48
  • Yea I got it!! But you can just do it with `css` right?? why `cloning` and again inserting and all for that?? – Guruprasad J Rao May 26 '15 at 04:55
  • You are facing that problem because when you try to clone the table there will not be any data present in your `table` since you are loading it through `ajax` request. What you can do is execute that piece of code like cloning and all, once all the table data has been loaded!! can you tell me the function name which loads the table data?? – Guruprasad J Rao May 26 '15 at 05:14
  • The data-loading function is from line 47 to 57. – Vic May 26 '15 at 05:17
  • I see what you mean now. Is there a way to accomplish the same effect without cloning the table? I tried setting the position of the first 2 columns as `absolute` by inserting this in CSS but didn't work out: #table th:nth-child(1), #table td:nth-child(1), #table th:nth-child(2), #table td:nth-child(2){ position: absolute } – Vic May 26 '15 at 05:27
  • Actually the thing is here `boostraptable` plugin will add some more `divs` before the table to make it `responsive` and you need to try to append it in the exact place! i.e. the example you have seen, hides the first header and column with a newly created `table` which is very difficult to achieve in this!! anyways!! will give a try once!! – Guruprasad J Rao May 26 '15 at 05:29

4 Answers4

59

Just add position:sticky to th & td first-child.

th:first-child, td:first-child
{
  position:sticky;
  left:0px;
  background-color:grey;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" rel="stylesheet"/>
<table class="table">
  <tr>
    <th>TIME</th>
    <th>Company</th>
    <th>Company</th>
    <th>Company</th>
    <th>Company</th>
    <th>Company</th>
    <th>Company</th>
    <th>Contact</th>
    <th>Country</th>
  </tr>
  <tr>
    <td>11:40   </td>
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td> 
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Germany</td>
  </tr>
  <tr>
    <td>11:40   </td>
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Centro comercial Moctezuma</td>
    <td>Francisco Chang</td>
    <td>Mexico</td>
  </tr>
  <tr>
    <td>11:40   </td>
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Ernst Handel</td>
    <td>Roland Mendel</td>
    <td>Austria</td>
  </tr>
  <tr>
   <td>11:40   </td>
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Island Trading</td>
    <td>Helen Bennett</td>
    <td>UK</td>
  </tr>
  <tr>
    <td>11:40   </td>
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Laughing Bacchus Winecellars</td>
    <td>Yoshi Tannamuri</td>
    <td>Canada</td>
  </tr>
  <tr>
    <td>11:40   </td>
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Alfreds Futterkiste</td>
    <td>Maria Anders</td>
    <td>Magazzini Alimentari Riuniti</td>
    <td>Giovanni Rovelli</td>
    <td>Italy</td>
  </tr>
</table>
suhailvs
  • 20,182
  • 14
  • 100
  • 98
  • Great one. But how to fix the left border if the table has the class `table-bordered` so that the scrolling shows the texts behind the border pixel. ref: https://jsfiddle.net/mpsbhat/hq9f4Lws/ – mpsbhat Sep 27 '21 at 04:11
45

Ok.. Remove all your js code and you can do this with some CSS tricks as below:

DEMO

CSS

.table > thead:first-child > tr:first-child > th:first-child {
    position: absolute;
    display: inline-block;
    background-color: red;
    height: 100%;
}

.table > tbody > tr > td:first-child {
    position: absolute;
    display: inline-block;
    background-color: red;
    height: 100%;
}

.table > thead:first-child > tr:first-child > th:nth-child(2) {
    padding-left: 40px;
}

.table > tbody > tr > td:nth-child(2) {
    padding-left: 50px !important;
}
Guruprasad J Rao
  • 29,410
  • 14
  • 101
  • 200
  • Anytime!! Happy Coding.. :) – Guruprasad J Rao May 26 '15 at 08:17
  • 1
    This is an excellent pure-CSS solution, that beats the crap out of that mess of JS & CSS from the other referenced post. – wndxlori Sep 14 '15 at 23:04
  • @GuruprasadRao ,Please update your Demo link,its not working anymore – Shekhar Pankaj Mar 18 '16 at 13:19
  • 1
    @ShekharPankaj. Sorry but I see it working still.. Could you please let me know what's not working...? – Guruprasad J Rao Mar 18 '16 at 16:48
  • 1
    (cannot format, backticks are newlines) Only following part was good enough for me (using bootstrap-table plugin): `` `/* making sure all rows are padded ahead of the fixed column*/` `.table > thead > tr > th {` `padding-left: 40px !important;` `}` `` `/* fixing the column using absolute positioning */` `.table > tbody > tr > td:first-child {` `position: absolute;` `width: 40px;` `}` `` – gawkface Mar 15 '17 at 10:10
  • This solution works fine, *but* it has a downside: there are **2 scrollbars**. How could we get rid of the inner one? – Razvan Zamfir Dec 11 '18 at 13:06
  • 1
    Demo doesn't seem to be working for me; assume the getData button is supposed to populate the table? – Jeff Axelrod Jun 18 '20 at 21:23
  • 1
    @JeffAxelrod I think the data source is throwing 404. You might need to test it against different data.. But trust me, the solution works.. :) – Guruprasad J Rao Jun 18 '20 at 21:53
3

The following style will create a striped table with the first column fixed:

th:first-child, td:first-child{
    position: sticky;
    left: 0px;
    z-index: 1;
}
tr:nth-child(odd) > td{
    background-color: #ededed;
}
tr:nth-child(even) > td{
    background-color: #e2e2e2;
}
tr:nth-child(odd) > th{
    background-color: #d7d7d7;
}
ClarkeyBoy
  • 4,934
  • 12
  • 49
  • 64
Jithin Pavithran
  • 1,250
  • 2
  • 16
  • 41
2

$('#table') means your finding element by id table.

$('.table') means your finding elements by class table.

These are the CSS selectors you used in css.

In your case, your table had id table so you can select that table using $('#table').

And you don't have any html elements using class table, so you'll get nothing when you select using $('.table').

Dilip Kumar
  • 2,504
  • 2
  • 17
  • 33
  • Thanks for pointing out that I don't have the class `table`. I realize that I put `table` inside of `data-class`. I followed your advice and referenced the table by its ID but I got this: http://jsfiddle.net/mademoiselletse/bypbqboe/62/ Are my codes conflicting? – Vic May 26 '15 at 04:12