London804
London804

Reputation: 1126

How can I reset a group of formControls in Reactive Forms?

I have table with many rows that's generated with a ngFor loop. When the user clicks on a row or group of rows, those rows are pushed into a new array and can be edited one at a time. I want to add reset functionality that allows the user to reset the row back to it's default settings. The problem I'm having is the reset function is resetting the entire table. How can I pass the specific row to the reset method to ONLY reset that specific row?

Below is the relevant code. // HTML

<div
*ngIf="!!modal"
class="modal__mask">
<section
    *ngIf="!!modal"
    class="modal modal__large"
    [formGroup]="tableForm">
    <div class="modal__header modal__header--large">
        <h6>Edit Employee Details</h6>
        <div class='u-flex u-alignCenter'>
            <i
                class="icon icon--medium icon--pointer"
                (click)="previousSelectedRow()">
                arrow_left
            </i>
            <p *ngIf="selectedRows.length > 0">{{modalPage + 1}} of {{selectedRows.length}} employees</p>
            <i
                class="icon icon--medium icon--pointer"
                (click)="nextSelectedRow()">
                arrow_right
            </i>
        </div>
    </div>
    <section>
        <div
            class="u-flex u-wrap"
            *ngFor='let row of selectedRows; let i = index'>
            <div
                class="u-flex modal__body"
                style="width: 50%"
                *ngFor="let column of columns">
                <div
                    *ngIf="column.label"
                    class="input__wrapper"
                    [ngClass]="{'input__wrapper--inline': layout === 'horizontal'}">
                    <div>
                        <label
                            class="input__label">
                            <p class="t-bold t-data">{{column.label}}</p>
                        </label>
                        <div class="z-input__default">
                            <input
                                class="input u-maxX"
                                [attr.type]=""
                                [attr.placeholder]=""
                                [formControlName]="column.key"
                                [value]="row[column.key]">
                        </div>
                    </div>
                </div>
            </div>
           <section class="modal__footer u-fillRemaining">
                <div class="u-flex">
                    <button
                        class="button button--medium"
                        (click)="nextSelectedRow()">
                        <div class="button__content">
                            <i
                                class="icon icon--medium"
                                *ngIf="!!icon">
                                {{icon}}
                            </i>
                            <span>Skip</span>
                        </div>
                    </button>
                </div>
                <div class="u-flex">
                    <button
                        class="button button--low"
                        (click)="reset(row)">
                        <div class="button__content">
                            <i
                                class="icon icon--medium"
                                *ngIf="!!icon">
                                {{icon}}
                            </i>
                            <span>Reset</span>
                        </div>
                    </button>
                    <button class="button button--low">
                        <div class="button__content">
                            <i
                                class="icon icon--medium"
                                *ngIf="!!icon">
                                {{icon}}
                            </i>
                            <span>Save Changes</span>
                        </div>
                    </button>
                </div>
            </section>
        </div>
    </section>

</section>

// TS

ngOnInit() {
    if (!!this.rows) {
        this.tableForm = new FormGroup({});

        this.rows.forEach(row => {
            this.columns.forEach(column => {
                this.tableForm.addControl(column.key, new FormControl(row[column.key]));
            });
        })
    }
}

reset(row) {
    let resetRow = row;
    this.tableForm.reset(resetRow) // this resets the entire table

}

Upvotes: 1

Views: 2198

Answers (1)

Amir Arbabian
Amir Arbabian

Reputation: 3699

Basically now you have your controls going just one after another, so you cannot just distinguish which are related to the particular row, what you can do is to wrap controls of each row into the FormGroup and add this FormGroup into the parent FormArray so index of the row would be its key. Then you can use that index to find FormGroup of needed row to reset it.

In ngOnInit method

this.tableForm = new FormArray([]);

this.rows.forEach((row, i) => {
    const rowGroup = new FormGroup({});

    this.columns.forEach(column => {
        this.rowGroup.addControl(column.key, new FormControl(row[column.key]));
    });
    this.tableForm.push(rowGroup);
})

In html template

...
<section
   *ngIf="!!modal"
   class="modal modal__large"
   [formArray]="tableForm">
...
<div
  class="u-flex u-wrap"
  *ngFor='let row of selectedRows; let i = index'
   [formGroupName]="i">
...
<button
    class="button button--low"
    (click)="reset(i)">
....

reset method

reset(i) {
    this.tableForm.at(i).reset();
}

Hope that helps.

Upvotes: 3

Related Questions