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
- this.selectedValue = val ?? null;
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(this.form.value) : true;
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.validators || [];
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
  }