Raj Chauhan
Raj Chauhan

Reputation: 61

How to make a form in html with dynamic formArray

How to make a form in HTML with dynamic FormArray which is generated by selecting the number of multiple file. Each file has its own FormGroup. and when i'm using formControlName and formGroupName it is showing error that

AttachComponent.html:45 ERROR Error: formControlName must be used with a parent formGroup directive. You'll want to add a formGroup directive and pass it an existing FormGroup instance (you can create one in your class).

  Example:


<div [formGroup]="myGroup">
  <input formControlName="firstName">
</div>

In your class:

this.myGroup = new FormGroup({
   firstName: new FormControl()
});
at Function.webpackJsonp.../../../forms/@angular/forms.es5.js.ReactiveErrors.controlParentException (forms.es5.js:4507)
at FormControlName.webpackJsonp.../../../forms/@angular/forms.es5.js.FormControlName._checkParentType (forms.es5.js:5396)
at FormControlName.webpackJsonp.../../../forms/@angular/forms.es5.js.FormControlName._setUpControl (forms.es5.js:5403)
at FormControlName.webpackJsonp.../../../forms/@angular/forms.es5.js.FormControlName.ngOnChanges (forms.es5.js:5322)
at checkAndUpdateDirectiveInline (core.es5.js:10840)
at checkAndUpdateNodeInline (core.es5.js:12341)
at checkAndUpdateNode (core.es5.js:12284)
at debugCheckAndUpdateNode (core.es5.js:13141)
at debugCheckDirectivesFn (core.es5.js:13082)
at Object.eval [as updateDirectives] (AttachComponent.html:49)

i have put my code as well screenshot.

<button class="btn btn-primary pull-right" (click)="file.click()" type="button">Select File</button>
    <input name="file" #file type="file" multiple="multiple" (change)="onSelectDocument($event)" style="display: none;" />

@Input() dataType;
@Input() reasonBO;

// this function will be called on select file

export class UploadAttachData {

    select: boolean;
    documentType: string;
    description: string;
    fileName: string;
    boQueryReason: string;
    boQueryComments: number;
    file: File;
    constructor(obj: any) {
        this.select = obj && obj.select ? obj.select : false;
        this.documentType = obj && obj.documentType ? obj.documentType : '';
        this.description = obj && obj.description ? obj.description : '';
        this.fileName = obj && obj.name ? obj.name : '';
        this.boQueryReason = obj && obj.boQueryReason ? obj.boQueryReason : '';
        this.boQueryComments = obj && obj.boQueryComments ? obj.boQueryComments : '';
        this.file = obj ? obj : null;
    }
}

onSelectDocument(event: any) {
    this.documentData = this.generateFormGroupArray(event);
    debugger
    console.log(this.documentData);
  }

  generateFormGroupArray(event): FormArray {
    const data: FormArray = this.fb.array([]);
    const fileList: FileList = event.target.files;
    if (fileList.length > 0) {
      for (let i = 0; i < fileList.length; i++) {
        data.push(this.generateDocuments(fileList[i]));
       }
       return data;
    }
  }

  generateDocuments(file): FormGroup {
    const uploadData = new UploadAttachData(file);
    return this.fb.group(this.generateDocumentRule(uploadData));
  }

  generateDocumentRule(element: any) {
    const documentRule: any = {};
    documentRule['selected'] = element['selected'];
    documentRule['documentType'] = element['documentType'];
    documentRule['description'] = element['description'];
    documentRule['fileName'] = element['fileName'];
    documentRule['boQueryReason'] = element['boQueryReason'];
    documentRule['boQueryComments'] = element['boQueryComments'];
    documentRule['file'] = element['file'];
    return documentRule;
  }
<div class="profile-value">
    <div class=" col-md-12 col-lg-12 heading-col select-border-b">
        <label class="profile-heading active">
            <i class="icon-bottom-triangle provile-expand-icon"></i>Attach Document</label>
        <button class="btn btn-primary pull-right" disabled="disabled" [disabled]="!enableButtons" (click)="onDeleteAttachedDocuments()"
            type="button">Delete</button>
        <button class="btn btn-primary pull-right" disabled="disabled" [disabled]="!enableButtons" (click)="onUploadAttachedDocuments()"
            type="button">Upload File</button>
        <button class="btn btn-primary pull-right" (click)="file.click()" type="button">Select File</button>
        <input name="file" #file type="file" multiple="multiple" (change)="onSelectDocument($event)" style="display: none;" />
    </div>
    <div class="clearfix"></div>
</div>
<div class="clearfix"></div>
<div class="col-sm-12 col-md-12">
    <table class="table customer-search-table">
        <thead>
            <tr>
                <th style="width: 50px">Select</th>
                <th>Document Type
                    <span class="red-start width-auto pull-left">*</span>
                </th>
                <th>Description
                    <span class="red-start width-auto pull-left">*</span>
                </th>
                <th>File Name/Comments</th>
                <th>BO Query Reason</th>
                <th>BO Query Comments</th>
            </tr>
        </thead>
        <tbody *ngIf="documentData">
            <tr *ngFor="let document of documentData.controls; let i=index;">
                <form>
                    <td class="prod-col mycheckbox">
                        <span class="check">
                            <input type="checkbox" id="document_{{i}}" name="document_{{i}}" (change)="addOrDeleteSelectedRecord(document)">
                            <label for="document_{{i}}">
                                <span></span>
                            </label>
                        </span>
                    </td>
                    <td>
                        <select>
                            <option value="">Select Value</option>
                            <option *ngFor="let data of dataType" [ngValue]="data.key">{{data.value}}</option>
                        </select>
                    </td>
                    <td>
                        <input type="text" class="form-control" formControlName="document.controls['description']">
                    </td>
                    <td> {{document.controls['fileName'].value}} </td>
                    <td>
                        <select style="width: -webkit-fill-available">
                            <option value="">Select Value</option>
                            <option *ngFor="let data of reasonBO" [ngValue]="data.key">{{data.value}}</option>
                        </select>
                    </td>
                    <td>
                        <input type="text" class="form-control"> </td>
                </form>
            </tr>
        </tbody>
    </table>
</div>

class

typescript

Upvotes: 0

Views: 2370

Answers (1)

Raj Chauhan
Raj Chauhan

Reputation: 61

i got the solution i don't need to use formArrayName, formGroupName, formControlName etc and etc

Simply go with the [formControl] i.e.

<tbody *ngIf="documentData">
        <tr *ngFor="let document of documentData.controls; let i=index;">
            <th>
                <span class="check">
                        <input type="checkbox" id="{{i}}" [formControl]="document.controls['selected']">
                        <label for="{{i}}"><span></span></label>
                </span>
            </th>
            <th></th>
            <th><input type="text" class="form-control" [formControl]="document.controls['description']"></th>
            <th>{{document.controls['fileName'].value}}</th>
            <th>5</th>
            <th><input type="text" class="form-control" [formControl]="document.controls['boQueryComments']"></th>
        </tr>
    </tbody>

Upvotes: 2

Related Questions