CSS and HTML: mark area of table with mouse tracking

Viewed 215

Is there an example anywhere how to select an area of a html table with tracking the mouse? e.g. I press the mouse button and move from the second row and second column to the sixth row and fifth column - than this cells should be selected (e.g. with an other background color or a dashed border) and also the information should be fired anyhow which cells are selected -> 2/2 to 6/5. Is there any template or example with this behaviour? I use HTML, CSS and AngularJS in my frontend application - it would be great if an example based on this would exist.

1 Answers

I think the snippet below is what you are looking for. It will apply the CSS class .hightlight to all the cells that need to be highlighted. The global variable range will contain two coordinates of the selected range.

assignEvents();

function assignEvents() {
  var rows = document.getElementsByTagName('tr');
  
  for (let y = 0; y < rows.length; y++) {
    var cells = rows[y].children;
    
    for (let x = 0; x < cells.length; x++) {
      cells[x].onclick = function() {
        cellClick(x, y);
      }
      
      cells[x].onmouseenter = function() {
        mouseEnterCell(x, y);
      }
    }
  }
}

var selecting = false;
var anchor = {"x": 0, "y": 0};
var range = [anchor, anchor];

function cellClick(x, y) {
  var cell = document.getElementsByTagName('tr')[y].children[x];
  
  if (selecting == false) {
    anchor.x = x;
    anchor.y = y;
    
    range = [anchor, anchor];
    
    selecting = true;
  } else {
    selecting = false;
  }
}

function mouseEnterCell(x, y) {
  if (selecting) {
    highlightRange(anchor.x, anchor.y, x, y);
    range = [anchor, {"x": x, "y": y}];
  }
}

function highlightRange(ax, ay, mx, my) {
  var oldRangeHighlights = document.getElementsByClassName('highlight');
  
  while (oldRangeHighlights.length > 0) {
    oldRangeHighlights[0].classList.remove('highlight');
  }
  
  if (mx < ax) {
    var tx = ax;
    
    ax = mx;
    mx = tx;
    
  }
  
  if (my < ay) {
    var ty = ay;
    
    ay = my;
    my = ty;
  }
  
  var w = (mx - ax) + 1;
  var h = (my - ay) + 1; 
  
  for (x = 0; x < w; x++) {
    for (y = 0; y < h; y++) {
      document.getElementsByTagName('tr')[y + ay].children[x + ax].classList.add('highlight');
    }
  }
}
table {
  border-collapse: collapse;
}

td {
  width: 20px;
  height: 20px;
  
  border: 1px solid black;
}

.highlight {
  background-color: yellow;
}
<table>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</table>

Explaination

The function assignEvents() is called on the load of the file. It gets all the rows of the table and loops them. For each row all the cells are selected and given events. onclick is for detecting clicks to start or stop a selection and onmouseenter is used for changing the live selection.

selecting will be true if the user is currently selecting an area
anchor will contain the x and y values of the original point clicked
range will contain anchor x and y and hovered x and y captured by the onmouseenter event

cellClick() is called when a cell is clicked. It gets the clicked cell and checks if the user is currently selecting a range. If not, it will start and defined anchor and range. If it is, it will end the selection.

mouseEnterCell() is called when the mouse enters a cell. If the user is selecting a range, it will update the live selection.

highlightRange() will highlight a range given two coordinates. First, it removes any old highlights. It will set the anchor (ax, ay) to the position highest to the top. The width (w) and hight (h) are then calculated for the box. Then they are selected and given the CSS class highlight.

If need you need something change just say.

Related