Skip to content
Advertisement

How to highlight and select multiple rows?

I would like to be able to perform similar operation to Excel where users can highlight and select multiple rows:

[Selected Excel rows are highlighted and the entire highlighted area has a green border.]

Here is an example where a user can click on the row and the row gets selected. But I want the green outline similar to Excel to be applied to my Bootstrap table. Ideally, there would be an option where to change the cursor to be able to highlight and select rows.

$("#table tr").click(function(){
   $(this).toggleClass('selected');    
   var value=$(this).find('td:first').html();
   alert(value);    
});

$('.ok').on('click', function(e){
    var selected = [];
    $("#table tr.selected").each(function(){
        selected.push($('td:first', this).html());
    });
    alert(selected);
});
td {border: 1px #DDD solid; padding: 5px; cursor: pointer;}

.selected {
    background-color: brown;
    color: #FFF;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">


<table id="table">
    <tr>
        <td>1 Ferrari F138</td>
        <td>1 000€</td>
        <td>1 200€</td>
        <td>Model monopostu stajne Scuderia Ferrari pre sezónu 2013</td>
        <td>1</td>
        <td>F138</td>
        <td>Klik pre detaily</td>
    </tr>
    <tr>
        <td>2 Ferrari F138</td>
        <td>1 000€</td>
        <td>1 200€</td>
        <td>Model monopostu stajne Scuderia Ferrari pre sezónu 2013</td>
        <td>1</td>
        <td>F138</td>
        <td>Klik pre detaily</td>
    </tr>
    <tr>
        <td>3 Ferrari F138</td>
        <td>1 000€</td>
        <td>1 200€</td>
        <td>Model monopostu stajne Scuderia Ferrari pre sezónu 2013</td>
        <td>1</td>
        <td>F138</td>
        <td>Klik pre detaily</td>
    </tr>
</table>
<input type="button" name="OK" class="ok" value="OK"/>

Advertisement

Answer

You would have to listen to the dragstart and dragend events on the <table>.

You can capture the cell index at the beginning and the end of dragging, calculate the delta, set the range selections, and finally display the selection.

var isDragging = false;
var start, end;
var lastKnownCell;

var $table = $('#table');

function getCellByCoords(coords) {
  return $table.find('tr').eq(coords.row).find('td').eq(coords.col);
}

function getCellCoords(cell) {
  return { row: $(cell).parent().index(), col: $(cell).index() };
}

function clearHighlight() {
  $table.find('td').removeClass('highlighted');
}

function getMin() {
  return {
    row: Math.min(start.row, end.row),
    col: Math.min(start.col, end.col)
  }
}

function getMax() {
  return {
    row: Math.max(start.row, end.row),
    col: Math.max(start.col, end.col)
  }
}

function iterateActive(callback) {
  var min = getMin(), max = getMax();
  for (var row = min.row; row < max.row + 1; row++) {
    for (var col = min.col; col < max.col + 1; col++) {
      var cell = getCellByCoords({ row: row, col: col });
      callback($(cell), row, col);
    }
  }
}

function selectCells() {
  iterateActive(function($cell, row, col) {
    $cell.toggleClass('selected');
  });
}

function highlightCells() {
  iterateActive(function($cell, row, col) {
    $cell.addClass('highlighted');
  });
}

function onStartDrag(e) {
  start = getCellCoords(e.target);
  isDragging = true;
}

function onStopDrag(e) {
  end = getCellCoords(e.target);
  isDragging = false;
  selectCells();
  clearHighlight();
}

function onDrag(e) {
  if (isDragging && e.target.tagName === 'TD' && e.target !== lastKnownCell) {
    lastKnownCell = e.target;
    end = getCellCoords(e.target);
    clearHighlight();
    highlightCells();
  }
}

function displaySelection() {
  var text = $table.find('tr').map(function() {
    return $(this).find('td').map(function() {
      return $(this).hasClass('selected') ? $(this).text() : '';
    }).toArray().join('t').trim();
  }).toArray().filter(function(row) {
    return row.length > 0;
  }).join('n');
  console.log(text);
}

$table.on({
  mousedown: onStartDrag,
  mouseup: onStopDrag,
  mousemove: onDrag
});
$('.ok').on('click', displaySelection);
.as-console-wrapper { max-height: 3em !important; }

table {
  border-collapse: collapse;
  font-size: smaller;
}

tr {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

td {
  border: 1px #DDD solid;
  padding: 5px;
  cursor: pointer;
}

.selected {
  background-color: brown;
  color: #FFF;
}

.highlighted {
  background-color: lightblue;
  color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="table">
  <tr>
    <td>1 Ferrari F138</td>
    <td>1 000€</td>
    <td>1 200€</td>
    <td>Model monopostu stajne Scuderia Ferrari pre sezónu 2013</td>
    <td>1</td>
    <td>F138</td>
    <td>Klik pre detaily</td>
  </tr>
  <tr>
    <td>2 Ferrari F138</td>
    <td>1 000€</td>
    <td>1 200€</td>
    <td>Model monopostu stajne Scuderia Ferrari pre sezónu 2013</td>
    <td>1</td>
    <td>F138</td>
    <td>Klik pre detaily</td>
  </tr>
  <tr>
    <td>3 Ferrari F138</td>
    <td>1 000€</td>
    <td>1 200€</td>
    <td>Model monopostu stajne Scuderia Ferrari pre sezónu 2013</td>
    <td>1</td>
    <td>F138</td>
    <td>Klik pre detaily</td>
  </tr>
</table>
<input type="button" name="OK" class="ok" value="OK" />
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement