Please help. I'm having trouble creating a directive that will always set text inputs to uppercase. It seems to be working looking at the user interface but the model binding is showing the last typed character to still in lowercase character.
below is a portion of my html:
<div>
<md-input-container fxFlex>
<textarea #listCode mdInput [(ngModel)]="listInfo.code" placeholder="List Code"
uppercase-code maxlength="50" rows="3"
required></textarea>
<md-hint align="end">{{listCode.value.length}} / 50</md-hint>
</md-input-container>
{{listInfo.code}}
</div>
below is the directive:
import { Directive } from '@angular/core';
import { NgControl } from '@angular/forms';
@Directive({
selector: '[ngModel][uppercase-code]',
host: {
'(ngModelChange)': 'ngOnChanges($event)'
}
})
export class UppercaseCodeDirective {
constructor(public model: NgControl) {}
ngOnChanges(event) {
var newVal = event.replace(/[^A-Za-z0-9_]*/g, '');
newVal = newVal.toUpperCase();
this.model.valueAccessor.writeValue(newVal);
}
}
You should be using a directive as below,
@HostListener('keyup') onKeyUp() {
this.el.nativeElement.value = this.el.nativeElement.value.toUpperCase();
}
LIVE DEMO
This question has somehow already been answered on SO, here, although solutions piled up together with framework newer versions.
At least in my experience, there were two useful answers, which on their own did not work, anyway: from Thierry Templier (with first comment as well), and from cal.
I put together parts of both, and came up with this version, which is now working with Angular 4.1.1 in a reactive form:
import { Directive, Renderer, ElementRef, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, DefaultValueAccessor } from '@angular/forms';
const LOWERCASE_INPUT_CONTROL_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => LowerCaseInputDirective),
multi: true,
};
@Directive({
selector: 'input[lowercase]',
host: {
// When the user updates the input
'(input)': 'onInput($event.target.value)',
'(blur)': 'onTouched()',
},
providers: [
LOWERCASE_INPUT_CONTROL_VALUE_ACCESSOR,
],
})
export class LowerCaseInputDirective extends DefaultValueAccessor {
constructor(renderer: Renderer, elementRef: ElementRef) {
super(renderer, elementRef, false);
}
writeValue(value: any): void {
const transformed = this.transformValue(value);
super.writeValue(transformed);
}
onInput(value: any): void {
const transformed = this.transformValue(value);
super.writeValue(transformed);
this.onChange(transformed);
}
private transformValue(value: any): any {
const result = value && typeof value === 'string'
? value.toLowerCase()
: value;
return result;
}
}
This is for lower-case, but everything holds for upper-case as well, just rename directive, replace within selector
and transformValue
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With