Closed acadianaapps closed 1 year ago
Hello. Is your sub form in an invalid state while you notice this? Without checking, I think the value isn't broadcasted up if the form is invalid so that may be it
@maxime1992 I'm wondering if it may be related to #93
This image shows that subForm is valid, but the engine hours remain null.
But if I was to do as mention in the #93 issue and just type 0 the blur out then updates the group
I tried the suggestions in the previous issue but didn't help. adding the [data.issue-93] to the html template.
Also just FYI have refactored the component to this utilizing the "formGroupOptions" of "createForm":
import { Component } from '@angular/core';
import { AbstractControl, FormControl, ValidationErrors, ValidatorFn, Validators } from '@angular/forms';
import { createForm, FormType, subformComponentProviders } from 'ngx-sub-form';
import { MaintanenceDetails } from 'src/app/log/models/log.model';
@Component({
selector: 'maintanence-details-control',
templateUrl: './maintanence-details.component.html',
styleUrls: ['./maintanence-details.component.css'],
providers: subformComponentProviders(MaintanenceDetailsControl)
})
export class MaintanenceDetailsControl {
collectiveInHoursCantBeLessThanOutHours(_collectiveOut, _collectiveIn): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const collectiveOut = control.get(_collectiveOut);
const collectiveIn = control.get(_collectiveIn);
const collectiveHourCalc = collectiveIn?.value - collectiveOut?.value;
control.get('collectiveHours').setValue(Number(collectiveHourCalc) > 0 ? collectiveHourCalc.toFixed(2) : null, { onlySelf: true });
return collectiveIn && collectiveOut && collectiveOut?.value > collectiveIn?.value ? { collectiveInHoursLessThanOut: true } : null;
};
}
engineInHoursCantBeLessThanOutHours: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
const engineOut = control.get('engineOut');
const engineIn = control.get('engineIn');
const engineHours = control.get('engineHours');
const engineHourCalc = engineIn?.value - engineOut?.value;
engineHours.setValue(engineHourCalc > 0 ? engineHourCalc.toFixed(2) : null, { onlySelf: true });
return engineIn && engineOut && engineOut?.value > engineIn?.value ? { engineInHoursLessThanOut: true } : null;
};
collectiveHoursCantBeMoreThanEngineHours: ValidatorFn = (control: AbstractControl): ValidationErrors | null => {
const engineHours = control.get('engineHours');
const collectiveHours = control.get('collectiveHours');
return engineHours && collectiveHours && (engineHours?.value < collectiveHours?.value) ? { collectiveHoursMoreThanEngine: true } : null
};
public form = createForm<MaintanenceDetails>(this, {
formType: FormType.SUB,
formGroupOptions: {
updateOn: 'blur',
validators: [
this.collectiveInHoursCantBeLessThanOutHours('collectiveOut', 'collectiveIn'),
this.engineInHoursCantBeLessThanOutHours,
this.collectiveHoursCantBeMoreThanEngineHours,
]
},
formControls: {
collectiveOut: new FormControl(null, Validators.required),
collectiveIn: new FormControl(null, Validators.required),
collectiveHours: new FormControl(null, Validators.required),
engineOut: new FormControl(null, Validators.required),
engineIn: new FormControl(null, Validators.required),
engineHours: new FormControl(null, Validators.required),
},
})
}
Can you please try to build a minimal repro on Stackblitz. Just necessary fields etc to keep it as simple as possible
Hopefully this helps
Ok so thanks for the repro! That said, it's definitely not a minimal repro. A minimal repro consist of trying to create a dead simple repro with only the strict minimum to help pin point the issue by making a work upstream of removing everything that's not needed in the demo. There's load of context in yours.
I've still taken a look. I suspect, it might come from the fact that you're computing a field in the form and updating it through a validator. That really sounds like where the issue might be and it seems completely unrelated to ngx sub form.
I'd strongly encourage you to have computed values outside of the form if possible and otherwise as a first step not update the value in the validator.
I'll have to close this issue as it's not ngx sub form related and I don't have much more time to investigate. Try out the above and otherwise ask on stackoverflow I reckon.
If you do ask on stackoverflow, I'd strongly encourage you to just create one simple form, no ngx-sub-form at all, pure angular. And try to reproduce this with only the needed fields and minimal amount of code needed. If you manage to do that you'll probably get some help on SO :)
If it happens to be ngx sub form related feel free to reopen though!
@maxime1992 Thanks for your time and great library.
This doesn't seem to be a direct ngx-sub-form issue, but I'm struggling with figuring out why the form isn't broadcasting a last key stroke change.
1st would the following code be the correct ngx-sub-form way to add a custom validator to the group itself?
(not sure it matters but the root form of this sub has ChangeDectectionStrategy.OnPush)
The issues I'm running into with this is that the form group value itself is not showing the correct sum of hours. Now what gets me is the field in the view shows the correct value but the form group value is wrong. (see below screenshot) Notice the field view "Col Hours" is correct, but the form value itself "collectiveHours" is wrong.
Its not updating on the very last key stroke. If a user would add a zero after the last digit in a hour field it would update correctly. So how does one force an update, is this an ngx-sub-form issues, or do I need to try and watch form.formGroup.value for changes?
Thanks ahead of time