Descripción general del componente del grupo de entrada Angular
IgxInputGroupComponent
permite al usuario mejorar elementos de entrada como entrada, selección, área de texto, etc. Esto se puede lograr agregando contenido personalizado como texto, íconos, botones, validación personalizada, etiqueta flotante, etc., a ambos lados de ellos, como un prefijo, sufijo o sugerencia.
Angular Input Group Example
Getting Started with Ignite UI for Angular Input Group
Para comenzar con el componente Ignite UI for Angular Input Group, primero debe instalar Ignite UI for Angular. En una aplicación Angular existente, escriba el siguiente comando:
ng add igniteui-angular
Para obtener una introducción completa a la Ignite UI for Angular, lea el tema de introducción.
El siguiente paso es importar IgxInputGroupModule
en su archivo app.module.ts.
Tenga en cuenta que IgxInputGroupComponent
también depende de Angular FormsModule para tener un formulario basado en plantilla que funcione:
// app.module.ts
import { FormsModule } from '@angular/forms';
import { IgxInputGroupModule } from 'igniteui-angular';
// import { IgxInputGroupModule } from '@infragistics/igniteui-angular'; for licensed package
@NgModule({
...
imports: [..., IgxInputGroupModule, FormsModule],
...
})
export class AppModule {}
Alternativamente, a partir de 16.0.0
, puede importar IgxInputGroupComponent
como una dependencia independiente o usar el token IGX_INPUT_GROUP_DIRECTIVES
para importar el componente y todos sus componentes y directivas de soporte.
// home.component.ts
import { FormsModule } from '@angular/forms';
import { IGX_INPUT_GROUP_DIRECTIVES, IgxIconComponent } from 'igniteui-angular';
// import { IGX_INPUT_GROUP_DIRECTIVES, IgxIconComponent } from '@infragistics/igniteui-angular'; for licensed package
@Component({
selector: 'app-home',
template: `
<igx-input-group>
<igx-prefix>+359</igx-prefix>
<label igxLabel for="phone">Phone</label>
<input igxInput [(ngModel)]="value" name="phone" type="tel" maxlength="9" />
<igx-icon igxSuffix>phone</igx-icon>
</igx-input-group>
`,
styleUrls: ['home.component.scss'],
standalone: true,
imports: [IGX_INPUT_GROUP_DIRECTIVES, IgxIconComponent, FormsModule]
/* or imports: [IgxInputGroupComponent, IgxPrefixDirective, IgxLabelDirective, IgxInputDirective, IgxIconComponent, IgxSuffixDirective, FormsModule] */
})
export class HomeComponent {
public value = '123456789';
}
Ahora que ha importado la Ignite UI for Angular, puede comenzar a usar el componente igx-input-group
.
Note
Para utilizar cualquiera de las directivas igxInput
, igxLabel
, igx-prefix
, igx-suffix
o igx-hint
, debe envolverlas en un contenedor <igx-input-group>
.
Using the Angular Input Group
Label & Input
Puede leer sobre las directivas igxLabel
e igxInput
, así como su validación, enlace de datos y API en un tema separado aquí.
Prefix & Suffix
Las directivas igx-prefix
o igxPrefix
y igx-suffix
o igxSuffix
pueden contener o estar adjuntas a elementos HTML, cadenas, iconos o incluso otros componentes. En el siguiente ejemplo crearemos un nuevo campo de entrada con un prefijo de cadena y un sufijo de icono:
<igx-input-group>
<igx-prefix>+359</igx-prefix>
<label igxLabel for="phone">Phone</label>
<input igxInput name="phone" type="tel" maxlength="9" />
<igx-icon igxSuffix>phone</igx-icon>
</igx-input-group>
Hints
La directiva igx-hint
proporciona un texto de ayuda colocado debajo de la entrada. Puede estar al principio o al final de la entrada según el valor de la propiedad position
. Agreguemos una pista a la entrada de nuestro teléfono:
<igx-input-group>
<igx-prefix>+359</igx-prefix>
<label igxLabel for="phone">Phone</label>
<input igxInput name="phone" type="tel" />
<igx-suffix>
<igx-icon>phone</igx-icon>
</igx-suffix>
<igx-hint position="start">Ex.: +359 888 123 456</igx-hint>
</igx-input-group>
Así es como se ve el campo del teléfono con sugerencia:
Input Types & Input Group Type Token
Los estilos del grupo de entrada se pueden modificar utilizando la propiedad type
del componente igxInputGroup
. El componente del grupo de entrada admite los siguientes tipos: line
(predeterminada si no se especifica el tipo), border
, box
y search
. Los tipos de line
, border
y box
están diseñados específicamente para los temas Material Design
. Configurar esos tipos con otros temas no tendrá ningún efecto en el aspecto del grupo de entrada. Un ejemplo de configuración de un tipo específico de forma declarativa:
<igx-input-group type="border">
El uso del token de inyección IGX_input-group_TYPE permite especificar un tipo en un nivel de aplicación para todas las instancias del grupo de entrada. Proporciona una manera fácil de diseñar todos los componentes relacionados a la vez. Para configurar el tipo, use el token de inyección IGX_input-group_TYPE para crear un proveedor DI.
providers: [{provide: IGX_input-group_TYPE, useValue: 'box' }]
Note
La propiedad type
tiene prioridad sobre IGX_INPUT_GROUP_TYPE, por lo que un valor de token se puede anular a nivel de componente si la propiedad de tipo se establece explícitamente. La mayoría de los controles de formulario igniteui-angular
utilizan componentes de grupo de entrada internamente o permiten una plantilla personalizada. Establecer un token global también afectará a estos componentes.
Ignite UI for Angular también proporciona estilo para la entrada de type="file"
y admite todos los tipos y temas de grupos de entrada, simplemente agregue esto a su plantilla:
<igx-input-group>
<input igxInput type="file" multiple />
</igx-input-group>
Input Group Theme
El componente del grupo de entrada admite varios temas: material
, fluent
, bootstrap
e indigo-design
; El theme
se configura automáticamente durante la inicialización del componente y se deduce de la hoja de estilo utilizada actualmente. Si planea admitir varios temas en su aplicación con cambio de tiempo de ejecución, puede configurar explícitamente el tema usando la propiedad Entrada theme
.
<igx-input-group theme="fluent">...</igx-input-group>
Typed Forms
El componente Ignite UI for Angular Input Group se puede usar dentro de formularios reactivos estrictamente tipados, que son los predeterminados a partir de Angular 14. Para obtener más información sobre los formularios tipificados, puede consultar la documentación oficial Angular.
Validación
Los siguientes ejemplos demuestran cómo configurar la validación de entrada cuando se utilizan formularios reactivos o basados en plantillas.
Template-Driven Forms
La validación de formularios basada en plantillas se logra agregando atributos de validación, es decir, required
, minlength
, etc., al elemento input
.
<form>
<igx-input-group>
<label igxLabel for="username">Username</label>
<input igxInput name="username" type="text" required />
</igx-input-group>
<igx-input-group>
<label igxLabel for="email">Email</label>
<input igxInput name="email" type="email" required email />
</igx-input-group>
<igx-input-group>
<label igxLabel for="password">Password</label>
<input igxInput name="password" type="password" required minlength="8" />
</igx-input-group>
<button igxButton="contained" igxRipple type="submit">Submit</button>
</form>
El atributo required
agrega un asterisco junto a la etiqueta, lo que indica que este campo debe completarse. Además, cuando a la input
se le aplica una validación adicional, como email
y minlength
, esto podría permitir al desarrollador notificar al usuario final para obtener información adicional. requisitos a través de la directiva igx-hint
.
El siguiente ejemplo utiliza enlace de datos bidireccional y demuestra cómo inspeccionar el estado del control exportando ngModel
a una variable local.
<form #login="ngForm">
...
<igx-input-group>
<label igxLabel for="email">Email</label>
<input igxInput name="email" type="email" [(ngModel)]="user.email" #email="ngModel" required email />
<igx-hint *ngIf="email.errors?.email">Please enter a valid email</igx-hint>
</igx-input-group>
<igx-input-group>
<label igxLabel for="password">Password</label>
<input igxInput name="password" type="password"
[(ngModel)]="user.password" #password="ngModel" required minlength="8" />
<igx-hint *ngIf="password.errors?.minlength">Password should be at least 8 characters</igx-hint>
</igx-input-group>
<button igxButton="contained" igxRipple type="submit">Submit</button>
</form>
El usuario no debería poder enviar el formulario si alguno de los controles del mismo no es válido. Esto podría lograrse habilitando/deshabilitando el botón de envío según el estado del formulario.
El siguiente ejemplo demuestra cómo inspeccionar el estado del formulario exportando ngForm
a una variable local.
<form #registrationForm="ngForm">
<igx-input-group>
<label igxLabel for="email">Email</label>
<input igxInput name="email" type="email" [(ngModel)]="user.email" #email="ngModel" required email />
<igx-hint *ngIf="email.errors?.email">Please enter a valid email</igx-hint>
</igx-input-group>
...
<button igxButton="contained" igxRipple type="submit" [disabled]="!registrationForm.valid">Submit</button>
</form>
El resultado de las configuraciones anteriores se puede ver en el siguiente ejemplo. Comience a escribir en los campos Correo electrónico y Contraseña y notará que se muestra la igx-hint
si los valores ingresados no son válidos. El ejemplo también demuestra cómo alternar la visibilidad de la contraseña utilizando las directivas igx-icon
y igx-suffix
.
Reactive Forms
La validación de formulario reactiva se logra agregando funciones de validación directamente al modelo de control de formulario en la clase de componente. Después de crear el control en la clase de componente, se debe asociar con un elemento de control de formulario en la plantilla.
public registrationForm: FormGroup<User>;
constructor(fb: FormBuilder) {
this.registrationForm = fb.group({
username: ['', { nonNullable: true, validators: [Validators.required] }],
email: ['', { nonNullable: true, validators: [Validators.required, Validators.email] }],
password: ['', { nonNullable: true, validators: [Validators.required, Validators.minLength(8)] }]
});
}
<form [formGroup]="registrationForm">
<igx-input-group>
<label igxLabel for="username">Username</label>
<input igxInput name="username" type="text" formControlName="username" />
</igx-input-group>
<igx-input-group>
<label igxLabel for="email">Email</label>
<input igxInput name="email" type="email" formControlName="email" />
</igx-input-group>
<igx-input-group>
<label igxLabel for="password">Password</label>
<input igxInput name="password" type="password" formControlName="password" />
</igx-input-group>
<button igxButton="contained" igxRipple type="submit">Submit</button>
</form>
De manera similar al ejemplo de formulario basado en plantilla, cuando se tiene validación adicional como email
y minlength
, se podría usar una directiva igx-hint
para notificar al usuario final si la validación falló.
El siguiente ejemplo demuestra cómo acceder al control mediante un método get
e inspeccionar su estado. También demuestra cómo habilitar/deshabilitar el botón de envío inspeccionando el estado de FormGroup
.
public get email() {
return this.registrationForm.get('email');
}
public get password() {
return this.registrationForm.get('password');
}
<form [formGroup]="registrationForm">
...
<igx-input-group>
<label igxLabel for="email">Email</label>
<input igxInput name="email" type="email" formControlName="email" />
<igx-hint *ngIf="email.errors?.email">Please enter a valid email</igx-hint>
</igx-input-group>
<igx-input-group>
<label igxLabel for="password">Password</label>
<input igxInput name="password" type="password" formControlName="password" />
<igx-hint *ngIf="password.errors?.minlength">Password should be at least 8 characters</igx-hint>
</igx-input-group>
<button igxButton="contained" igxRipple type="submit" [disabled]="!registrationForm.valid">Submit</button>
</form>
El resultado de las configuraciones anteriores se puede ver en el siguiente ejemplo. De manera similar al ejemplo de formulario basado en plantilla, también demuestra cómo alternar la visibilidad de la contraseña usando el igx-icon
y la directiva igx-suffix
.
Custom Validators
Algunos campos de entrada pueden requerir una validación personalizada y esto se puede lograr mediante validadores personalizados. Cuando el valor no es válido, el validador generará un conjunto de errores que podrían usarse para mostrar un mensaje de error específico.
A continuación se muestra un ejemplo de un validador de formulario reactivo personalizado simple que valida si la dirección de correo electrónico ingresada contiene un valor predefinido y genera diferentes errores según dónde ocurre el valor.
public registrationForm: FormGroup<User>;
constructor(fb: FormBuilder) {
this.registrationForm = fb.group({
email: ['', {
nonNullable: true,
validators: [
Validators.required,
Validators.email,
this.emailValidator('infragistics')
]
}],
...
});
}
private emailValidator(val: string): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const value = control.value?.toLowerCase();
const localPartRegex = new RegExp(`(?<=(${val})).*[@]`);
const domainRegex = new RegExp(`(?<=[@])(?=.*(${val}))`);
const returnObj: ValidatorErrors = {};
if (value && localPartRegex.test(value)) {
returnObj.localPart = true;
}
if (value && domainRegex.test(value)) {
returnObj.domain = true;
}
return returnObj;
}
}
Cross-Field Validation
En algunos escenarios, la validación de un control puede depender del valor de otro. Para evaluar ambos controles en un único validador personalizado, la validación debe realizarse en un control ancestro común, es decir, FormGroup
. El validador recupera los controles secundarios llamando al método get
de FormGroup
, compara los valores y, si la validación falla, se genera un conjunto de errores para FormGroup
.
Esto establecerá sólo el estado del formulario como no válido. Para establecer el estado del control, podríamos usar el método setErrors
y agregar los errores generados manualmente. Luego, cuando la validación sea exitosa, los errores podrían eliminarse utilizando el método setValue
que volverá a ejecutar la validación del control para el valor proporcionado.
El siguiente ejemplo demuestra una validación entre campos donde la Contraseña no debe contener la dirección de correo electrónico y la Contraseña repetida debe coincidir con la Contraseña.
private passwordValidator(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const email = control.get('email');
const password = control.get('password');
const repeatPassword = control.get('repeatPassword');
const returnObj: ValidatorErrors = {};
if (email.value
&& password.value
&& password.value.toLowerCase().includes(email.value)) {
password.setErrors({ ...password.errors, containsEmail: true });
returnObj.containsEmail = true;
}
if (password
&& repeatPassword
&& password.value !== repeatPassword.value) {
repeatPassword.setErrors({ ...repeatPassword.errors, mismatch: true });
returnObj.mismatch = true;
}
if (!returnObj.containsEmail && password.errors?.containsEmail) {
password.setValue(password.value);
}
if (!returnObj.mismatch && repeatPassword.errors?.mismatch) {
repeatPassword.setValue(repeatPassword.value);
}
return returnObj;
}
}
Para agregar el validador personalizado al FormGroup
, se debe pasar como segundo argumento al crear el formulario.
public registrationForm: FormGroup<User>;
constructor(fb: FormBuilder) {
this.registrationForm = fb.group({
email: ['', {
nonNullable: true,
validators: [
Validators.required,
Validators.email,
this.emailValidator('infragistics')
]
}],
...
},
{
validators: [this.passwordValidator()]
});
}
El siguiente ejemplo demuestra cómo se pueden usar los validadores integrados en combinación con el emailValidator
personalizado y passwordValidator
campos cruzados de los ejemplos anteriores.
Estilismo
Lo primero que debemos hacer para comenzar con el estilo del grupo de entrada es incluir el archivo index
en nuestro archivo de estilo:
@use "igniteui-angular/theming" as *;
// IMPORTANT: Prior to Ignite UI for Angular version 13 use:
// @import '~igniteui-angular/lib/core/styles/themes/index';
A continuación, tenemos que crear un nuevo tema que extienda el input-group-theme
y pasar los parámetros que nos gustaría cambiar:
$custom-input-group: input-group-theme(
$filled-text-color: #288a54,
$focused-text-color: #174f30,
$idle-text-color: #288a54,
$idle-bottom-line-color: #288a54,
$interim-bottom-line-color: #288a54,
$hover-bottom-line-color: #288a54,
$focused-secondary-color: #174f30,
$box-background: #eeeeee
);
Using CSS variables
El último paso es incluir el tema recién creado:
@include css-vars($custom-input-group);
Using Theme Overrides
Para diseñar componentes para navegadores más antiguos, como Internet Explorer 11, tenemos que usar el grupo de entrada mixin, ya que no admite variables CSS.
Sin embargo, si simplemente dejamos la instrucción de inclusión, como se muestra en el paso anterior, nuestros estilos no se aplicarán correctamente: aunque el color del texto haya cambiado correctamente, el borde inferior y el fondo seguirán siendo los mismos. Esto se debe a que nuestro componente utiliza Emulated
ViewEncapsulation. Los elementos input
y label
son parte de esa vista, por lo que sus estilos se aplican correctamente. El borde inferior, por otro lado, lo genera el componente igx-input-group
y no se ve afectado por los estilos de nuestro componente.
Para darle estilo al borde, tenemos que penetrate
esta encapsulación usando::ng-deep
. Para evitar que el tema personalizado se filtre a otros componentes, también debemos asegurarnos de que aplicamos el alcance de los estilos con un selector:host
antes de::ng-deep
:
:host {
::ng-deep {
@include input-group($custom-input-group);
}
}
Demo
API References
- DirectivaIgxInput
- Directiva IgxHint
- Tipos de grupos de entrada Igx
- Componente IgxInputGroup
- Estilos de componentes IgxInputGroup
Theming Dependencies
Additional Resources
Temas relacionados:
Nuestra comunidad es activa y siempre da la bienvenida a nuevas ideas.