angular - 如何在角材料表中获得选定区域?
问题描述
我想允许用户选择角表中的区域,如 Excel 表。如下图所示
我在点击时实现了多选行。
我不确定如何进行。
我发现了一些类似的插件,但不知道如何在 Angular 中实现
任何帮助,建议表示赞赏
解决方案
但它并不是那么复杂,它是stackblitz吗
如果我们的 tds 像
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef> No. </th>
<td mat-cell #cell *matCellDef="let element;let i=index"
(click)="select($event,cell)"
<!--use isSelected(i,0) for the first column
isSelected(i,1) for the second column
...
-->
[ngClass]="{'selected':isSelected(i,0)}"
> {{element.position}} </td>
</ng-container>
我们使用 viewChildren 获取单元格,并使用选择声明一个数组
selection: number[]=[];
@ViewChildren("cell", { read: ElementRef }) cells: QueryList<ElementRef>;
在单元格中,我们有从上到下和从左到右的所有“td”顺序
如果您按下 shifh 键或 control 键,该功能选择会考虑在内
select(event: MouseEvent, cell: any) {
//search the cell "clicked"
const cellClick = this.cells.find(x => x.nativeElement == event.target);
//get the index of this cells
let indexSelected = -1;
this.cells.forEach((x, i) => {
if (x == cellClick) indexSelected = i;
});
if (event.ctrlKey) { //if ctrl pressed
if (this.selection.indexOf(indexSelected)>=0) //if its yet selected
this.selection=this.selection.filter(x=>x!=indexSelected);
else //if it's not selected
this.selection.push(indexSelected)
} else {
if (event.shiftKey) { //if the key shift is pressed
if (this.selection.length) //if there any more selected
{
//calculate the row and col of fisrt element we selected
let rowFrom=this.selection[0]%this.dataSource.data.length;
let colFrom=Math.floor(this.selection[0]/this.dataSource.data.length)
//idem from the index selected
let rowTo=indexSelected%this.dataSource.data.length;
let colTo=Math.floor(indexSelected/this.dataSource.data.length)
//interchange if from is greater than to
if (rowFrom>rowTo)
[rowFrom, rowTo] = [rowTo, rowFrom]
if (colFrom>colTo)
[colFrom, colTo] = [colTo, colFrom]
//clean the array
this.selection=[]
//we run througth all the td to check if we need push or not
this.cells.forEach((x,index)=>{
const row=index%this.dataSource.data.length;
const col=Math.floor(index/this.dataSource.data.length)
if (row>=rowFrom && row<=rowTo && col>=colFrom && col<=colTo)
this.selection.push(index)
})
}
else //if there're anything selected and the shit is pressed
this.selection = [indexSelected]
} else { //if no key shit nor key ctrl
this.selection = [indexSelected]
}
}
}
并且一个函数 isSelected 提供了改变类的可能性
isSelected(row,column)
{
const index=column*this.dataSource.data.length+row
return this.selection.indexOf(index)>=0
}
带有 .css
table {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
td {
outline: none!important
}
.selected
{
border:1px solid red;
}
更新
在您需要的示例shift & ctrl
中。但是我们可以有一个复选框或一个选择来“改变选择方式” - 使用 [(ngModel)] - 并替换条件 event.shiftKey 和 event.ctrlKey。
如果你总是选择一个范围,你可以使用两个变量“fromIndex”和“toIndex”,
fromIndex:number=-1
toIndex:number=-1
select(event: MouseEvent, cell: any){
....
..get the indexSelected ...
if (this.fromIndex==-1){ //If nothing select
this.fromIndex=indexSelected
this.toIndex=-1
}
else{
this.toIndex=indexSelected;
}
if (this.toIndex>=0 && this.fromIndex>=0)
{
...the code to select range
}
}
推荐阅读
- java - org.apache.juli.FileHandler 在 GMT 中轮换
- java - 如何在 GitLab 的同一作业中保留多个 gradle 测试任务的测试报告?
- java - JComboBox.getSelectedItem().toString() 和 JTextField.getText() 有什么区别吗?
- python - Django Table 不存在 - 第一次迁移后
- sql - 如何在 SAS Enterprise Guide 中使用 PROC SQL 仅选择 char 变量?
- php - str_ireplace 没有按预期工作
- function - 重启后Powershell功能不起作用?
- opengl - 在 pyBullet 中模拟失真的相机
- pdf - 使用 Ghostscript 将扫描的 PDF 转换为纯文本
- python - 重复的查询行