Custom input component

2

Hello, I have a form 'Reactive Forms' where it has several fields, so I decided to create a component and run a ngFor in it to reduce the number of lines ...

Component html

<div *ngFor='let input of inputs' class="input-size-{{input.size}}" >
    <label>{{input.label}}</label>

    <input *ngIf='input.control == "input"' class="{{input.css}}" type="{{input.type}}" />

    <textarea *ngIf='input.control == "textarea"' class="{{input.css}}"></textarea>

    <select *ngIf='input.control == "select"' class="{{input.css}}">
        <option value="">:: Selecione ::</option>
    </select>
</div>

Component TS

/* Angular */
import { Component, Input} from "@angular/core";
import { FormularioModel } from "./vw.formulario.model";

@Component({
    selector: 'vw-input',
    templateUrl: './vw.input.html',
    styleUrls: ['./vw.input.scss']
})

export class VwInput{   
    @Input() inputs: FormularioModel[];
}

Component

export class FormularioModel {
    constructor(
        public control: string, 
        public label: string, 
        public value: any, 
        public formControlName: string, 
        public css: string, 
        public type: string, 
        public size: number){
    }
}

And implement this component as follows ...

html form

<form [formGroup]='formulario' novalidate>
    <!-- Inputs gerados -->
    <!-- IMPLEMENTAÇÃO DO COMPONENT DE INPUT -->
    <vw-input [inputs]='inputs' ></vw-input>

    <!-- Footer -->
    <vw-formulario-footer></vw-formulario-footer>

    <div class="container-button">
        <button>Enviar</button>
    </div>
</form>

TS Form

/* Angular */
import { Component } from "@angular/core";
import { FormGroup, FormBuilder, Validators, AbstractControl, NgControlStatus, FormControl } from '@angular/forms';


import { FormularioModel } from "../../vw.shared/vw.input/vw.formulario.model";

@Component({
    selector: 'vw-formulario',
    templateUrl: './vw.formulario.html',
    styleUrls: ['vw.formulario.scss']
})

export class VwFormulario {

    formulario: FormGroup;
    caracteres_restantes: number;

    inputs: FormularioModel[] = [
        {control:'select', label: 'Motivo', value: '', formControlName: 'motivo', css: 'vw-input', type: 'text', size: 6},
        {control:'select', label: 'Assunto', value: '', formControlName: 'assunto', css: 'vw-input', type: 'text', size: 6},
        {control:'input', label: 'E-mail', value: '', formControlName: 'email', css: 'vw-input', type: 'text', size: 6},
        {control:'input', label: 'Nome', value: '', formControlName: 'nome', css: 'vw-input', type: 'text', size: 6},
        {control:'input', label: 'CPF', value: '', formControlName: 'cpf', css: 'vw-input', type: 'text', size: 6},
        {control:'input', label: 'Data Nascimento', value: '', formControlName: 'dt_nascimento', css: 'vw-input', type: 'text', size: 2},
        {control:'input', label: 'DDD', value: '', formControlName: 'ddd', css: 'vw-input', type: 'text', size: 1},
        {control:'input', label: 'Telefone', value: '', formControlName: 'telefone', css: 'vw-input', type: 'text', size: 3},
        {control:'input', label: 'Endereco', value: '', formControlName: 'endereco', css: 'vw-input', type: 'text', size: 6},
        {control:'input', label: 'Número', value: '', formControlName: 'numero', css: 'vw-input', type: 'text', size: 2},
        {control:'input', label: 'Complemento', value: '', formControlName: 'complemento', css: 'vw-input', type: 'text', size: 2},
        {control:'input', label: 'CEP', value: '', formControlName: 'cep', css: 'vw-input', type: 'text', size: 2},
        {control:'select', label: 'Estado', value: '', formControlName: 'estado', css: 'vw-input', type: 'text', size: 6},
        {control:'select', label: 'Cidade', value: '', formControlName: 'cidade', css: 'vw-input', type: 'text', size: 6},
        {control:'input', label: 'Bairro', value: '', formControlName: 'bairro', css: 'vw-input', type: 'text', size: 6},
        {control:'textarea', label: 'Mensagem', value: '', formControlName: 'mensagem', css: 'vw-input', type: 'text', size: 12}
    ]


    constructor(fb: FormBuilder){
        /* Grupo de formulario - Validações */
        this.formulario = fb.group({
            motivo: new FormControl('', [ Validators.required ]),
            assunto: new FormControl('', [ Validators.required ]),
            email: new FormControl('', [ Validators.required ]),
            nome: new FormControl('', [ Validators.required ]),
            cpf: new FormControl('', [ Validators.required ]),
            dt_nascimento: new FormControl('', [  ]),
            ddd: new FormControl('', [ Validators.required ]),
            telefone: new FormControl('', [ Validators.required ]),
            endereco: new FormControl('', [ Validators.required ]),
            numero: new FormControl('', [ Validators.required ]),
            complemento: new FormControl('', [  ]),
            cep: new FormControl('', [ Validators.required ]),
            estado: new FormControl('', [ Validators.required ]),
            cidade: new FormControl('', [ Validators.required ]),
            bairro: new FormControl('', [ Validators.required ]),
            mensagem: new FormControl('', [ Validators.required ]),
        });
    }
}

However, my formGroup is not associating with the inputs generated by the component. I would like to know how I bridge this to get the values of each input and perform validation by formGroup!

Thank you in advance ....

    
asked by anonymous 27.04.2018 / 19:28

2 answers

0

Assigns in each input the formControlName, which was only passed in the model and not applied to Input. The input was as follows ...

<input *ngIf='input.control == "input"' formControlName='{{input.formControlName}}' class="{{input.css}}" type="{{input.type}}" />

In addition, I passed my formGroup as parameter of the inputs component to the following way:

<vw-input [formGroup]="formulario" [inputs]='inputs' ></vw-input>

Receiving the same in TS from the component as follows:

@Input() formGroup: FormGroup;

And assigning it to one of the following:

<div [formGroup]="formGroup">
    <div *ngFor='let input of inputs' class="input-size-{{input.size}}" >
        <label>{{input.label}}</label>
        
        <input *ngIf='input.control == "input"' formControlName='{{input.formControlName}}' class="{{input.css}}" type="{{input.type}}" />
    </div>
</div>

So getting the desired result ...

    
02.05.2018 / 13:47
0

The formControlName was missing.

<input *ngIf='input.control == "input"' class="{{input.css}}" type="{{input.type}}" formControlName='{{ input.formControlName }}' />
    
02.05.2018 / 13:59