0

DOB Datepicker should disable the years based on the value selected in the dropdown field.

  • I have a dropdown with 3 values - ADULT, INFANT and CHILD.
  • There is another field called DOB which opens a datepicker.

UI image


When I select ADULT from the dropdown,in the DOB datepicker, it should enable only from last 100 years to today. It should disable the other years. (Should be able to select from 29 March 1921 to 29 March 2021(today))

Similary, when I select CHILD from the dropdown,in the DOB datepicker, it should enable only from last 12 years to today. It should disable the other years.

For INFANT, last 2 years.


HTML Component Code

 <div class="form-group col-md-3" [ngClass]="displayFieldCss('paxType',passengerFormIndex)" *ngIf = "getControlCheckInfo('paxType')">
        <label>{{'Pax Type' | translate}}<span *ngIf = "getControlCheckInfo('paxType', true)" class="mandatory-fields err-msg">*</span></label>
        <select class="form-control" formControlName="paxType">
          <option [ngValue]="null">Select Pax Type</option>
          <option *ngFor="let data of paxData" [ngValue]="data">{{data.passengerTypeName}}</option>
        </select>
        <app-field-error-display [displayError]="isFieldValid('paxType',passengerFormIndex)" errorMsg="Please enter the pax type">
        </app-field-error-display>
      </div>

  <div class="form-group col-md-3" [ngClass]="displayFieldCss('dateOfBirth',passengerFormIndex)" *ngIf = "getControlCheckInfo('dateOfBirth')">
    <label>{{'Date of Birth' | translate}}<span *ngIf = "getControlCheckInfo('dateOfBirth', true)" class="mandatory-fields err-msg">*</span></label>
    <input [min]="mindateOfBirth"  matInput [matDatepicker]="dob" placeholder="Date of Birth" class="form-control"
      formControlName="dateOfBirth" (click)="dob.open()">
    <mat-datepicker #dob></mat-datepicker>
    <app-field-error-display [displayError]="isFieldValid('dateOfBirth',passengerFormIndex)" errorMsg="Please enter the Date Of Birth">
    </app-field-error-display>
    </div>  

I have the respective functions in ts file.

fabc
  • 182
  • 10
WarMachine
  • 27
  • 8

1 Answers1

0

EDIT: This answer previously stated information that was not relevant to the case due to the use of base Angular in lieu of Angular Material (in that the instructions specified were in reference to Bootstrap's DatePicker and not Material's DatePicker)

My apologies, I did not realize you were using Material, I've suggested changes on the posts' tags to clarify that for anyone else searching for this kind of issue.

I've realized you were more than correct in using "min" to establish the minimum date, changing according to the value so:

ADULT:

minDate = new Date(currentYear - 100, 0, 1);

Child:

minDate = new Date(currentYear - 12, 0, 1);

Infant:

minDate = new Date(currentYear - 2, 0, 1);

Where "currentYear" is declared as follows:

const currentYear = new Date().getFullYear();

These dates would replace the "min" attribute on the "input" tag of your Angular HTML.

The listener used in my response before the edit are still valid, however I feel it necessary to elaborate further:

This would be within the HTML:

<select (ngModelChange)="nameOfYourFunction($event)"/>

And this would be inside of the Component.ts file:

/* Extra comments added at 5pm CET */ 
/* "(value)" is collected instead of ID because ngModelChange refers to changes in the select (in this case), more specifically "value selected" which is the value attribute inside of the option inside of the select tag. This is more useful given that the string text inside the option can change according to the language and the ID must be unique (you may want to reuse this snippet of code for another form, it helps to have it be reproduceable*/
nameOfYourFunction(value){
    /*a simple if/else with the different categories listed above. Then simply call the element using jQuery/angular.element*/
    var end=1000;
    const currentYear=new Date().getFullYear();
    if(value=="ADULT") {end=100} else if(value=="CHILD" {end=12} else if(value=="INFANT"){end=2};
    var minDate=new Date(currentYear - end, 0, 1);
    /* Previously, and erroneously, declared this as .value, the attribute name is min, so it should be .min*/
    /* What's more, #dateInputID refers to whatever ID you've given the datepicker, alternatively you could use a selector that targets this element, but I'd recommend ID's, as they are unique */
    angular.element(document).find(#dateInputID).min=minDate;
}

If I'm not mistaken.

BEFORE EDIT:

From what I understand from the documentation about startDate in datepicker, you should be able to set up a different value for "startDate" with a simple valueChangelistener on the select that you have (this is what I've found regarding Angular's change events). I don't know your exact structure within ng, so I'll do my best to explain it with the following pseudo-code

<script>
    function endDateChange(value){
        var end;
        if(value=="ADULT") {end=endDateValueAdult}
        else if(value=="CHILD") {end=endDateValueChild}
        else if(value=="INFANT") {end=endDateValueInfant}
        datePickerInput.endDate=end;
    }
</script>

The function would be attached with an ng listener like:

(ngModelChange)="clearFilter()"

in the tag.

fabc
  • 182
  • 10
  • Can you share the exact function logic based on this code? – WarMachine Mar 29 '21 at 13:25
  • Also, should the `(ngModelChange)="clearFilter()" ` be given in PAX type or DOB? – WarMachine Mar 29 '21 at 13:33
  • Apologies @ClarkeGriffin , I only just realized that I answered for Bootstrap when you were using Material, I've changed my answer to match. In regards to where the ngModelChange should be located, it should be in PAX, because that's where you want to listen to the change; the function name should be "endDateChange($event)" instead of "clearFilter()" – fabc Mar 29 '21 at 14:03
  • 1
    Not able to build as Iam getting error in the last line `angular.element(document).find(#dateInputID).value=minDate;` – WarMachine Mar 29 '21 at 14:38
  • 1
    Also can we use ID instead of value. `data.paxType = this.findElement(this.paxData, 'passengerTypeId', data.paxType);` I have passengerTypeId for this. – WarMachine Mar 29 '21 at 14:46
  • I've also added a few extra comments regarding the why and where of the choices that I made in the angular code block. I'm having a little trouble understanding the "use ID instead of value", I commented that I'm using value because it's the attribute that's selected upon changing selected options - "#dateInputID" refers to the DOB element, the value should come from the PAX element, have I misunderstood? – fabc Mar 29 '21 at 15:02
  • 1
    Made few change with the variables. It works now . Thanks for the logic. – WarMachine Mar 30 '21 at 08:49
  • Can you please check this question also https://stackoverflow.com/questions/66829018/how-to-edit-the-field-while-using-ng-select – WarMachine Mar 30 '21 at 08:55
  • Please check this question also, https://stackoverflow.com/questions/66829608/how-to-auto-fill-value-in-one-drop-down-with-the-same-value-selected-in-another/66857966#66857966 @fabc – WarMachine Mar 31 '21 at 09:57