Search code examples
angularngx-bootstrap

Angular - Validate StartDate and EndDate without using DateRange


In Angular-13 project, I am using BsDatepickerModule datepicker in ngx-bootstrap.

I don't want to use DateRange picker, so I have StartDate and EndDate separately.

component.ts:

import { BsDatepickerConfig } from 'ngx-bootstrap/datepicker/public_api';

export class EmployeeCreateComponent implements OnInit {
  createEmployeeForm!: FormGroup;
  colorTheme = 'theme-red';
  bsConfig!: Partial<BsDatepickerConfig>;
  minStartDate!: Date;
  minEndDate!: Date;

  constructor(
    private fb: FormBuilder,
    private employeeService: EmployeeService,
  ) {
    this.minStartDate = new Date();
    this.minEndDate = new Date();
    this.minStartDate.setDate(this.minStartDate.getDate());
    this.minEndDate.setDate(this.minEndDate.getDate() + 1);
  }

  ngOnInit(): void {
    this.bsConfig = Object.assign({}, { dateInputFormat: 'DD-MM-YYYY', showClearButton: true, isAnimated: true, adaptivePosition: true, containerClass: this.colorTheme });
    this.createEmployee();
  }

  createEmployee() {
    this.createEmployeeForm = this.fb.group({
      EmployeeName: ['', [Validators.required, Validators.minLength(3), Validators.maxLength(50)]],
      StartDate: ['', [Validators.required]],
      EndDate: ['', [Validators.required]]
    });
  }
}

component.html:

<div class="row">
  <div class="col-md-6">
    <div class="form-group">
      <label for="StartDate">Start Date<span style="color:red;">*</span></label>
      <div class="input-group">
        <div class="input-group-prepend">
          <span class="input-group-text"><i class="far fa-calendar-alt"></i></span>
        </div>
        <input type="text" bsDatepicker [bsConfig]="bsConfig" [minDate]="minStartDate" class="form-control" formControlName="StartDate" placeholder="DD-MM-YYYY" formControlName="StartDate" readonly>
      </div>
      <div *ngIf="fc['StartDate'].touched && fc['StartDate'].invalid" class="alert alert-danger">
        <div *ngIf="fc['StartDate'].errors && fc['StartDate'].errors['required']">Start Date is required!</div>
      </div>
    </div>
  </div>
  <div class="col-md-6">
    <div class="form-group">
      <label for="EndDate">End Date<span style="color:red;">*</span></label>
      <div class="input-group">
        <div class="input-group-prepend">
          <span class="input-group-text"><i class="far fa-calendar-alt"></i></span>
        </div>
        <input type="text" bsDatepicker [bsConfig]="bsConfig" [minDate]="minEndDate" class="form-control" formControlName="EndDate" placeholder="DD-MM-YYYY" formControlName="EndDate" readonly>
      </div>
      <div *ngIf="fc['EndDate'].touched && fc['EndDate'].invalid" class="alert alert-danger">
        <div *ngIf="fc['EndDate'].errors && fc['EndDate'].errors['required']">End Date is required!</div>
      </div>
    </div>
  </div>
</div>

Using the documentation, I have implemented other formats and validation.

How do I validate StartDate not to be grater than the EndDate?

Thanks


Solution

  • In template you could add something along the line of (bsValueChange)="setStartDate($event)" to save user picked date to a variable. Same with the endDate. And then compare those two.

            <input
            class="form-control"
            [minDate]="minDate"
            [maxDate]="maxDate"
            #dp="bsDatepicker"
            bsDatepicker
            formControlName="myDate"
            (bsValueChange)="setStartDate($event)"
            [bsConfig]="{ dateInputFormat: 'MMM DD, YYYY' }">
    
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.css'],
    })
    export class AppComponent implements AfterViewInit {
      startDate: Date = new Date(Date.parse('15 Jan 1970 00:00:00 GMT'))
      endDate: Date = new Date(Date.parse('10 Jan 1970 00:00:00 GMT'))
    
      ngAfterViewInit() {
        this.validateDates();
      }
    
      validateDates() {
        if (this.startDate > this.endDate) {
          console.log('start date is greater');
        } else {
          console.log('end date is greater');
        }
      }
    
      setStartDate(event: Date) {
        //2022-01-25T11:43:45.300Z
        this.startDate = event;
      }
    
      setEndDate(event: Date) {
        //2022-01-25T11:43:45.300Z
        this.endDate = event;
      }
    }