Directive to upper case input fields
Solution 1
I developed a solution in Angular 7 for uppercase and lowercase, based in some posts i've read. But i tested only for reactive forms. This solution resolve the problem of the last word and the position of the cursor.
// user.component.html
<input type="text" name="name" class="form-control" formControlName="name" uppercase />
// user.component.ts
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[uppercase]',
host: {
'(input)': '$event'
}
})
export class UppercaseInputDirective {
lastValue: string;
constructor(public ref: ElementRef) { }
@HostListener('input', ['$event']) onInput($event)
{
var start = $event.target.selectionStart;
var end = $event.target.selectionEnd;
$event.target.value = $event.target.value.toUpperCase();
$event.target.setSelectionRange(start, end);
$event.preventDefault();
if (!this.lastValue || (this.lastValue && $event.target.value.length > 0 && this.lastValue !== $event.target.value)) {
this.lastValue = this.ref.nativeElement.value = $event.target.value;
// Propagation
const evt = document.createEvent('HTMLEvents');
evt.initEvent('input', false, true);
event.target.dispatchEvent(evt);
}
}
}
I posted here in stackblitz
Solution 2
For reactive form inputs (and also textareas) I got it working just with:
import { Directive, HostListener } from '@angular/core';
import { NgControl } from '@angular/forms';
@Directive({
selector: '[formControlName][inputUppercase]'
})
export class InputUppercaseDirective {
constructor(
private readonly control: NgControl
) { }
@HostListener('input', ['$event.target'])
public onInput(input: HTMLInputElement): void {
const caretPos = input.selectionStart;
this.control.control.setValue(input.value.toUpperCase());
input.setSelectionRange(caretPos, caretPos);
}
}
Solution 3
Basically when you modify the value from imperative code, it becomes difficult manage position of cursor. When you re-write value input value, it throws cursor at the start of input.
I'd recommend you to go for CSS way. More cleaner
[my-attribute] input { text-transform: uppercase; }
Solution 4
Pankaj's idea it's better than create a directive. You only must send data.toUpperCase(). Anyway if you want use a directive like this. Be careful, not only we must use preventDefault(), we must dispatch event change
import { Directive,HostListener } from '@angular/core';
@Directive({
selector: '[appToUpperCase]'
})
export class ToUpperCaseDirective {
constructor() { }
@HostListener('keydown', ['$event']) onKeyDown(event:KeyboardEvent) {
if (event.keyCode>32 && event.keyCode<128)
{
event.target['value']+=event.key.toUpperCase();
event.preventDefault(); //stop propagation
//must create a "input" event, if not, there are no change in your value
var evt = document.createEvent("HTMLEvents");
evt.initEvent("input", false, true);
event.target.dispatchEvent(evt);
}
}
}
Julien AZEMA
Updated on June 14, 2022Comments
-
Julien AZEMA almost 2 years
I want to use a directive to transform all input data to uppercase. To achieve that, I create this custom directive :
@Directive({ selector: '[appToUpperCase]' }) export class ToUpperCaseDirective { constructor() {} @HostListener('input', ['$event']) onKeyUp(event) { event.target['value'] = event.target['value'].toUpperCase(); } }
And I use it like that :
<form [formGroup]="formGroup" appToUpperCase>
It works almost good exept that when I enter text in my field, the upper case transform is permormed but the focus is set at the end of the field...So when I edit a pre filled input, if I want to modify the begining of the data, I have to set the focus at the right place after each Keyup event...
How can I fix that ?