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

    Theming Dependencies

    Additional Resources

    Temas relacionados:

    Nuestra comunidad es activa y siempre da la bienvenida a nuevas ideas.