user7303261
user7303261

Reputation: 137

Resizing whole column

My goal is to create table with resizable width of columns in pure JavaScript. See this link. When I enlarge the size of let's say td 1 and then I try to make it smaller by dragging the border of td 3, it is stuck and not possible to make it smaller unless you do it again with td 1. I guess the problem is it creates a div with certain size which is not possible to change while dragging with the border of td 3. Any ideas how can i change the div width from the other cell?

JS:

(function () {
    var thElm;
    var startOffset;

    Array.prototype.forEach.call(
      document.querySelectorAll("table td"),
      function (th) {
        th.style.position = 'relative';

        var grip = document.createElement('div');
        grip.innerHTML = " ";
        grip.style.top = 0;
        grip.style.right = 0;
        grip.style.bottom = 0;
        grip.style.width = '5px';
        grip.style.position = 'absolute';
        grip.style.cursor = 'col-resize';
        grip.addEventListener('mousedown', function (e) {
            thElm = th;
            startOffset = th.offsetWidth - e.pageX;
        });

        th.appendChild(grip);
      });

    document.addEventListener('mousemove', function (e) {
      if (thElm) {
        thElm.style.width = startOffset + e.pageX + 'px';
      }
    });

    document.addEventListener('mouseup', function () {
        thElm = undefined;
    });
})();

HTML:

<table>
    <thead>
        <tr>
            <th>th 1</th>
            <th>th 2</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>td 1</td>
            <td>td 2</td>
        </tr>
        <tr>
            <td>td 3</td>
            <td>td 4</td>
        </tr>
    </tbody>
</table>

Upvotes: 0

Views: 79

Answers (1)

Rohan
Rohan

Reputation: 79

Your code is resizing the cell. Try resizing the header, instead of the cell.

HTML:

<thead>
    <tr>
        <th data-header-id="col-1">th 1</th>
        <th data-header-id="col-2">th 2</th>
    </tr>
</thead>
<tbody>
    <tr>
        <td data-column-id="col-1">td 1</td>
        <td data-column-id="col-2">td 2</td>
    </tr>
    <tr>
        <td data-column-id="col-1">td 3</td>
        <td data-column-id="col-2">td 4</td>
    </tr>
</tbody>

var thElm;
var startOffset;

JS:

Array.prototype.forEach.call(
  document.querySelectorAll("table td"),
  function (th) {
    var columnId = th.attributes["data-column-id"].value;
    th.style.position = 'relative';

    var grip = document.createElement('div');
    grip.innerHTML = "&nbsp;";
    grip.style.top = 0;
    grip.style.right = 0;
    grip.style.bottom = 0;
    grip.style.width = '5px';
    grip.style.position = 'absolute';
    grip.style.cursor = 'col-resize';

    grip.addEventListener('mousedown', function (e) {
        thElm = document.querySelectorAll("[data-header-id='" + columnId + "']")[0];
      console.log(thElm);
        startOffset = thElm.offsetWidth - e.pageX;
    });

    th.appendChild(grip);
  });

document.addEventListener('mousemove', function (e) {
    if (thElm) {
        thElm.style.width = startOffset + e.pageX + 'px';
    }
});

document.addEventListener('mouseup', function () {
    thElm = undefined;
});

This is a fork of your fiddle, showing this updated code: http://jsfiddle.net/54n2rke9/12/

Update: An alternate approach

Here, the original HTML doesn't need to be changed.

Array.prototype.forEach.call(
  document.querySelectorAll("table td"),
  function (th) {
    th.style.position = 'relative';
    var cellIndex = th.cellIndex;
    ...
    grip.addEventListener('mousedown', function (e) {
          thElm = document.querySelectorAll("th")[cellIndex];
        startOffset = thElm.offsetWidth - e.pageX;
    });

    th.appendChild(grip);
  });

Upvotes: 1

Related Questions