JavaScript

Creating resizable table grid with JavaScript

In this tutorial we’ll learn how to make html table columns resizable using pure JavaScript.

Create a table and style it

<style>
*{box-sizing: border-box;}
table{border-collapse:collapse;}
td,th{padding:5px 15px;text-align:left;}
table,th,td{border:1px solid #000;}
</style>

<table id="tableId">
 <thead>
  <tr>
   <th><input type="checkbox" /></th>
   <th>Size</th>
   <th>File</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><input type="checkbox" /></td>
   <td>10Mb</td>
   <td>C:\Users\BrainBell\Desktop\Empty\abc.txt</td>
  </tr>
 </tbody>
</table>
Size File
10Mb C:\Users\BrainBell\Desktop\empty\abc.txt

JavaScript code to resize HTML table column

The following code will select all tables and pass them to resizableGrid function.

var tables = document.getElementsByTagName('table');

for (var i=0; i<tables.length;i++){
 resizableGrid(tables[i]);
}

You can change the code If you don’t want to select all tables. For example, to select a single table by id:

var table = document.getElementById('tableId');
resizableGrid(table);

Next, we’ll create the resizableGrid which retrieves the very first row of the table and store all td elements to cols variable using row.children.

function resizableGrid(table) {
 var row = table.getElementsByTagName('tr')[0],
 cols = row ? row.children : undefined;
 if (!cols) return;

We’ll make a div for each column as column selector using createDiv function and pass this div to setListeners function for adding some mouse events listeners.

for (var i=0;i<cols.length;i++){
 var div = createDiv(table.offsetHeight);
 cols[i].appendChild(div);
 cols[i].style.position = 'relative';
 setListeners(div);
}

The createDiv function makes a div with absolute position which sits right side on the column. We’ll use this div as column resizer handle.

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';
 /* remove backGroundColor later */
 div.style.backgroundColor = 'red';
 div.style.userSelect = 'none';
 /* table height */
 div.style.height = height+'px';
 return div;
}

Table preview:

Size File
10Mb C:\Users\BrainBell\Desktop\empty\abc.txt

The setListeners function adds mousedown event to provided div element, so, when someone press the mouse button on that div (to resize the column) the mousedown event will trigger, where we store the values of current mouse position, the target column width and the next column width. The mousemove event listener add the difference previous and current mouse position pageX to current and next columns to resize the column. On mouseup event we’ll clear all the stored values.

function setListeners(div){
 var pageX,curCol,nxtCol,curColWidth,nxtColWidth;
 div.addEventListener('mousedown', function (e) {
  curCol = e.target.parentElement;
  nxtCol = curCol.nextElementSibling;
  pageX = e.pageX;
  curColWidth = curCol.offsetWidth
  if (nxtCol)
   nxtColWidth = nxtCol.offsetWidth
 });

 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';
  }
 });

document.addEventListener('mouseup', function (e) { 
 curCol = undefined;
 nxtCol = undefined;
 pageX = undefined;
 nxtColWidth = undefined;
 curColWidth = undefined;
 });
}

Re-sizeable Table preview, the table width is 100%:

Size File
10Mb C:\Users\BrainBell\Desktop\empty\abc.txt

Re-sizeable Table demo 2, the table width is set to auto:

a b c d e
         

Re-sizeable Table demo 3, red color removed:

a b c d e
         

Adding hover effect when mouse over the column selector

We'll add a class to column selector div by editing the createDiv function.

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';
 div.className = 'columnSelector';
 return div;
}

Now style the columnSelector class:

columnSelector : hover {
 border-right: 2px solid #0000f;
}

Re-sizeable Table demo 4, hover effect:

a b c d e
         
         

Make an HTML table resizable

Complete code:

//var tables = document.getElementsByClassName('flexiCol');
var tables = document.getElementsByTagName('table');
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;

  div.addEventListener('mousedown', function (e) {
   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';
   }
  });

  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))
 }
};

Visit HTML table resizer demo page to download the minified version of "Table Resizer" script.

Advertisement:
Advertisement: