【问题标题】:How to highlight selected table cells in AngularJS?如何在 AngularJS 中突出显示选定的表格单元格?
【发布时间】:2020-07-12 22:14:25
【问题描述】:

例如,当用户通过将鼠标从第一个单元格拖动到另一个单元格来选择表格行中的某些单元格时,我需要在表格单元格中获取隐藏的输入值。我如何在 AngularJS 中做到这一点?

看图更好理解:http://screencast.com/t/m3hcN11leTh

【问题讨论】:

  • 好吧,您需要发布您的代码、您尝试过的内容以及遇到的问题。创建一个 plunker 会很有用(或 jsfiddle/jsbin/等)。
  • 要解决您的问题,您可能需要在每个单元格上创建一个 mousedown 和 mouseup 侦听器,然后您可以使用 angular 元素抓取第一个 mousedown 和 mouseup 之间的所有单元格。

标签: javascript angularjs selection


【解决方案1】:

如果您仍在寻找答案,我为表格中的多单元格选择开发了一个角度指令。您可以在

上找到它

在你的脚本中;

var app = angular.module('myApp', []);

app.controller('MainCtrl', function($scope) {
  $scope.ids = [];
  $scope.rowTable = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
  $scope.colTable = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];
});
app.directive('multiCellSelect', function($window, $document) {

  return {
    scope: {
      multiCellIds: '='
    },
    controller: function($scope, $element) {
      var clearFlag = false;
      var startCell = null;
      var dragging = false;
      var finalCell = null;

      function mouseDown(el) {
        dragging = true;
        setStartCell(el);
        setRangeArea(startCell, el)
      }

      function mouseUp(el) {
        dragging = false;
        finalCell = el;
        setSelectedCells(startCell, finalCell);
        if (clearFlag) {
          clearCells(startCell, finalCell);
          clearFlag = false;
        }
        startCell = null;
      }



      function mouseLeave(el) {
        if (dragging) {
          if (el.hasClass('hover-area')) {
            cellsBetween(startCell, el).each(function() {
              var el = angular.element(this);
              el.toggleClass('hover-area').addClass('ui-state-default')
            });
            if (startCell == el) {
              el.toggleClass('hover-area').addClass('ui-state-default')
            }
          }
        } else {
          return;
        }
      }

      function mouseEnter(el) {
        if (!dragging) {
          return;
        } else {
          setRangeArea(startCell, el);
        }
      }

      function setStartCell(el) {
        startCell = el;
      }



      function setRangeArea(start, el) {
        if (dragging) {
          if (el.hasClass('ui-state-default')) {
            cellsBetween(startCell, el).each(function() {
              var el = angular.element(this);
              el.addClass('hover-area')
            });
          } else if (el.hasClass('hover-area') || el.hasClass('ui-state-default')) {
            cellsBetween(startCell, el).each(function() {
              var el = angular.element(this);
              el.toggleClass('hover-area').addClass('ui-state-default');
            });
          }

          if (!start.hasClass('eng-selected-item')) {
            cellsBetween(startCell, el).each(function() {
              var el = angular.element(this);
              if (el.hasClass('eng-selected-item')) {
                clearFlag = true;
              }
            });
          }

        }
      }

      function setSelectedCells(start, end) {
        if (start && end) {
          cellsBetween(start, end).each(function() {
            var el = angular.element(this);
            if (el.hasClass('eng-selected-item') && el.hasClass('hover-area')) {
              el.removeClass('eng-selected-item');
              el.removeClass('hover-area')
              var id = el.attr('id');
              var index = $scope.multiCellIds.indexOf(id);
              if ($scope.multiCellIds.indexOf(el.attr('id')) > -1) {
                $scope.multiCellIds.splice(index, 1);
              }
            } else if (el.hasClass('hover-area') && !el.hasClass('eng-selected-item')) {
              el.addClass('eng-selected-item');
              el.removeClass('hover-area')

              if ($scope.multiCellIds.indexOf(el.attr('id')) == -1) {
                $scope.multiCellIds.push(el.attr('id'));
              }
            }
          });
        }
      }

      function clearCells(start, end) {
        cellsBetween(start, end).each(function() {
          var el = angular.element(this);
          el.removeClass('eng-selected-item');
          el.removeClass('hover-area');
          var id = el.attr('id');
          var index = $scope.multiCellIds.indexOf(id);
          if ($scope.multiCellIds.indexOf(el.attr('id')) > -1) {
            $scope.multiCellIds.splice(index, 1);
          }
        });


      }

      function cellsBetween(start, end) {
        var coordsStart = getCoords(start);
        var coordsEnd = getCoords(end);
        var topLeft = {
          column: $window.Math.min(coordsStart.column, coordsEnd.column),
          row: $window.Math.min(coordsStart.row, coordsEnd.row),
        };
        var bottomRight = {
          column: $window.Math.max(coordsStart.column, coordsEnd.column),
          row: $window.Math.max(coordsStart.row, coordsEnd.row),
        };
        return $element.find('td').filter(function() {
          var el = angular.element(this);
          var coords = getCoords(el);
          return coords.column >= topLeft.column && coords.column <= bottomRight.column && coords.row >= topLeft.row && coords.row <= bottomRight.row;
        });

      }



      function getCoords(cell) {
        var row = cell.parents('row');
        return {
          column: cell[0].cellIndex,
          row: cell.parent()[0].rowIndex
        };

      }

      function wrap(fn) {
        return function() {
          var el = angular.element(this);
          $scope.$apply(function() {
            fn(el);
          });
        }
      }

      $element.delegate('td', 'mousedown', wrap(mouseDown));
      $element.delegate('td', 'mouseenter', wrap(mouseEnter));
      $element.delegate('td', 'mouseleave', wrap(mouseLeave));
      $element.delegate('td', 'mouseup', wrap(mouseUp));

    }
  }
});

