Issue
I have a form looking like this when everything is checked:
I want it to look like this when the user changes the brand to something else:
The values available in the second dropdown list depend on the chosen value in the first dropdown list, the colored boxes are actually radio buttons and they are determined by the previous selection.
I am currently able to select a ‘Toyota Furious FT18DV blue’ and have the form not be validated until all the values are checked but when I change the selected value in the first or second dropdown list the form doesn’t ‘forget’ the values selected in the later input controls and validates while the combination shouldn’t be possible to choose.
How can I unselect the outdated values in the later controls and have it ‘reset’ the validation?
@Component({
selector: 'app-car-chooser',
templateUrl: './car-chooser.component.html',
styleUrls: ['./car-chooser.component.css']
})
export class CarChooserComponent {
cars: Car[];
brands: string[];
formBuilder: FormBuilder = new FormBuilder();
colors: string[];
carChooserForm: FormGroup;
car: string[] = undefined;
brandToModelsPipe: BrandToModelsPipe = new BrandToModelsPipe();
brandModelToColorsPipe: BrandModelToColorsPipe = new BrandModelToColorsPipe(); //
constructor(enumPipe: EnumToArrayPipe) {
this.generateCars(10);
this.brands = enumPipe.transform(Brand).map(b => Brand[b]);
this.colors = enumPipe.transform(Color);
this.carChooserForm = this.formBuilder.group({
brand: ['', Validators.required],
model: ['', Validators.required],
color: ['', Validators.required]
});
}
onSubmit(customerData): void {
this.carChooserForm.clearValidators();
this.carChooserForm.reset();
console.warn(customerData);
this.car = customerData;
}
}
.colorBox {
all: unset;
display: inline-block;
width: 20px;
height: 20px;
margin: 5px;
border: 1px solid rgba(0, 0, 0, .2);
}
<div id="zad5">
<form [formGroup]="carChooserForm" (ngSubmit)="onSubmit(carChooserForm.value)">
<label>
Choose the brand:
<select formControlName="brand">
<option *ngFor="let brand of brands" [value]="brand">{{brand}}</option>
</select>
</label>
<br>
<label>
Choose the model:
<select formControlName="model">
<option *ngFor="let brandModel of carChooserForm.controls['brand'].value | brandToModels : cars"
[value]="brandModel">
{{brandModel[1]}}
</option>
</select>
</label>
<br>
<label>
<div>
Choose the color:
</div>
<input *ngFor="let ourcolor of (carChooserForm.controls['model'].value | brandModelToColors : cars)"
class="colorBox" formControlName="color" name="color" [value]="ourcolor" type="radio"
[style]="'background-color:' + ourcolor">
</label>
<br>
<button type="submit" [disabled]="!carChooserForm.valid">Submit</button>
</form>
<app-car-item *ngIf="car !== undefined" [car]="car">asdsa</app-car-item>
</div>
Solution
You can respond to value changes on fields by subscribing to the valueChanges
event on the field and then doing what you need to do, for example, if you want to simply reset the value of the second control whenever the first control changes, you can do something similar to:
this.carChooserForm = this.formBuilder.group({
brand: ['', Validators.required],
model: ['', Validators.required],
color: ['', Validators.required]
});
const brandCtrl = this.carChooserForm.get("brand");
const modelCtrl = this.carChooserForm.get("model");
brandCtrl.valueChanges.subscribe(val => {
modelCtrl.setValue(null);
});
Here is a working demo