Skip to content

Commit b511083

Browse files
committed
feat(multisort): add selection service
1 parent 694a729 commit b511083

File tree

3 files changed

+88
-4
lines changed

3 files changed

+88
-4
lines changed

projects/ng-sortgrid/src/lib/ng-sortgrid-item.directive.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1-
import {AfterViewInit, Directive, ElementRef, HostListener, Input, NgZone} from '@angular/core';
1+
import {AfterViewInit, Directive, ElementRef, HostListener, Input, NgZone, OnInit} from '@angular/core';
22
import {SortService} from './sort.service';
3+
import {SelectionService} from './selection.service';
34

45
@Directive({
56
selector: '[ngSortgridItem]'
67
})
7-
export class NgSortgridItemDirective implements AfterViewInit {
8+
export class NgSortgridItemDirective implements OnInit, AfterViewInit {
89

910
@Input('ngSortgridItem')
1011
private ngSortGridItemKey: string;
12+
private selected: boolean;
1113

12-
constructor(public el: ElementRef, public zone: NgZone, private sortService: SortService) {
14+
private readonly SELECTED_CLASS = 'selected';
15+
16+
constructor(public el: ElementRef, public zone: NgZone, private sortService: SortService, private selectionService: SelectionService) {
17+
}
18+
19+
ngOnInit(): void {
20+
this.selected = false;
1321
}
1422

1523
ngAfterViewInit(): void {
@@ -38,4 +46,12 @@ export class NgSortgridItemDirective implements AfterViewInit {
3846
drop(event): void {
3947
console.log('Drop', event);
4048
}
49+
50+
@HostListener('click', ['$event'])
51+
clicked(event): void {
52+
const element = event.target;
53+
this.selected = !this.selected;
54+
this.selected ? element.classList.add(this.SELECTED_CLASS) : element.classList.remove(this.SELECTED_CLASS);
55+
this.selectionService.updateSelectedDragItem(element, this.selected);
56+
}
4157
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import {Injectable} from '@angular/core';
2+
import {fromEvent, merge, NEVER, Observable, Subject} from 'rxjs';
3+
import {filter, mapTo, switchMap} from 'rxjs/operators';
4+
5+
enum ChangeAction {
6+
ADD,
7+
REMOVE
8+
}
9+
10+
interface SelectionChange {
11+
item: Node;
12+
action: ChangeAction;
13+
}
14+
15+
@Injectable({
16+
providedIn: 'root'
17+
})
18+
export class SelectionService {
19+
20+
private COMMAND_KEY = 'Meta';
21+
private CONTROL_KEY = 'Control';
22+
23+
private selectionChange$ = new Subject<SelectionChange>();
24+
private selectedElements: Node[] = [];
25+
26+
constructor() {
27+
const selectionKeyPressed$ = this.selectionKeyPressed();
28+
selectionKeyPressed$.pipe(
29+
switchMap((pressed) => pressed ? this.selectionChange$ : NEVER)
30+
).subscribe((selectionChange: SelectionChange) => this.handleSelectionChange(selectionChange));
31+
}
32+
33+
private handleSelectionChange(selectionChange: SelectionChange): void {
34+
if (selectionChange.action === ChangeAction.ADD) {
35+
this.selectedElements.push(selectionChange.item);
36+
}
37+
if (selectionChange.action === ChangeAction.REMOVE) {
38+
this.selectedElements = this.selectedElements.filter(
39+
(element: Node) => element !== selectionChange.item
40+
);
41+
}
42+
}
43+
44+
private selectionKeyPressed(): Observable<boolean> {
45+
const selectionKeyPressed = fromEvent(window, 'keydown').pipe(
46+
filter((keyboardEvent: KeyboardEvent) => keyboardEvent.key === this.COMMAND_KEY || keyboardEvent.key === this.CONTROL_KEY),
47+
mapTo(true)
48+
);
49+
const keyup = fromEvent(window, 'keyup').pipe(mapTo(false));
50+
return merge(selectionKeyPressed, keyup);
51+
}
52+
53+
public updateSelectedDragItem(item: Node, selected: boolean): void {
54+
this.selectionChange$.next({
55+
item, action: selected ? ChangeAction.ADD : ChangeAction.REMOVE
56+
});
57+
}
58+
59+
public getSelectedElements(): Node[] {
60+
return this.selectedElements;
61+
}
62+
}

projects/ng-sortgrid/src/lib/sort.service.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {Injectable} from '@angular/core';
2+
import {SelectionService} from './selection.service';
23

34
@Injectable({
45
providedIn: 'root'
@@ -8,9 +9,14 @@ export class SortService {
89
private dragIndex: number;
910
private dragElements: Node[];
1011

12+
constructor(private selectionService: SelectionService) {
13+
}
14+
1115
public startDrag(dragItem: Node): void {
16+
console.log('Im drag start');
1217
this.dragIndex = this.indexOf(dragItem.parentNode.children, dragItem);
13-
this.dragElements = [dragItem];
18+
const slectedElements = this.selectionService.getSelectedElements();
19+
this.dragElements = slectedElements.length > 0 ? slectedElements : [dragItem];
1420
}
1521

1622
public sort(dropElement: Node): void {

0 commit comments

Comments
 (0)