drag/Drop multiselect

This commit is contained in:
Maximilian Krambach 2019-05-17 14:46:58 +02:00
parent 7e2045aa76
commit bd27951648
3 changed files with 94 additions and 5 deletions

View File

@ -2,18 +2,29 @@
<div class="line" *ngIf="!array.length">
<span translate>No data</span>
</div>
<div class="line" *ngFor="let item of array; let i = index" cdkDrag>
<div class="section-one backgroundColorLight" cdkDragHandle *ngIf="enable">
<div
[ngClass]="isSelectedRow(i) ? 'backgroundColorSelected line' : 'backgroundColorLight line'"
*ngFor="let item of array; let i = index"
cdkDrag
(click)="onItemClick($event, i)"
(cdkDragStarted)="dragStarted(i)"
>
<div class="section-one " cdkDragHandle *ngIf="enable">
<mat-icon>drag_indicator</mat-icon>
</div>
<div class="section-two backgroundColorLight">
<div class="section-two">
<!-- {number}. {item.getTitle()} -->
<span *ngIf="count">{{ i + 1 }}.&nbsp;</span>
<span>{{ item.getTitle() }}</span>
</div>
<div class="section-three backgroundColorLight">
<div class="section-three">
<!-- Extra controls slot using implicit template references -->
<ng-template [ngTemplateOutlet]="templateRef" [ngTemplateOutletContext]="{ $implicit: item }"></ng-template>
</div>
<div class="line" *cdkDragPreview>
<div class="spacer.left-10" *ngIf="multiSelectedIndex.length > 0">
{{ multiSelectedIndex.length }}&nbsp;<span translate>items selected</span>
</div>
</div>
</div>
</div>

View File

@ -36,6 +36,12 @@ export class SortingListComponent implements OnInit, OnDestroy {
*/
public array: Selectable[];
/**
* The index of multiple selected elements. Allows for multiple items to be
* selected and then moved
*/
public multiSelectedIndex: number[] = [];
/**
* Declare the templateRef to coexist between parent in child
*/
@ -143,12 +149,79 @@ export class SortingListComponent implements OnInit, OnDestroy {
}
}
/**
* Handles the start of a dragDrop event and clears multiSelect if the ittem dragged
* is not part of the selected items
*/
public dragStarted(index: number): void {
if (this.multiSelectedIndex.length && !this.multiSelectedIndex.includes(index)) {
this.multiSelectedIndex = [];
}
}
/**
* drop event
* @param event the event
*/
public drop(event: CdkDragDrop<Selectable[]>): void {
moveItemInArray(this.array, event.previousIndex, event.currentIndex);
if (this.multiSelectedIndex.length < 2) {
moveItemInArray(this.array, event.previousIndex, event.currentIndex);
} else {
const before: Selectable[] = [];
const insertions: Selectable[] = [];
const behind: Selectable[] = [];
for (let i = 0; i < this.array.length; i++) {
if (!this.multiSelectedIndex.includes(i)) {
if (i < event.currentIndex) {
before.push(this.array[i]);
} else if (i > event.currentIndex) {
behind.push(this.array[i]);
} else {
event.currentIndex < 1 ? behind.push(this.array[i]) : before.push(this.array[i]);
}
} else {
insertions.push(this.array[i]);
}
}
this.array = [...before, ...insertions, ...behind];
}
this.sortEvent.emit(this.array);
this.multiSelectedIndex = [];
}
/**
* Handles a click on a row. If the control key is clicked, the element is
* added/removed from a multiselect list /(which will be handled on
* dropping)
*
* @param event MouseEvent.
* @param indx The index of the row clicked.
*/
public onItemClick(event: MouseEvent, indx: number): void {
if (event.ctrlKey) {
const ind = this.multiSelectedIndex.findIndex(i => i === indx);
if (ind === -1) {
this.multiSelectedIndex.push(indx);
} else {
this.multiSelectedIndex = this.multiSelectedIndex
.slice(0, ind)
.concat(this.multiSelectedIndex.slice(ind + 1));
}
} else {
// deselect all when clicking on an non-selected item
if (this.multiSelectedIndex.length && !this.multiSelectedIndex.includes(indx)) {
this.multiSelectedIndex = [];
}
}
}
/**
* Checks if the row at the given index is currently selected
*
* @param index
* @returns true if the item is currently selected
*/
public isSelectedRow(index: number): boolean {
return this.multiSelectedIndex.includes(index);
}
}

View File

@ -80,6 +80,11 @@
color: mat-color($accent, default-contrast) !important;
}
.backgroundColorSelected {
background-color: rgba(0, 0, 0, 0.155);
color: mat-color($foreground, text) !important;
}
.backgroundColorLight {
background-color: mat-color($background, hover);
color: mat-color($foreground, text) !important;