I am with a project in Angular 7. I have several forms and in the fields that are only digits and/or amounts I use this onlyDigits directive ( https://github.com/changhuixu/ngx-digit-only ) and it works very well. As the documentation says when I have an .html that belongs to a module, I use it this way:
In the .module.ts I declare this way:
import { DigitOnlyModule } from '@uiowa/digit-only';
@NgModule({
declarations: [
...
],
imports: [
BrowserModule,
DigitOnlyModule
],
...
})
And in the html form that I need to use it, I do it this way:
<input type="text" digitOnly />
Nothing special and just as the documentation says. The PROBLEM is that I have a couple of forms (modals) that are generic and are not defined as modules so digitOnly doesn't work (it doesn't throw an error or anything... it just doesn't work). This is an example of one of them and where I use digitOnly but it doesn't work for me:
<form class="form" role="form" [formGroup]="form">
<fieldset>
<div class="modal-header">
<span>{{ modalHeader }}</span>
</div>
<div class="modal-body">
<div class=" form-group row">
<label class="col-sm-3 col-form-label">Nim a portar</label>
<div class="col-sm-8">
<div class="form-group row">
<div class="col-sm-4">
<input type="text" digitOnly maxlength="4" class="form-control" placeholder="Prefijo (sin 0)" [formControl]="form.controls['pref']" [ngClass]="{'form-control-danger': form.controls['pref'].hasError('required') && form.controls['pref'].touched}">
</div>
<div class="col-sm-8">
<input type="text" digitOnly maxlength="10" class="form-control" placeholder="Número (sin 15)" [formControl]="form.controls['nim']" [ngClass]="{'form-control-danger': form.controls['nim'].hasError('required') && form.controls['nim'].touched}">
</div>
</div>
<div style="color:red" class="m-1 form-control-feedback" *ngIf="form.controls['pref'].hasError('required') && form.controls['pref'].touched">¡El código de área del Nim a portar es requerido!</div>
<div style="color:red" class="m-1 form-control-feedback" *ngIf="form.controls['pref'].hasError('minlength') && form.controls['pref'].touched">¡El código de área del Nim a portar debe contener al menos 2 dígitos!</div>
<div style="color:red" class="m-1 form-control-feedback" *ngIf="form.controls['pref'].hasError('pattern') && form.controls['pref'].touched">¡El código de área del Nim a portar no tiene el formato correcto!</div>
<div style="color:red" class="m-1 form-control-feedback" *ngIf="form.controls['nim'].hasError('required') && form.controls['nim'].touched">¡El número del Nim a portar es requerido!</div>
<div style="color:red" class="m-1 form-control-feedback" *ngIf="form.controls['nim'].hasError('pattern') && form.controls['nim'].touched">¡El número del Nim a portar no tiene el formato correcto!</div>
<div style="color:red" class="m-1 form-control-feedback" *ngIf="form.hasError('phoneLength')">¡El número del Nim a portar (Cód área + número) no tiene la longitud correcta!</div>
</div>
<button class="col-sm-1 btn btn-edit-claro btn-copy" (click)="copyText(formNim.value.area + formNim.value.num)"><i class="far fa-copy" aria-hidden="true"></i></button>
</div>
<div class=" form-group row">
<label class="col-sm-3 col-form-label">Empresa orig.</label>
<div class="col-sm-9">
<select class="form-control" [formControl]="form.controls['operator']">
<option [value]="null" hidden>Seleccione la empresa de origen </option>
<option [value]="i.id" *ngFor="let i of modalOperators">{{i.name}}</option>
</select>
</div>
</div>
<div class="form-group row">
<label for="market" class="col-sm-3 col-form-label">Mercado orig.</label>
<div class="col-sm-9">
<select class="form-control" [formControl]="form.controls['market']">
<option [value]="null" hidden>Seleccione el mercado origen</option>
<option [value]="i.id" *ngFor="let i of modalMarkets">{{i.name}}</option>
</select>
</div>
</div>
<div class="form-group row with-space left-panel-form">
<div class="col-sm-12 title-form">
<span>Gestión plan nuevo</span>
</div>
<div class="col-sm-12">
<hr>
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Mercado dest.</label>
<div class="col-sm-9">
<select class="form-control" [formControl]="form.controls['markettarget']"
(change)="changeMarketTarget($event.target.value)">
<option [value]="null" hidden>Seleccione el mercado destino </option>
<option [value]="i.id" *ngFor="let i of modalMarkets">{{i.name}}
</option>
</select>
</div>
</div>
<div class="form-group row">
<label for="payment" class="col-sm-3 col-form-label">Abono elegido</label>
<div class="col-sm-9">
<select class="form-control" [formControl]="form.controls['payment']">
<option [value]="null" hidden>Seleccione el abono del plan </option>
<option [value]="i.id" *ngFor="let i of payments">{{i.description}}
</option>
</select>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-md btn-outline-claro" (click)="closeModal()">Cerrar</button>
<button type="button" [disabled]="!form.valid" class="btn btn-claro" (click)="onSaveContinue()">Agregar y
Limpiar</button>
<button type="button" [disabled]="!form.valid" class="btn btn-claro" (click)="onSaveClose()">Agregar y
Cerrar</button>
</div>
</fieldset>
and the .component.ts of said form:
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
import { ErrorMessageService } from '../error-message/error-message.service';
import { AditionalNimVo } from '../../services/vos/AditionalNimVo';
import { WSRESTCatalog } from '../../services/catalog.service';
@Component({
selector: 'ngx-aditionalnim',
templateUrl: './aditional-nim.component.html',
styleUrls: ['../../app.component.scss'],
})
export class AditionalNimComponent implements OnInit {
@Output() passEntry: EventEmitter<any> = new EventEmitter();
form: FormGroup;
modalHeader: string;
modalOperation: number;
modalObject: any;
modalOperators;
modalMarkets;
payments;
constructor(private activeModal: NgbActiveModal,
private fb: FormBuilder,
private catalogService: WSRESTCatalog,
private errorService: ErrorMessageService,
) { }
ngOnInit() {
this.form = this.fb.group({
pref: new FormControl(null, Validators.compose([Validators.required, Validators.minLength(2),
Validators.pattern('^[1-9][0-9]*$')])),
nim: new FormControl(null, Validators.compose([Validators.required, Validators.pattern('^[1-9][0-9]*$')])),
operator: new FormControl(null, Validators.compose([Validators.required])),
market: new FormControl(null, Validators.compose([Validators.required])),
markettarget: new FormControl(null, Validators.compose([Validators.required])),
payment: new FormControl(null, Validators.compose([Validators.required])),
}, { validator: this.checkLenghtTogether });
}
checkLenghtTogether(group: FormGroup): any {
if (group) {
const area = group.get('pref').value;
const num = group.get('nim').value;
if (area && num && (area.length + num.length) !== 10)
return {phoneLength: true};
}
return null;
}
closeModal(): void {
this.activeModal.dismiss();
}
changeMarketTarget(value) {
if (value) {
this.catalogService.getAllActivePayments(value).subscribe(
data => {
this.payments = data['body'];
},
error => {
this.errorService.showError('Aviso Importante',
error['error']['description']);
},
);
}
}
onSaveContinue() {
const aditional = this.fillAditional(
this.form.value.pref,
this.form.value.nim,
this.form.value.operator,
this.form.value.market,
this.form.value.markettarget,
this.form.value.payment);
this.passEntry.emit(aditional);
this.form.reset();
}
onSaveClose() {
const aditional = this.fillAditional(
this.form.value.pref,
this.form.value.nim,
this.form.value.operator,
this.form.value.market,
this.form.value.markettarget,
this.form.value.payment);
this.passEntry.emit(aditional);
this.activeModal.dismiss();
}
private fillAditional(nim: string, phone: string,
operatorid: number, marketid: number, markettargetid: number,
paymentid: number): AditionalNimVo {
const aditional = new AditionalNimVo();
aditional.phone = phone;
aditional.pref = nim;
aditional.operatorid = operatorid;
aditional.operator = this.modalOperators.find(x => Number(x.id) === Number(operatorid))['name'];
aditional.marketid = marketid;
aditional.market = this.modalMarkets.find(x => Number(x.id) === Number(marketid))['name'];
aditional.markettargetid = markettargetid;
aditional.markettarget = this.modalMarkets.find(x => Number(x.id) === Number(markettargetid))['name'];
aditional.paymentid = paymentid;
const pay = this.payments.find(x => Number(x.id) === Number(paymentid));
aditional.payment = pay['description'];
return aditional;
}
}
As I mentioned before, digitOnly doesn't work for me here because I don't have a .module.ts to declare it. I tried declaring it in the app.module.ts but it didn't work either. Someone who can guide me how to use it or who has experienced the same thing with some other directive in this type of form??? Thank you at least for reading it.
In this type of case, since I don't have a .module.ts to declare the digitOnly, I had to solve it in a more "homemade" way and was building a function responding to the html keypress event. I leave you the solution for this in case it helps anyone:
In the html:
And in the .component.ts: