form validation not working with select2 (touched, dirty, ...)
Hi Romaric Babatundé
you can loop through the Select2 elements and trigger the update dynamically.
Create a utility function to update Select2 elements based on the form values:
function updateSelect2Elements(formValues: any) {
for (const key in formValues) {
if (formValues.hasOwnProperty(key)) {
const value = formValues[key];
const selectElement = $(`#${key}Select`);
if (selectElement.length > 0) {
selectElement.val(value).trigger("change");
}
}
}
}
// Patch the form values
this.entityForm.patchValue({
civilite: entity.civilite,
// Add other form values here
});
// Call the utility function to update Select2 elements
updateSelect2Elements(this.entityForm.value);
Hi Faizal,
Thank you very much for your interesting feedback.
I followed everything you suggested. But the current problem is that without the name attribute on the select, nothing is displayed after the patchvalue. We therefore have a conflict between name and formcontrolname when both are on the same select.
Also without the attribute, there is no change in the value of select2 after modification.
What to do ?
Hi Romaric Babatundé
May I know which library are you using for "pathValue"?
Or do you want to do something like this?
this.entityForm.patchValue({ civilite: entity.civilite });
// Trigger Select2 update
$("#civiliteSelect").val(entity.civilite).trigger("change");
Hello Faizal
Thank you for your quick response.
I use the default library (AbstractControl).
Now if I have to do as you say, that means that if I have more than 20 selects on my form, I have to make the call more than 20 times
$("#civiliteSelect").val(entity.civilite).trigger("change")
Hi Romaric Babatundé
It might be because Select2 does not trigger Angular's change detection automatically when the value changes.
constructor(private fb: FormBuilder, private cdr: ChangeDetectorRef) {}
ngOnInit(): void {
this.form = this.fb.group({
civilite: [null, Validators.required],
});
}
ngAfterViewInit(): void {
const $select2 = $(".select2");
$select2.select2();
// Update form control value on Select2 change
$select2.on("change", (event: any) => {
const value = $(event.target).val();
this.form.controls["civilite"].setValue(value);
this.cdr.detectChanges(); // Manually trigger change detection
});
}
Hello Faizal,
Thanks a lot for your answer.
it works but how can I exploit the patchvalue to display the value in the select with select2.
The patchvalue no longer works with select2.
Typescript Code :
this.entityForm.patchValue({civilite: entity.civilite});
Hi Romaric Babatundé
The problem might be due to Select2 not properly updating the Angular form control state. You can manually trigger Angular's change detection when the Select2 value changes.
TypeScript Code:
import { ChangeDetectorRef } from "@angular/core";
// Inject ChangeDetectorRef in your component"s constructor
constructor(private cdr: ChangeDetectorRef) {}
ngAfterViewInit() {
var $select2 = $(".select2");
$select2.select2();
// Trigger Angular"s change detection on change event
$select2.on("change", () => {
this.cdr.detectChanges();
});
}
<!--begin::Select-->
<select class="form-select form-select-sm mb-2 select2" formControlName="civilite"
[ngClass]="{"is-invalid": submitted && f.civilite.errors}">
<option disabled value="null">Sélectionnez une civilité...</option>
<option value="M.">M.</option>
<option value="Mme.">Mme.</option>
<option value="Mlle.">Mlle.</option>
</select>
<!--end::Select-->
<div *ngIf="submitted && f.civilite.errors" class="invalid-feedback">
<div *ngIf="f.civilite.errors.required">Ce champ est obligatoire</div>
</div>
Hi Faizal,
Thanks for your answer.
The problem now is that it no longer saves the value of the select when submitting.
form: FormGroup;
ngOnInit(): void {
this.form = this.fb.group({
civilite: [null, Validators.required],
});
}
Hi Romaric Babatundé
Could you please provide a snippet of your code where you're using Select2 in your Angular project? Could you clarify whether you're using the ng-select2 library or the Select2 JavaScript plugin directly in your Angular application? This information will help us provide you with a more specific solution.
Hi Faizal
I'm using Select2 JavaScript plugin directly.
Typescript Code Source :
var $select2 = $(".select2");
$select2.select2();
<!--begin::Select-->
<select class="form-select form-select-sm mb-2 select2" formControlName="civilite"
[ngClass]="{ "is-invalid": submitted && f.civilite.errors }" >
<option disabled value="null">Sélectionnez une civilité...</option>
<option value="M.">M.</option>
<option value="Mme.">Mme.</option>
<option value="Mlle.">Mlle.</option>
</select>
<!--end::Select-->
<div *ngIf="submitted && f.civilite.errors" class="invalid-feedback">
<div *ngIf="f.civilite.errors.required">Ce champs est obligatoire</div>
</div>