UpperCasePipe для ввода в Angular 4
Я хочу использовать верхний регистр для поля ввода без ngModel, также я использую конструктор форм. Любой способ конвертировать все значения формы в верхний регистр.
<form [formGroup]="addTrackForm" (ngSubmit)="addTrack(addTrackForm.value)">
<input type="text" formControlName="name" />
<input type="text" formControlName="adminAdamGroup" class="inputTxt" />
<button type="submit" class="btn btn-primary btn-sm" [disabled]="!addTrackForm.valid">Add</button>
</form>
2 ответа
Решение. Вы можете использовать вход следующим образом
(input)="orderForm.patchValue({name: $event.target.value.toUpperCase()})"
Вам просто нужно установить значение элемента управления, не отправляя событие изменения. Зацикливание на всех значениях формы можно сделать так:
this.form.valueChanges.do(values=>{
Object.keys(values).forEach(k=>{
this.form.get(k).setValue(value.toUpperCase(),{emitEvent:false});
});
}).subscribe();
Вы также можете создать компонент или директиву, которая реализуетControlValueAccessor
и справится с преобразованием.
Я использую декоратор, чтобы пометить тип регистра свойств, и когда значение изменяется для одного из свойств, помеченных как "верхний" или "нижний", а новое значение вводится неправильно, я изменяю регистр, а затем перемещаю курсор на правильная позиция из-за изменения значения FormControl поместит курсор в конец значения.
Это работает для ввода, удаления или вставки текста независимо от позиции или типа дела.
Возможно, его можно преобразовать в директиву, в которую будет передан тип регистра для более элегантного решения.
Следующий код будет проверять каждый FormControl, который связан со свойством, помеченным как "верхний" или "нижний":
import { Component, OnInit, OnDestroy, Renderer2 } from '@angular/core';
import { takeUntil, filter } from 'rxjs/operators';
----
constructor(private _renderer2: Renderer2){}
ngOnInit() {
this.getProperties(this.entity)
.filter(prop => new Array<string>('upper', 'lower')
.includes(this.getPropertyCaseType(this.entity, prop)))
.forEach(prop => {
this.form.controls[prop].valueChanges
.pipe(filter(v => {
if (!v) return false;
let caseType = this.getPropertyCaseType(this.entity, prop);
if (caseType === 'upper') return v !== (<string>v).toUpperCase();
if (caseType === 'lower') return v !== (<string>v).toLowerCase();
return false;
}))
.subscribe(t => {
let oldVal = this.form.value[prop];
let currentVal = <string>t;
this.form.controls[prop].setValue(this.getPropertyCaseType(this.entity, prop) === 'upper' ?
currentVal.toUpperCase() :
currentVal.toLowerCase());
let inputElement = this._renderer2.selectRootElement(`#input_${prop}`);
if (!inputElement || !oldVal) return;
let diff: string = '';
for (let i = 0; i < currentVal.length; i++)
if (currentVal[i] !== oldVal[i - diff.length])
diff = `${diff}${currentVal[i]}`;
let diffPosition = currentVal.lastIndexOf(diff);
inputElement.setSelectionRange(diffPosition + diff.length, diffPosition + diff.length);
});
});
}