File
Description
via Keeping It Simple: Implementing Edit-in-Place in Angular
https://netbasal.com/keeping-it-simple-implementing-edit-in-place-in-angular-4fd92c4dfc70
Modified & Adapted to our needs
Implements
Index
Properties
|
|
Methods
|
|
Outputs
|
|
HostListeners
|
|
Accessors
|
|
HostListeners
keyup.enter
|
keyup.enter()
|
|
Methods
onEnter
|
onEnter()
|
Decorators :
@HostListener('keyup.enter')
|
|
|
editMode
|
Default value : new Subject<boolean>()
|
|
editMode$
|
Default value : this.editMode.asObservable()
|
|
mode
|
Type : "view" | "edit"
|
Default value : 'view'
|
|
Accessors
currentView
|
getcurrentView()
|
|
import {
Component,
ContentChild,
DestroyRef,
ElementRef,
EventEmitter,
HostListener,
OnInit,
Output,
inject
} from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { Subject, fromEvent } from 'rxjs';
import { filter, switchMapTo, take } from 'rxjs/operators';
import { EditModeDirective } from './edit-mode.directive';
import { ViewModeDirective } from './view-mode.directive';
/**
* via Keeping It Simple: Implementing Edit-in-Place in Angular
* https://netbasal.com/keeping-it-simple-implementing-edit-in-place-in-angular-4fd92c4dfc70
*
* Modified & Adapted to our needs
*/
@Component({
selector: 'acl-editable',
template: ` <ng-container *ngTemplateOutlet="currentView"></ng-container> `,
styles: [
`
:host {
width: 100%;
}
`
],
standalone: false
})
export class EditableComponent implements OnInit {
@Output() editComplete = new EventEmitter<void>();
@Output() editStart = new EventEmitter();
@ContentChild(ViewModeDirective) viewModeTpl!: ViewModeDirective;
@ContentChild(EditModeDirective) editModeTpl!: EditModeDirective;
mode: 'view' | 'edit' = 'view';
editMode = new Subject<boolean>();
editMode$ = this.editMode.asObservable();
private destroyRef = inject(DestroyRef);
constructor(private host: ElementRef) {}
get currentView() {
return this.mode === 'view' ? this.viewModeTpl.tpl : this.editModeTpl.tpl;
}
ngOnInit() {
this.viewModeHandler();
this.editModeHandler();
}
private get parentElement() {
return this.host.nativeElement.parentElement;
}
private viewModeHandler() {
fromEvent(this.parentElement, 'dblclick')
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.toEditMode();
});
}
private editModeHandler() {
const clickOutside$ = fromEvent(document, 'click').pipe(
filter(({ target }) => this.parentElement.contains(target) === false),
take(1)
);
this.editMode$
.pipe(switchMapTo(clickOutside$), takeUntilDestroyed(this.destroyRef))
.subscribe(() => {
this.editComplete.next();
this.mode = 'view';
});
}
toEditMode() {
this.mode = 'edit';
this.editMode.next(true);
this.editStart.emit();
}
toViewMode() {
this.mode = 'view';
this.editComplete.next();
}
@HostListener('keyup.enter')
onEnter() {
this.toViewMode();
}
}
Legend
Html element with directive