5
votes

I'm making use of ng-bootstrap's ngbDatepicker in a Reactive Form in an Angular2 project, and the dates are optional, however ngbDatepicker always marks the form as Invalid unless a date is selected.

Is there a way to exclude ngbDatepicker from the form validation, or to configure it so that it returns Valid whether it has a value set or not?

2
It should work correctly, we even got a test covering this use-case: github.com/ng-bootstrap/ng-bootstrap/blob/… Are you sure that you've got a null / undefined model as opposed to, for example, an empty string? If you still face the problem please open an issue with a minimal reproduce scenario.pkozlowski.opensource
That was the problem - thank you! I was initializing the values in the model with empty strings, initializing the date fields with null solves the problem.Stephen R. Smith

2 Answers

6
votes

The issue was with how I was initializing the form values. I was setting the default values to empty strings where I should have been initializing the dates to null. So I was doing this:

  replicantForm = this.fb.group({
      name: ['', Validators.required],
      incepdate: '',
      longevity: ''
  })

When I should have been doing this:

  replicantForm = this.fb.group({
      name: ['', Validators.required],
      incepdate: null,
      longevity: ''
  })

Many thanks to @pkozlowski-opensource for the clarification.

1
votes

In response to the accepted answer and the fact it will not work for subsequent updates, I've used the following hack to make sure the control will be valid if no or an invalid date is inserted.

Pretty nasty to change the value in a validator if you ask me, but get's the job done until the ngb-datepicker sets the value internally.

Custom validator on the desired control:

validateOptionalDate(control: AbstractControl) {
  if (!(control.value instanceof Object) && control.value !== null) {
    control.patchValue(null, {
      onlySelf: true,
      emitEvent: false,
      emitModelToViewChange: true,
      emitViewToModelChange: false
    });
  }
}