Visão geral do componente Angular Input Group

    The IgxInputGroupComponent allows the user to enhance input elements like input, select, textarea, etc. This can be achieved by adding custom content like text, icons, buttons, custom validation, floating label, etc., on either side of them, as a prefix, suffix, or hint.

    Angular Input Group Example

    Getting Started with Ignite UI for Angular Input Group

    Para começar a usar o componente Ignite UI for Angular Input Group, primeiro você precisa instalar Ignite UI for Angular. Em um aplicativo Angular existente, digite o seguinte comando:

    ng add igniteui-angular
    

    Para obter uma introdução completa ao Ignite UI for Angular, leia o tópico de introdução.

    O próximo passo é importar issoIgxInputGroupModule no seu arquivo app.module.ts.

    Note that the IgxInputGroupComponent also depends on the Angular FormsModule in order to have a working Template Driven Form:

    // 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,16.0.0 você pode importarIgxInputGroupComponent como uma dependência independente ou usar oIGX_INPUT_GROUP_DIRECTIVES token para importar o componente e todos os seus componentes e diretivas de suporte.

    // 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';
    }
    

    Now that you have the Ignite UI for Angular Input Group module or directives imported, you can start using the igx-input-group component.

    Observação

    To use any of the directives igxInput, igxLabel, igx-prefix, igx-suffix or igx-hint, you have to wrap them in an <igx-input-group> container.

    Using the Angular Input Group

    Label & Input

    You can read about the igxLabel and igxInput directives as well as their validation, data binding and API in a separate topic here.

    Prefix & Suffix

    The igx-prefix or igxPrefix and igx-suffix or igxSuffix directives can contain or be attached to HTML elements, strings, icons or even other components. In the following sample we will create a new input field with a string prefix and an icon suffix:

    <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

    The igx-hint directive provides a helper text placed below the input. It can be at the beginning or at the end of the input depending on the value of the position property. Let's add a hint to our phone input:

    <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>
    

    É assim que o campo de telefone com dica se parece:

    Input Types & Input Group Type Token

    The input group styles can be altered by using the type property of the igxInputGroup component. The input group component supports the following types: line (default if type is not specified), border, box, and search. The line, border, and box types are made specifically for the Material Design themes. Setting those types with other themes will not have any effect on how the input group looks. An example of setting a specific type declaratively:

    <igx-input-group type="border">
    

    Usar o token de injeção IGX_input-group_TYPE permite especificar um tipo em um nível de aplicativo para todas as instâncias de input-group. Ele fornece uma maneira fácil de estilizar todos os componentes relacionados de uma vez. Para definir o tipo, use o token de injeção IGX_input-group_TYPE para criar um provedor DI.

    providers: [{provide: IGX_input-group_TYPE, useValue: 'box' }]
    
    Observação

    The type property has precedence over a IGX_INPUT_GROUP_TYPE, thus a token value can be overridden on a component level if the type property is set explicitly. Most of the igniteui-angular form controls use input-group component internally, or allow for a custom template. Setting a global token will affect these components as well.

    Ignite UI for Angular also provides styling for the input of type="file" and it supports all the input group types and themes, just add this to your template:

    <igx-input-group>
        <input igxInput type="file" multiple />
    </igx-input-group>
    

    Input Group Theme

    The input group component supports several themes - material, fluent, bootstrap, and indigo-design; The theme is automatically set during component initialization and is inferred from the currently used stylesheet. If you plan to support several themes in your application with runtime switching, you can explicitly set the theme using the theme Input property.

    <igx-input-group theme="fluent">...</igx-input-group>
    

    Typed Forms

    O componente Ignite UI for Angular Input Group pode ser usado dentro de formulários reativos estritamente tipados, que são os padrões do Angular 14. Para saber mais sobre os formulários tipados, você pode verificar a documentação oficial Angular.

    Validação

    Os exemplos a seguir demonstram como configurar a validação de entrada ao usar formulários reativos ou baseados em modelo.

    Template-Driven Forms

    Template-driven form validation is achieved by adding validation attributes, i.e., required, minlength, etc., to the input element.

    <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>
    

    The required attribute adds an asterisk next to the label, indicating that this field must be filled in. Furthermore, when the input has additional validation applied to it, such as email and minlength, this could allow the developer to notify the end user for additional requirements via the igx-hint directive.

    The following example uses two-way data binding and demonstrates how to inspect the control's state by exporting the ngModel to a local variable.

    <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>
    

    O usuário não deve conseguir enviar o formulário se algum dos controles de formulário nele for inválido. Isso pode ser feito habilitando/desabilitando o botão de envio com base no estado do formulário.

    The following example demonstrates how to inspect the form's state by exporting the ngForm to a local variable.

    <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>
    

    The result from the above configurations could be seen in the below sample. Start typing into the Email and Password fields and you will notice that the igx-hint is shown if the entered values are invalid. The sample also demonstrates how to toggle the password's visibility by using the igx-icon and the igx-suffix directive.

    Reactive Forms

    A validação reativa de formulário é obtida adicionando funções validadoras diretamente ao modelo de controle de formulário na classe de componente. Após criar o controle na classe de componente, ele deve ser associado a um elemento de controle de formulário no modelo.

    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>
    

    Similar to the template-driven form sample, when having additional validation like email and minlength, an igx-hint directive could be used to notify the end user if the validation has failed.

    The following example demonstrates how to access the control through a get method and inspect its state. It also demonstrates how to enable/disable the submit button by inspecting the state of the 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>
    

    The result from the above configurations could be seen in the below sample. Similar to the template-driven form sample, it also demonstrates how to toggle the password's visibility by using the igx-icon and the igx-suffix directive.

    Custom Validators

    Alguns campos de entrada podem exigir validação personalizada e isso pode ser obtido por meio de validadores personalizados. Quando o valor é inválido, o validador gerará um conjunto de erros que podem ser usados para exibir uma mensagem de erro específica.

    Abaixo está um exemplo de um validador de formulário reativo personalizado simples que valida se o endereço de e-mail inserido contém um valor predefinido e gera erros diferentes com base em onde o valor ocorre.

    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

    In some scenarios, the validation of one control may depend on the value of another one. To evaluate both controls in a single custom validator the validation should be performed in a common ancestor control, i.e., the FormGroup. The validator retrieves the child controls by calling the FormGroup's get method, compares the values and if the validation fails, a set of errors is generated for the FormGroup.

    This will set only the form's state to invalid. To set the control's state, we could use the setErrors method and add the generated errors manually. Then, when the validation is successful, the errors could be removed by using the setValue method that will rerun the control's validation for the provided value.

    O exemplo abaixo demonstra uma validação entre campos onde a Senha não deve conter o Endereço de e-mail e a Repetir senha deve corresponder à Senha.

    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;
        }
    }
    

    To add the custom validator to the FormGroup it should be passed as a second argument when creating the form.

    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()]
        });
    }
    

    The below sample demonstrates how the built-in validators could be used in combination with the custom emailValidator and cross-field passwordValidator from the previous examples.

    Estilização

    The first thing we need to do, in order to get started with the input group styling, is to include the index file in our style file:

    @use "igniteui-angular/theming" as *;
    
    // IMPORTANT: Prior to Ignite UI for Angular version 13 use:
    // @import '~igniteui-angular/lib/core/styles/themes/index';
    

    To customize the appearance of input groups, you can create a new theme by extending the input-group-theme. This approach allows you to override only the parameters you want to change, while the rest are automatically handled by the base theme.

    Mesmo especificando apenas alguns parâmetros principais, como cores para a borda ou plano de fundo, você obterá um grupo de entrada totalmente estilizado com estilos consistentes baseados em estado (foco, foco, etc.) aplicados a você.

    Aqui está um exemplo simples:

    $custom-input-group: input-group-theme(
        $box-background: #57a5cd,
        $border-color: #57a5cd,
    );
    

    O último passo é incluir o tema recém-criado:

    @include css-vars($custom-input-group);
    

    Demo

    Observação

    If your page includes multiple types of input groups — such as box, border, line, or search — it's best to scope your theme variables to the specific input group type.
    For example:
    Use .igx-input-group--box when styling box-style inputs. Use .igx-input-group--search when targeting search inputs. This helps prevent style conflicts between different input types. For instance, setting a dark $box-background globally could cause the borders of border or line inputs to become invisible (usually appearing white).

    Referências de API

    Theming Dependencies

    Recursos adicionais

    Tópicos relacionados:

    Nossa comunidade é ativa e sempre acolhedora para novas ideias.