Search code examples
jquerycsshtml-tablefixed

Fixed header on resizable HTML table including auto-horizontal scroll overflow


I have built an html table using the following example as a guide, however I haven't been able to figure out how to make the head fixed so that it remains visible as a user scrolls:

https://jsfiddle.net/thatOneGuy/u5bvwh8m/16/

I have tried using CSS to control

.resizable{overflow-y: auto; position: sticky; height: 750px;}

I have also tried adding custom style to the head, however that breaks the resizing:

table thead tr{
    display:block;
}

table th,table td{
    width:100px;//fixed width
}


table  tbody{
  display:block;
  height:200px;
  overflow:auto;//set tbody to auto
}

Any help is very much appreciated.


Solution

  • try this

    thead th{     
      position: sticky !important; 
      top: 0; 
      background-color: white;
    }
    

    and remove the resizable class from table tag and put it in thead and tbody tags

    <table id="tableId" >
       <thead class="resizable">
        ...
       <tbody class="resizable">
    

    //var tables = document.getElementsByClassName('flexiCol');
    var tables = document.getElementsByClassName('resizable');
    for (var i = 0; i < tables.length; i++) {
      resizableGrid(tables[i]);
    }
    
    function resizableGrid(table) {
      var row = table.getElementsByTagName('tr')[0],
        cols = row ? row.children : undefined;
      if (!cols) return;
    
      table.style.overflow = 'hidden';
    
      var tableHeight = table.offsetHeight;
    
      for (var i = 0; i < cols.length; i++) {
        var div = createDiv(tableHeight);
        cols[i].appendChild(div);
        cols[i].style.position = 'relative';
        setListeners(div);
      }
    
      function setListeners(div) {
        var pageX, curCol, nxtCol, curColWidth, nxtColWidth, tableWidth;
    
        div.addEventListener('mousedown', function(e) { 
        
            tableWidth = document.getElementById('tableId').offsetWidth;
          curCol = e.target.parentElement;
          nxtCol = curCol.nextElementSibling;
          pageX = e.pageX;
    
          var padding = paddingDiff(curCol);
    
          curColWidth = curCol.offsetWidth - padding;
        //  if (nxtCol)
            //nxtColWidth = nxtCol.offsetWidth - padding;
        });
    
        div.addEventListener('mouseover', function(e) {
          e.target.style.borderRight = '2px solid #0000ff';
        })
    
        div.addEventListener('mouseout', function(e) {
          e.target.style.borderRight = '';
        })
    
        document.addEventListener('mousemove', function(e) {
          if (curCol) {
            var diffX = e.pageX - pageX;
    
           // if (nxtCol)
              //nxtCol.style.width = (nxtColWidth - (diffX)) + 'px';
    
            curCol.style.width = (curColWidth + diffX) + 'px';
            console.log(curCol.style.width)
            console.log(tableWidth)
            document.getElementById('tableId').style.width = tableWidth + diffX + "px"
          }
        });
    
        document.addEventListener('mouseup', function(e) {
          curCol = undefined;
          nxtCol = undefined;
          pageX = undefined;
          nxtColWidth = undefined;
          curColWidth = undefined
        });
      }
    
      function createDiv(height) {
        var div = document.createElement('div');
        div.style.top = 0;
        div.style.right = 0;
        div.style.width = '5px';
        div.style.position = 'absolute';
        div.style.cursor = 'col-resize';
        div.style.userSelect = 'none';
        div.style.height = height + 'px';
        return div;
      }
    
      function paddingDiff(col) {
    
        if (getStyleVal(col, 'box-sizing') == 'border-box') {
          return 0;
        }
    
        var padLeft = getStyleVal(col, 'padding-left');
        var padRight = getStyleVal(col, 'padding-right');
        return (parseInt(padLeft) + parseInt(padRight));
    
      }
    
      function getStyleVal(elm, css) {
        return (window.getComputedStyle(elm, null).getPropertyValue(css))
      }
    };
     * {
        box-sizing: border-box;
      }
    
      table {
        border-collapse: collapse;
      }
    
      td,
      th {
        padding: 5px 15px;
        text-align: left;
      }
    
      table,
      th,
      td {
        border: 1px solid #000;
      }
       
      thead th  { 
          position: sticky !important;
          top: 0;
          background-color: white;
        }
    <table id="tableId" >
      <thead class="resizable">
        <tr>
          <th><input type="checkbox" /></th>
          <th>Size</th>
          <th>File</th>
        </tr>
      </thead>
      <tbody class="resizable">
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
        <tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr><tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr><tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr><tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr><tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr><tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr><tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr><tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr><tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr><tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr><tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr><tr>
          <td><input type="checkbox" /></td>
          <td>10Mb</td>
          <td>C:\Usabc.txt</td>
        </tr>
      </tbody>
    </table>