Validación compartida Angular2+ entre dos campos de entrada
Tengo una tarea interesante (Creo). Necesito una validación de acciones de campo de entrada. El resultado deseado sería que ambos campos sean "técnicamente" requeridos. Sin embargo, si un usuario tipo en su dirección de correo electrónico entonces ambos campos ahora son válidos y viceversa si llenan un número de teléfono. Aquí está mi código abajo.
HTML
TS pertinente
checkValidation(name) {
if (
this.form.controls[name]?.controls?.email?.value ||
this.form.controls[name]?.controls?.phone?.value
) {
this.eitherFieldRequired = false;
}
}
Pregunta hecha hace 3 años, 4 meses, 29 días - Por coderconqueror
3 Respuestas:
-
Puedes hacerlo de dos maneras:
this.myFormGroup({ ... }, formValue => this.myValidator)
this.myFormGroup .get(‘myControl’) .valueChanges .pipe( takeUntil(this.destroyed), // handle the unsubscription tap(value => { if (value) { this.myFormGroup .get(‘myControl’) .setValidators([ ... ]) } else { // unset validators } }), ).subscribe()
Avísame si necesitas más orientación.
Respondida el Dec 17, 2020 a las 01:52 - por techtrailblazer
Votos positivos: 0 | Votos negativos: 0 -
Para lograr la validación compartida entre los campos de entrada de teléfono y correo electrónico en Angular, puedes utilizar una validación personalizada en el formulario. Aquí te muestro cómo puedes hacerlo:
- En tu archivo TypeScript, primero importa ValidatorFn y AbstractControl de @angular/forms para crear la validación personalizada:
typescript import { ValidatorFn, AbstractControl } from '@angular/forms';
- Luego, crea la función de validación personalizada que verificará si alguno de los campos está lleno:
typescript export const requireEitherPhoneOrEmail: ValidatorFn = (control: AbstractControl) => { const phone = control.get('phone'); const email = control.get('email'); if (!phone.value && !email.value) { return { requireEither: true }; } return null; };
- En tu componente de Angular, dentro del formulario, agrega la validación personalizada a nivel de formulario:
typescript import { FormGroup, FormBuilder } from '@angular/forms'; constructor(private fb: FormBuilder) { this.form = this.fb.group({ phone: ['', { minlength: 10 }], email: ['', { pattern: '\\b[\\w.%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}\\b' }] }, { validator: requireEitherPhoneOrEmail }); }
- En tu HTML, elimina los `[required]` de los campos de teléfono y correo electrónico, ya que la validación personalizada se encargará de eso:
html contactphone="ngModel" (change)="checkValidation()" class="form-control" minlength="10" name="phone" ngmodel="" type="text"/>contactemail="ngModel" (change)="checkValidation()" class="form-control" maxlength="100" name="email" ngmodel="" type="text"/>
- Finalmente, modifica tu función `checkValidation()` para que la validación se active en el cambio de cualquier campo y para mostrar u ocultar mensajes de error según el estado de la validación:
typescript checkValidation() { if (this.form.controls.phone.value || this.form.controls.email.value) { this.eitherFieldRequired = false; } else { this.eitherFieldRequired = true; } }
Con estos cambios, tu formulario requerirá que al menos uno de los campos de teléfono o correo electrónico esté lleno para ser válido. ¡Espero que esto te ayude a lograr la validación compartida que deseas en tu formulario!
Respondida el Dec 18, 2020 a las 01:55 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
El código que proporcionaste casi funciona como se describe. El problema es que no actualiza la validez de los campos cuando se borran. Para resolverlo, puedes agregar un escuchador de eventos
ngModelChange
a los campos de entrada y llamar a la funcióncheckValidity
en el métodongModelChange
. Aquí tienes el código actualizado:html contactphone="ngModel" (change)="checkValidity()" (ngModelChange)="checkValidity()" [required]="contactEmail.pristine" class="form-control" minlength="10" name="phone" ngModel type="text"/>
html contactemail="ngModel" (change)="checkValidity()" (ngModelChange)="checkValidity()" [required]="contactPhone.pristine" class="form-control" maxlength="100" name="email" ngModel pattern="\b[\w.%+-A-z0-9.-]+\\@A-z]{2,}\b" type="text"/>
ts checkValidity() { if (this.form.controls[this.fieldName].value) { this.eitherFieldRequired = false; } else if (this.form.controls[this.fieldName].pristine && !this.eitherFieldRequired) { this.eitherFieldRequired = true; } }
Ten en cuenta que he agregado el
fieldName
como parámetro a la funcióncheckValidity
para que se pueda usar con múltiples campos de entrada.Respondida el Dec 18, 2020 a las 01:58 - por Gemini
Votos positivos: 0 | Votos negativos: 0