web-dev-qa-db-fra.com

Angular 2 Directive pour définir le champ d'entrée en majuscule à l'aide de ngModelChange

S'il vous plaît aider. Je ne parviens pas à créer une directive qui définira toujours les entrées de texte en majuscule. Il semble fonctionner en regardant l'interface utilisateur, mais la liaison de modèle montre le dernier caractère saisi en minuscule.

ci-dessous est une partie de mon code 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>

ci-dessous est la 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);       
  }
}
5
JR S.

Vous devriez utiliser une directive comme ci-dessous,

@HostListener('keyup') onKeyUp() {
      this.el.nativeElement.value = this.el.nativeElement.value.toUpperCase();

    }

LIVE DEMO

7
Aravind

D'une manière ou d'une autre, cette question a déjà reçu une réponse sur SO, ici , bien que les solutions se soient superposées avec des versions plus récentes du cadre.

Au moins dans mon expérience, il y avait deux réponses utiles, qui ne fonctionnaient pas seules, de toute façon: de Thierry Templier (avec le premier commentaire également), et de cal .

J'ai assemblé des parties des deux et j'ai créé cette version, qui fonctionne maintenant avec Angular 4.1.1 sous une forme réactive:

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

Ceci est pour les minuscules, mais tout est valable pour les majuscules également, il suffit de renommer la directive, de remplacer dans selector et transformValue.

1
superjos