html5 angular angular2-template angular2-forms

html5 - Cómo convertir el valor de entrada a mayúsculas en angular 2(valor que pasa a ngControl)



input uppercase angular 6 (8)

Al menos en mi experiencia, encontré dos de las respuestas aquí perspicaces, pero no funcionan por sí mismas: de Thierry Templier (con el primer comentario también) y de cal .

Reuní partes de ambos y se me ocurrió esta versión, que ahora funciona con Angular 4.1.1 en forma reactiva:

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; } }

Esto es para minúsculas, pero todo vale para mayúsculas también, solo cambie el nombre de la directiva, reemplace dentro del selector y transformValue .

Editar:
Un ejemplo de uso directo del código HTML que usa dicha directiva:

<input id="myField" formControlName="myField" type="text" class="form-control required" lowercase>

Estoy intentando validar los campos de entrada usando el valor de ngControl en angular 2. Necesito validar que el usuario ingrese el valor en mayúsculas siempre.

Ahora necesitamos convertir el valor ingresado por el usuario a mayúsculas. Pero estoy manejando valores de campos de entrada usando ngControl, no ngModel (considerando que podría haber usado el evento ngModelChange para actualizar el valor a mayúsculas).

Entonces, ¿cuál es la forma mejor y de bajo costo para convertir el valor utilizado por ngControl.


Aquí está mi código de trabajo que estoy usando angular4

Esta es su directiva para mayúsculas

import { Directive, ElementRef, HostListener } from ''@angular/core''; @Directive({ selector: ''[appUpper]'' }) export class UpperDirective { constructor(public ref: ElementRef) { } @HostListener(''input'', [''$event'']) onInput(event) { this.ref.nativeElement.value = event.target.value.toUpperCase(); } }

Este es su código de archivo html donde utilizó la directiva en mayúsculas

<input type="text" id="id" placeholder="id" tabindex="0" formControlName="id" appUpper>


Aquí está mi solución más genérica que es básicamente como DefaultValueAccessor con una función de "transformador" de texto agregada. Entonces usarías

<input mdInput [transformer]="uppercase" ...>

En su componente, tiene la función de mayúsculas (podría hacer otras cosas además de mayúsculas como implementar una máscara) ...

uppercase(value: string) { return value.toUpperCase(); }

Directiva...

