mn-angular-lib 1.0.25 → 1.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -2719,7 +2719,8 @@ class MnSelect {
|
|
|
2719
2719
|
this.destroyRef.onDestroy(() => sub.unsubscribe());
|
|
2720
2720
|
}
|
|
2721
2721
|
writeValue(val) {
|
|
2722
|
-
|
|
2722
|
+
// Treat empty string as null so the placeholder is shown and the control stays properly invalid
|
|
2723
|
+
this.selectedValue = (val === '' || val == null) ? null : val;
|
|
2723
2724
|
}
|
|
2724
2725
|
registerOnChange(fn) {
|
|
2725
2726
|
this.onChange = fn;
|
|
@@ -4393,6 +4394,8 @@ class MnFormBodyComponent {
|
|
|
4393
4394
|
formErrors = {};
|
|
4394
4395
|
/** Track which fields are currently visible (for conditional fields) */
|
|
4395
4396
|
fieldVisibility = {};
|
|
4397
|
+
/** Track which fields are currently conditionally required */
|
|
4398
|
+
fieldConditionallyRequired = {};
|
|
4396
4399
|
/** Track loading state per field for async data sources */
|
|
4397
4400
|
fieldLoading = {};
|
|
4398
4401
|
/** Dynamic options loaded from data sources */
|
|
@@ -4411,6 +4414,12 @@ class MnFormBodyComponent {
|
|
|
4411
4414
|
return val;
|
|
4412
4415
|
}
|
|
4413
4416
|
hasRequiredValidator(field) {
|
|
4417
|
+
// Check if conditionallyRequired is currently active
|
|
4418
|
+
if (field.conditionallyRequired) {
|
|
4419
|
+
const formValue = this.form?.value ?? {};
|
|
4420
|
+
if (field.conditionallyRequired(formValue))
|
|
4421
|
+
return true;
|
|
4422
|
+
}
|
|
4414
4423
|
const validators = field.validators;
|
|
4415
4424
|
if (!validators)
|
|
4416
4425
|
return false;
|
|
@@ -4635,10 +4644,11 @@ class MnFormBodyComponent {
|
|
|
4635
4644
|
// Feature 1: Conditional/Dynamic Fields
|
|
4636
4645
|
// =========================
|
|
4637
4646
|
initializeVisibility() {
|
|
4647
|
+
const formValue = this.form.value;
|
|
4638
4648
|
this.config.fields.forEach(field => {
|
|
4639
4649
|
const key = field.key;
|
|
4640
4650
|
const fieldAny = field;
|
|
4641
|
-
const isVisible = fieldAny.visible ? fieldAny.visible(
|
|
4651
|
+
const isVisible = fieldAny.visible ? fieldAny.visible(formValue) : true;
|
|
4642
4652
|
this.fieldVisibility[key] = isVisible;
|
|
4643
4653
|
// If initially hidden, clear validators so they don't block submit
|
|
4644
4654
|
if (!isVisible) {
|
|
@@ -4648,6 +4658,19 @@ class MnFormBodyComponent {
|
|
|
4648
4658
|
control.updateValueAndValidity({ emitEvent: false });
|
|
4649
4659
|
}
|
|
4650
4660
|
}
|
|
4661
|
+
else if (fieldAny.conditionallyRequired) {
|
|
4662
|
+
// Initialize conditionallyRequired state for visible fields
|
|
4663
|
+
const isRequired = fieldAny.conditionallyRequired(formValue);
|
|
4664
|
+
this.fieldConditionallyRequired[key] = isRequired;
|
|
4665
|
+
if (isRequired) {
|
|
4666
|
+
const control = this.form.get(key);
|
|
4667
|
+
if (control) {
|
|
4668
|
+
const validators = this.buildValidators(fieldAny, formValue);
|
|
4669
|
+
control.setValidators(validators);
|
|
4670
|
+
control.updateValueAndValidity({ emitEvent: false });
|
|
4671
|
+
}
|
|
4672
|
+
}
|
|
4673
|
+
}
|
|
4651
4674
|
});
|
|
4652
4675
|
}
|
|
4653
4676
|
updateVisibility() {
|
|
@@ -4666,14 +4689,54 @@ class MnFormBodyComponent {
|
|
|
4666
4689
|
control.updateValueAndValidity({ emitEvent: false });
|
|
4667
4690
|
}
|
|
4668
4691
|
else if (isVisible && !wasVisible) {
|
|
4669
|
-
// Restore validators
|
|
4670
|
-
const validators = fieldAny
|
|
4692
|
+
// Restore validators (including conditionallyRequired if active)
|
|
4693
|
+
const validators = this.buildValidators(fieldAny, formValue);
|
|
4671
4694
|
control.setValidators(validators);
|
|
4672
4695
|
control.updateValueAndValidity({ emitEvent: false });
|
|
4673
4696
|
}
|
|
4697
|
+
else if (isVisible) {
|
|
4698
|
+
// Update conditionallyRequired for visible fields
|
|
4699
|
+
this.updateConditionallyRequired(fieldAny, formValue);
|
|
4700
|
+
}
|
|
4674
4701
|
}
|
|
4675
4702
|
});
|
|
4676
4703
|
}
|
|
4704
|
+
/**
|
|
4705
|
+
* Builds the full validator array for a field, including conditionallyRequired.
|
|
4706
|
+
* @param fieldAny The field configuration.
|
|
4707
|
+
* @param formValue The current form values.
|
|
4708
|
+
* @returns Array of validators to apply.
|
|
4709
|
+
*/
|
|
4710
|
+
buildValidators(fieldAny, formValue) {
|
|
4711
|
+
const baseValidators = fieldAny.validators ? [...fieldAny.validators] : [];
|
|
4712
|
+
if (fieldAny.conditionallyRequired && fieldAny.conditionallyRequired(formValue)) {
|
|
4713
|
+
if (!baseValidators.includes(Validators.required)) {
|
|
4714
|
+
baseValidators.push(Validators.required);
|
|
4715
|
+
}
|
|
4716
|
+
}
|
|
4717
|
+
return baseValidators;
|
|
4718
|
+
}
|
|
4719
|
+
/**
|
|
4720
|
+
* Updates the conditionallyRequired state for a single field and adjusts validators.
|
|
4721
|
+
* @param fieldAny The field configuration.
|
|
4722
|
+
* @param formValue The current form values.
|
|
4723
|
+
*/
|
|
4724
|
+
updateConditionallyRequired(fieldAny, formValue) {
|
|
4725
|
+
if (!fieldAny.conditionallyRequired)
|
|
4726
|
+
return;
|
|
4727
|
+
const key = fieldAny.key;
|
|
4728
|
+
const wasRequired = this.fieldConditionallyRequired[key] ?? false;
|
|
4729
|
+
const isRequired = fieldAny.conditionallyRequired(formValue);
|
|
4730
|
+
this.fieldConditionallyRequired[key] = isRequired;
|
|
4731
|
+
if (isRequired !== wasRequired) {
|
|
4732
|
+
const control = this.form.get(key);
|
|
4733
|
+
if (control) {
|
|
4734
|
+
const validators = this.buildValidators(fieldAny, formValue);
|
|
4735
|
+
control.setValidators(validators);
|
|
4736
|
+
control.updateValueAndValidity({ emitEvent: false });
|
|
4737
|
+
}
|
|
4738
|
+
}
|
|
4739
|
+
}
|
|
4677
4740
|
isFieldVisible(field) {
|
|
4678
4741
|
return this.fieldVisibility[field.key];
|
|
4679
4742
|
}
|