I have a table in which I need to render database values and then after user changes I need to submit that form. Here is demo
There I need to apply like, if status is 'eliminated' or 'absent' then need to disable rank dropdown and rank will be null/0.
I am able to render details and tried on change of status to disable rank but it not working.
Please help and guide. Thanks.
Ts
import { Component } from '@angular/core';
import {
AbstractControl,
FormArray,
FormBuilder,
FormControl,
FormGroup,
Validators,
} from '@angular/forms';
import { merge } from 'rxjs';
import { takeWhile, tap } from 'rxjs/operators';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name = 'Angular';
myForm!: FormGroup;
rankArray = [];
rankStatusArray: any = [
{ id: 'participated', name: 'Participated' },
{ id: 'eliminated', name: 'Eliminated' },
{ id: 'absent', name: 'Absent' },
];
checklist = [
{
id: 13,
rank: 3,
horse_id: 86,
horse_name: 'test232 fdfgdg',
life_number: null,
country: 'Afghanistan',
result_status: 'participated',
comment: 'my comment',
},
{
id: 12,
rank: null,
horse_id: 87,
horse_name: 'test horse',
life_number: '234234',
country: 'Algeria',
result_status: null,
comment: null,
},
{
id: 11,
rank: null,
horse_id: 88,
horse_name: 'tesdfs',
life_number: null,
country: 'Afghanistan',
result_status: null,
comment: null,
},
{
id: 10,
rank: null,
horse_id: 94,
horse_name: 'nam horse',
life_number: 'fh345',
country: 'India',
result_status: null,
comment: null,
},
];
constructor(private fb: FormBuilder) {
this.myForm = this.fb.group({
checklist: this.fb.array([]),
});
this.populate();
}
ngOnInit(): void {
this.rankArray = Array(4)
.fill(1)
.map((x, i) => i 1);
}
get formChecklist() {
return this.myForm.get('checklist') as FormArray;
}
populate() {
this.checklist.forEach((x) => {
this.formChecklist.push(
this.fb.group({
participantId: x.id,
rankStatus: x.result_status,
rank: x.rank,
comment: x.comment,
horse_name: x.horse_name,
country: x.country,
life_number: x.life_number,
})
);
});
}
onChange(event) {
console.log(event);
if (event == 'eliminated' || event == 'absent') {
this.myForm.controls['rank'].disable();
} else {
this.myForm.controls['rank'].enable();
}
}
onSubmit() {
console.log(this.myForm.value);
}
}
HTML
<div >
<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
<table
>
<thead>
<tr>
<th width="150" colspan="6">Competition Name</th>
</tr>
</thead>
<tbody formArrayName="checklist">
<tr >
<td>Status</td>
<td>Rank</td>
<td>Participant Name</td>
<td>Country</td>
<td>Life Number</td>
<td>Comment</td>
</tr>
<tr
*ngFor="let item of formChecklist.controls; let i = index"
[formGroupName]="i"
>
<td>
<div >
<select
formControlName="rankStatus"
(ngModelChange)="onChange($event)"
>
<option [ngValue]="null">Select</option>
<option
*ngFor="let status of rankStatusArray"
[ngValue]="status.id"
>
{{ status.name }}
</option>
</select>
</div>
</td>
<td>
<div >
<select formControlName="rank">
<option value="null">Select</option>
<option *ngFor="let rankno of rankArray" [value]="rankno">
{{ rankno }}
</option>
</select>
</div>
</td>
<td>{{ item.get('horse_name').value }}</td>
<td>
{{ item.get('country').value }}
</td>
<td>
{{ item.get('life_number').value }}
</td>
<td>
<div >
<textarea
type="text"
formControlName="comment"
></textarea>
</div>
</td>
</tr>
</tbody>
</table>
<button >Add Result</button>
</form>
</div>
<pre>{{ myForm.value | json }}</pre>
CodePudding user response:
You're enumerating a ton of points and since this is not a free code provider app, I won't be solving them all until, at least, you try to do something.
This being said, I created a demo that solves the first problem I see you tried and couldn't finish. You weren't able to disable the rank field because:
- first, the event you're passing in the onchange function is not what you want. You need the event's value and even then, you need to extract the information that's important to you, the id.
- second, you were trying to disable/enable something that didn't exist. The console was giving you errors about it. this.myForm.controls['rank'] is undefined.
Regarding step n.4, you might need to be listening to the rank formcontrol and hide the chosen options from the next competitor's rank dropdown. Hope this gives you a hint to tackle the problem.