在你的 html 中;

<body ng-app="myApp">

      <div ng-controller="MainCtrl">
        <h1>
        <i>Multi Cell Selection by Zerocool27</i>
        </h1>
        <table ng-table="idTable" class="table table-striped" multi-cell-select multi-cell-ids="ids">
          <tr>
            <th colspan="1">Days</th>
            <th colspan="2" ng-repeat="col in colTable">{{col}}
          </tr>
          <tr ng-repeat="row in rowTable">
            <th>{{row}}</th>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-0"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-1"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-2"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-3"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-4"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-5"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-6"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-7"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-8"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-9"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-10"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-11"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-12"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-13"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-14"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-15"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-16"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-17"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-18"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-19"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-20"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-21"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-22"></td>
            <td colspan="2" style="effect" class="ui-state-default" id="{{row}}-23"></td>
          </tr>
        </table>
        <div style="margin-top:20px;">
          <i>Selected Cells : </i>
          <span ng-repeat="id in ids">
          <i>{{id}}</i>
        </span>
        </div>


      </div>
    </body>

你的 CSS;

td {
  border: 0px solid black;
}

td:hover {
  background: #8deaed;
  background: -webkit-gradient(linear, 0 0, 0 bottom, from(#8deaed), to(#9fedf0));
  background: -moz-linear-gradient(#8deaed, #9fedf0);
  background: linear-gradient(#8deaed, #9fedf0);
  box-shadow: inset 0 0 0 1px #b9f2f5;
}

td,
th {
  width: 30px;
  text-align: center;
  font-weight: normal;
  color: #858584;
}

[multi-cell-select] {
  cursor: pointer;
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -user-select: none;
}

[multi-cell-select] .eng-selected-item {
  background: #007AFF;
  color: white;
  border-bottom-color: #007AFF;
  border: #007AFF;
}

[multi-cell-select] .hover-area {
  background: #8deaed;
  background: -webkit-gradient(linear, 0 0, 0 bottom, from(#8deaed), to(#9fedf0));
  background: -moz-linear-gradient(#8deaed, #9fedf0);
  background: linear-gradient(#8deaed, #9fedf0);
  box-shadow: inset 0 0 0 1px #b9f2f5;
}

.ui-state-default {
  border: 0px solid rgba(211, 211, 211, 0.54);
  background: #C0C0C0;
  -moz-box-shadow: inset 0 0 0 1px #63ad0d;
  -webkit-box-shadow: inset 0 0 0 1px #63ad0d;
  -moz-border-radius: 0px;
  background: #eee;
  background: -moz-linear-gradient(#eee, #e2e2e2);
  box-shadow: inset 0 0 0 1px #aaa;
  color: #5A5757;
  font: bold 10px Arial, Helvetica, Clean, sans-serif;
  text-align: center;
}

我已经为你创建了小提琴示例。

https://jsfiddle.net/Zerocool27/dg98mc9u/16/

【讨论】:

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review
  • @Laurel 该链接不是包含信息的参考,它是指向工具的链接。您的自动评论对这样的链接毫无意义。
  • @MarkAmery 它包含代码,其中一些应该回答问题(理论上)。重要的部分可以复制进去,除非它太多(我们应该看看问题是否太宽泛)。
  • @Laurel 不同意包含此类代码的必要性。使用一种语言的内置函数的建议不一定要附带函数的实现,那为什么库的建议需要附带任何实现该库的代码呢?
  • @MarkAmery 如果他们的 GitHub 链接被破坏/更改,我们不会失去内置函数的实现。我从experience, 发言,从长远来看,只有图书馆的答案是不好的。
【解决方案2】:

你可以通过安装ngx-cell-selectable来实现它。 这是一个关于它的 stackblitz 示例。 https://stackblitz.com/edit/angular-ivy-csqbzv

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 2015-11-03
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多