import { NG_VALUE_ACCESSOR, ControlValueAccessor } from ''@angular/forms''; import { Directive, forwardRef, Input, OnChanges, SimpleChanges, Renderer, ElementRef } from ''@angular/core''; import { TextMaskModule, MaskedInputDirective } from ''angular2-text-mask''; @Directive({ selector: ''input[transformer]'', // When the user updates the input host: { ''(input)'': ''handleInput($event.target.value)'', ''(blur)'': ''onTouched()'' }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TextTransformerDirective), multi: true }, ] }) export class TextTransformerDirective implements ControlValueAccessor { private inputElement: HTMLInputElement lastValue = ""; onTouched = () => { } onChange = (_: any) => { } @Input(''transformer'') transformer = (v: string) => v; constructor(private renderer: Renderer, private element: ElementRef) { } handleInput(value: any) { let newVal = this.transformer(value); if (newVal != value || this.lastValue != newVal) { this.lastValue = newVal; this.renderer.setElementProperty(this.element.nativeElement, ''value'', newVal); this.onChange(newVal); } } writeValue(value: any) { let normalizedValue = value == null ? '''' : value; normalizedValue = this.transformer(normalizedValue); this.renderer.setElementProperty(this.element.nativeElement, ''value'', normalizedValue); } registerOnChange(fn: (value: any) => any): void { this.onChange = fn } registerOnTouched(fn: () => any): void { this.onTouched = fn } }


Aquí está mi solución:

Usar el escucha del host para escuchar el evento de entrada y luego forzarlo a mayúsculas.

import {Directive, EventEmitter, HostListener, Output} from ''@angular/core''; @Directive({ selector: ''[ngModel][uppercase]'' }) export class UppercaseDirective { @Output() ngModelChange: EventEmitter<any> = new EventEmitter(); value: any; @HostListener(''input'', [''$event'']) onInputChange($event) { this.value = $event.target.value.toUpperCase(); this.ngModelChange.emit(this.value); } }

Con esta directiva, puede forzar fácilmente la entrada a mayúsculas de esta manera:

<input type="text" class="form-control" placeholder="ID" formControlName="id" [(ngModel)]="form.value.id" uppercase/>


Como sugirió @Eric Martinez, puede crear una variable de plantilla local y vincular la cadena en mayúscula a la propiedad de valor en el evento de entrada:

<input type="text" #input (input)="input.value=$event.target.value.toUpperCase()" />

Alternativamente, puede hacer de esto una directiva:

@Directive({ selector: ''input[type=text]'', host: { ''(input)'': ''ref.nativeElement.value=$event.target.value.toUpperCase()'', } }) export class UpperCaseText { constructor(private ref: ElementRef) { } }

Para usar la directiva, especifique UpperCaseText en la lista de directivas de su componente:

directives: [UpperCaseText]

Demo Plnkr


Crearía una implementación personalizada de ControlValueAccessor. Este último correspondería a una directiva que escucharía el evento de entrada del host. De esta forma, podrá poner en mayúscula lo que llena el usuario. El control contendrá automáticamente el valor en mayúsculas.

Aquí está la implementación:

@Directive ({ selector: ''input[uppercase]'', // When the user updates the input host: { ''(input)'': ''onChange($event.target.value.toUpperCase())'' } }) export class UppercaseValueAccessor extends DefaultValueAccessor { (...) // When the code updates the value of the // property bound to the input writeValue(value:any):void { if (value!=null) { super.writeValue(value.toUpperCase()); } } }

No olvide registrar este descriptor de acceso de valor personalizado en los proveedores de directivas. De esta forma, se utilizará su descriptor de valor personalizado en lugar del predeterminado.

const UPPERCASE_VALUE_ACCESSOR = new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => UppercaseValueAccessor), multi: true}); @Directive ({ providers: [ UPPERCASE_VALUE_ACCESSOR ], (...) }) export class UppercaseValueAccessor ...

Y agregue la directiva en el atributo directivas del componente donde desea usar este enfoque.

Vea esta clase para más detalles:

Este enlace podría dar sugerencias adicionales (consulte la sección "Componente compatible con NgModel):


ha proporcionado una gran solución, pero no funciona en la última versión de Angular (v4.3.1) ya que las directivas se deprecian del componente. Mi solución se basa solo en su respuesta, pero funciona con la última

Estoy proporcionando una solución genérica con una directiva de atributo personalizado con una entrada booleana que convertirá la entrada a mayúsculas si es cierta.

upper-case.directive.ts:

import { Directive, ElementRef, Input } from ''@angular/core''; @Directive({ selector: ''[UpperCase]'', host: { ''(input)'': ''toUpperCase($event.target.value)'', } }) export class UpperCaseTextDirective { @Input(''UpperCase'') allowUpperCase: boolean; constructor(private ref: ElementRef) { } toUpperCase(value: any) { if (this.allowUpperCase) this.ref.nativeElement.value = value.toUpperCase(); } }

Aquí está el componente de aplicación correspondiente con la plantilla.

app.ts

//our root app component import {Component, NgModule, VERSION} from ''@angular/core'' import {BrowserModule} from ''@angular/platform-browser'' import {UpperCaseTextDirective} from ''./upper-case.directive'' @Component({ selector: ''my-app'', template: ` <div> <h2>Hello {{name}}</h2> Auto Capitalize True: <input [UpperCase]="true" type="text" #input /> <br/> Auto Capitalize False: <input [UpperCase]="allowEdit" type="text"/> </div> `, }) export class App { name:string; allowEdit:boolean; constructor() { this.name = `Angular! v${VERSION.full}`; this.allowEdit= false; } } @NgModule({ imports: [ BrowserModule ], declarations: [ App,UpperCaseTextDirective ], bootstrap: [ App ] }) export class AppModule {}

Aquí hay un Plnkr que demuestra esto.


Código simple sin directivas

En el evento de desenfoque de su texto de entrada, llame a un método que cambia el valor a mayúsculas, el mío se llama "cambiaUpper"

<input id="shortsel" type="text" class="form-control m-b-12" #shortsel="ngModel" name="shortsel" [(ngModel)]="_stockprod.shortName" (blur)="cambiaUpper($event)"/>

Y en el componente (yourComponentFile.ts) cree este método que recibe el evento, obtenga el valor del evento y cámbielo a mayúsculas.

public cambiaUpper(event: any) { event.target.value = event.target.value.toUpperCase(); }

Tada!