Skip to content

Commit cfba963

Browse files
authored
feat: Disable components using directive (#19)
* feat: Disable components using directive * feat: add information about DestroyedDirective + add ElementRef * feat: clean up redundant information
1 parent 1b68d23 commit cfba963

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
title: Disable components using directive
3+
description: "Example of directive to disable interactive components when a certain condition is met."
4+
tags: ["angular", "directives"]
5+
pubDate: Feb 25, 2023
6+
contributedBy: "@pawelkubiakdev"
7+
---
8+
9+
The code snippet below shows how to disable (angular material) components if the shouldDisable$ stream from the ExampleService emits true.
10+
This can be a useful solution when we want to block actions when the user does not have the appropriate permissions resulting from:
11+
- user role
12+
- a feature that is blocked for the user etc.
13+
14+
(*) `DestroyedDirective` was implemented according to the idea of [Kristiyan Kostadinov](https://twitter.com/_crisbeto/status/1582475442715385858).
15+
16+
17+
```typescript
18+
@Directive({
19+
selector: '[disableInteractiveElements]',
20+
standalone: true,
21+
hostDirectives: [DestroyedDirective]
22+
})
23+
export class DisableInteractiveElementsDirective implements OnInit {
24+
private readonly destroyed$ = inject(DestroyedDirective).destroyed$;
25+
26+
constructor(private readonly service: ExampleService,
27+
private readonly elementRef: ElementRef,
28+
@Optional() @Self() private readonly button: MatButton,
29+
@Optional() @Self() private readonly select: MatSelect) {}
30+
31+
ngOnInit(): void {
32+
this.service.shouldDisable$
33+
.pipe(takeUntil(this.destroyed$))
34+
.subscribe((shouldDisable) => {
35+
if (this.button) {
36+
this.button.disabled = shouldDisable;
37+
} else if (this.select) {
38+
this.select.disabled = shouldDisable;
39+
} else if (this.elementRef.nativeElement && ('disabled' in this.elementRef.nativeElement)) {
40+
this.elementRef.nativeElement.disabled = shouldDisable;
41+
}
42+
});
43+
}
44+
}
45+
```
46+
47+
Usage in template:
48+
49+
```html
50+
<button mat-button mat-raised-button>Always available</button>
51+
<button disableInteractiveElements mat-button mat-raised-button>Could be disabled</button>
52+
<mat-select disableInteractiveElements placeholder="Settings">
53+
<mat-option value="'setting1'">Setting 1</mat-option>
54+
<mat-option value="'setting2'">Setting 2</mat-option>
55+
</mat-select>
56+
<input disableInteractiveElements type="text" />
57+
```
58+
59+
In the case shown above, the first button will always be active, while the other elements, i.e. the second button, select and input, will be active if `service.shouldDisable$` emits false.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy