4.8 KiB
utils-positive-integer-input
An Angular directive that ensures only positive integers can be entered into number input fields.
Features
- ✅ Blocks invalid characters during keyboard input (
.,,,-,+,e,E) - ✅ Sanitizes pasted content to extract only positive integers
- ✅ Handles all input methods (typing, paste, drag & drop)
- ✅ Removes leading zeros automatically
- ✅ Works seamlessly with Angular forms (
ngModel,formControl) - ✅ Standalone directive - easy to import
Installation
The directive is available through the @isa/utils/positive-integer-input package.
Usage
Basic Usage
Simply add the positiveIntegerInput directive to any <input type="number"> element:
<input type="number" positiveIntegerInput />
With Angular Forms
<!-- With ngModel -->
<input
type="number"
positiveIntegerInput
[(ngModel)]="points"
placeholder="Enter points"
/>
<!-- With Reactive Forms -->
<input
type="number"
positiveIntegerInput
[formControl]="pointsControl"
placeholder="Enter points"
/>
Complete Example
import { Component, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { PositiveIntegerInputDirective } from '@isa/utils/positive-integer-input';
@Component({
selector: 'app-booking',
standalone: true,
imports: [FormsModule, PositiveIntegerInputDirective],
template: `
<input
type="number"
positiveIntegerInput
[(ngModel)]="points"
placeholder="Punkte"
min="1"
step="1"
/>
<p>Entered points: {{ points() ?? 'None' }}</p>
`,
})
export class BookingComponent {
points = signal<number | undefined>(undefined);
}
How It Works
The directive implements three protection layers:
1. Keyboard Input Protection (keydown)
Blocks invalid keys before they can be entered:
- Blocked:
.,,,-,+,e,E - Allowed:
0-9, navigation keys (arrow keys, backspace, delete, tab)
2. Paste Protection (paste)
Intercepts paste operations and sanitizes the content:
- Extracts only digits from pasted text
- Removes leading zeros
- Updates the input value with the sanitized result
3. General Input Protection (input)
Catches all other input methods (drag & drop, autofill, programmatic changes):
- Validates and sanitizes any value changes
- Ensures consistency across all input methods
Examples
✅ What Works
| User Action | Input Attempt | Result in Field | Explanation |
|---|---|---|---|
| Typing | 123 |
123 |
Valid positive integer |
| Typing | 1-2-3 |
123 |
Minus signs blocked during typing |
| Typing | 1.5 |
15 |
Decimal point blocked, only digits entered |
| Paste | -100 |
100 |
Negative sign removed |
| Paste | 1.000 |
1000 |
Decimal point removed |
| Paste | 1,58 |
158 |
Comma removed |
| Paste | +42 |
42 |
Plus sign removed |
| Paste | 3.14e2 |
314 |
Scientific notation sanitized |
| Paste | 00123 |
123 |
Leading zeros removed |
| Paste | abc123xyz |
123 |
Non-digit characters removed |
| Typing | 007 |
7 |
Leading zeros removed |
❌ What Doesn't Work (By Design)
| User Action | Input Attempt | Result | Explanation |
|---|---|---|---|
| Typing/Paste | -50 |
50 |
Negative numbers converted to positive |
| Typing/Paste | 12.34 |
1234 |
Decimals removed (not rounded) |
| Typing/Paste | 0 |
`` (empty) | Single zero removed (use min="0" if needed) |
| Paste | abc |
`` (empty) | No digits to extract |
| Paste | --- |
`` (empty) | No digits to extract |
Important Notes
Zero Handling
The directive removes leading zeros, which means a single 0 input will result in an empty field. If you need to allow zero as a valid value, consider:
<!-- Add min="0" and handle empty state in your component -->
<input
type="number"
positiveIntegerInput
[(ngModel)]="points"
min="0"
/>
Decimal Numbers
This directive is not suitable for decimal number inputs. Pasted decimals like 1.58 become 158, not 1 or 2. For decimal inputs, use a different validation approach.
Form Validation
The directive sanitizes input but doesn't perform validation. Combine it with Angular form validators:
import { Validators } from '@angular/forms';
// In your component
pointsControl = new FormControl(null, [
Validators.required,
Validators.min(1),
Validators.max(1000)
]);
Browser Compatibility
The directive uses standard browser APIs and works in all modern browsers:
- Chrome/Edge (Chromium-based)
- Firefox
- Safari
- Mobile browsers (iOS Safari, Chrome Mobile)
Running Unit Tests
Run nx test utils-positive-integer-input to execute the unit tests.