web-dev-qa-db-ja.com

angular4アプリケーションでの入力の最小値と最大値

フォーム付きのangular4アプリケーションがあります。これには、パーセンテージを入力する入力があります。そこで、0〜100の値で入力をブロックしたいと思います。min="0"max="100"を追加しようとしましたが、100より大きいか0より小さい数値を入力できます。

テンプレート

<md-input-container>
  <input type="number" 
    maxlength="3" 
    min="0" 
    max="100" 
    required 
    mdInput 
    placeholder="Charge" 
    [(ngModel)]="rateInput" 
    name="rateInput">
  <md-error>Required field</md-error>
</md-input-container>

私がこれをどうやってできるか知っていますか?

25
Adrien

フォームコントロールを使用して成功しました。これは私のhtmlコードです:

    <md-input-container>
        <input type="number" min="0" max="100" required mdInput placeholder="Charge" [(ngModel)]="rateInput" name="rateInput" [formControl]="rateControl">
        <md-error>Please enter a value between 0 and 100</md-error>
    </md-input-container>

そして、私のTypeScriptコードには、

        this.rateControl = new FormControl("", [Validators.max(100), Validators.min(0)])

したがって、100より大きい値または0より小さい値を入力すると、マテリアルデザインの入力は赤になり、フィールドは検証されません。そのため、値が適切でない場合、保存ボタンをクリックしても保存されません。

34
Adrien

実際にtype = "number"を使用すると、入力コントロールに上/下矢印が入力されて数値が増減します。そのため、これらのボタンでテキストボックスの値を更新すると、制限を通過しません) of 1butあなたがmanuallyを120/130などのように入力すると、max limitに対して検証されないなので、コードで検証する必要があります。

手動入力を無効にできますOR valueChange/textChange/key *イベントにコードを記述する必要があります。

これが解決策です:

これは一種のハックですが、うまくいきます

<input type="number" 
placeholder="Charge" 
[(ngModel)]="rateInput" 
name="rateInput"
pattern="^$|^([0-9]|[1-9][0-9]|[1][0][0])?"
required 
#rateInput2 = "ngModel">

<div *ngIf="rateInput2.errors && (rateInput2.dirty || rateInput2.touched)"
    <div [hidden]="!rateInput2.errors.pattern">
        Number should be between 0 and 100
    </div>
</div>

plunker へのリンクはこちらです。

6
Vivek Doshi

入力で変更イベントをリッスンするディレクティブを記述し、値が低すぎる場合は値を最小値にリセットできます。 StackBlitz

@HostListener('change') onChange() {
  const min = +this.elementRef.nativeElement.getAttribute('min');

  if (this.valueIsLessThanMin(min, +this.elementRef.nativeElement.value)) {
    this.renderer2.setProperty(
      this.elementRef.nativeElement,
      'value',
      min + ''
    );
  }
}

また、ngModelChangeイベントをリッスンして、フォームの値が設定されているときに同じことを行います。

@HostListener('ngModelChange', ['$event'])
onModelChange(value: number) {
  const min = +this.elementRef.nativeElement.getAttribute('min');
  if (this.valueIsLessThanMin(min, value)) {
    const formControl = this.formControlName
      ? this.formControlName.control
      : this.formControlDirective.control;

    if (formControl) {
      if (formControl.updateOn === 'change') {
        console.warn(
          `minValueDirective: form control ${this.formControlName.name} is set to update on change
          this can cause issues with min update values.`
        );
      }
      formControl.reset(min);
    }
  }
}

完全なコード:

import {
  Directive,
  ElementRef,
  HostListener,
  Optional,
  Renderer2,
  Self
} from "@angular/core";
import { FormControlDirective, FormControlName } from "@angular/forms";

@Directive({
  // tslint:disable-next-line: directive-selector
  selector: "input[minValue][min][type=number]"
})
export class MinValueDirective {
  @HostListener("change") onChange() {
    const min = +this.elementRef.nativeElement.getAttribute("min");

    if (this.valueIsLessThanMin(min, +this.elementRef.nativeElement.value)) {
      this.renderer2.setProperty(
        this.elementRef.nativeElement,
        "value",
        min + ""
      );
    }
  }

  // if input is a form control validate on model change
  @HostListener("ngModelChange", ["$event"])
  onModelChange(value: number) {
    const min = +this.elementRef.nativeElement.getAttribute("min");
    if (this.valueIsLessThanMin(min, value)) {
      const formControl = this.formControlName
        ? this.formControlName.control
        : this.formControlDirective.control;

      if (formControl) {
        if (formControl.updateOn === "change") {
          console.warn(
            `minValueDirective: form control ${
              this.formControlName.name
            } is set to update on change
              this can cause issues with min update values.`
          );
        }
        formControl.reset(min);
      }
    }
  }

  constructor(
    private elementRef: ElementRef<HTMLInputElement>,
    private renderer2: Renderer2,
    @Optional() @Self() private formControlName: FormControlName,
    @Optional() @Self() private formControlDirective: FormControlDirective
  ) {}

  private valueIsLessThanMin(min: any, value: number): boolean {
    return typeof min === "number" && value && value < min;
  }
}

フォームコントロールをupdateOnblurに設定してこれを使用してください。そうしないと、最初の桁が最小値を下回っている場合、ユーザーは+1桁の数字を入力できません。

 this.formGroup = this.formBuilder.group({
    test: [
      null,
      {
        updateOn: 'blur',
        validators: [Validators.min(5)]
      }
    ]
  });
0
JayChase

(onkeypress)を追加するだけで、angular2 +でこれを実行します

<input type="number" 
    maxlength="3" 
    min="0" 
    max="100" 
    required 
    mdInput 
    placeholder="Charge" 
    [(ngModel)]="rateInput"
    (onkeypress)="return (event.charCode == 8 || event.charCode == 0) ? null : event.charCode >= 48 && event.charCode <= 57"
    name="rateInput">

Angular 7でテスト

0
Ian Samz