1
votes

I need to select two different date formats (YYYY-MM-DD and YYYY-MM) in two mat datepicker fields in one component view.

I'm using angular 6.0.3 and material 6.4.7.

I configured datepicker format to YYYY-MM-DD in app module using MAT_DATE_FORMATS and it works globally but I need to override this format to YYYY-MM in a few datepicker fields as I wrote above. Unfortunatelly I have no idea how I can achieve this.

Could You help me please?

Parts of my code:

        import { Component, OnInit, ViewChild } from '@angular/core';
    import { FormGroup, FormControl } from '@angular/forms';

    @Component({
      selector: 'app-invoice-list',
      templateUrl: './invoice-list.component.html',
      styleUrls: ['./invoice-list.component.css']
    })
    export class InvoiceListComponent {

      filterForm: FormGroup;

      @ViewChild('month_picker') month_picker;

      constructor() {
        this.filterForm = new FormGroup({
          assigned_date_from: new FormControl(),
          assigned_date_to: new FormControl(),
          assigned_month: new FormControl(),
        });
      }
    }

<div class="container" [formGroup]="filterForm">
  <div class="container" fxLayout="row" fxLayout.xs="column" fxLayoutWrap fxLayoutGap="0.5%" fxLayoutAlign="start">
      <div fxFlex="32%">
        <mat-form-field>
            <input matInput [matDatepicker]="date_from_picker" (focus)="date_from_picker.open()" formControlName="assigned_date_from" placeholder="Date from">
            <mat-datepicker-toggle matSuffix [for]="date_from_picker"></mat-datepicker-toggle>
            <mat-datepicker #date_from_picker></mat-datepicker>
        </mat-form-field>
      </div>
      <div fxFlex="32%">
        <mat-form-field>
            <input matInput [matDatepicker]="date_to_picker" (focus)="date_to_picker.open()" formControlName="assigned_date_to" placeholder="Date to">
            <mat-datepicker-toggle matSuffix [for]="date_to_picker"></mat-datepicker-toggle>
            <mat-datepicker #date_to_picker></mat-datepicker>
          </mat-form-field>
      </div>

      <!-- In below input I want month year format - YYYY-MM - so different than default format in above fields -->
      <div fxFlex="32%">
          <mat-form-field>
              <input matInput [matDatepicker]="month_picker" (focus)="month_picker.open()" formControlName="assigned_month" placeholder="Month">
              <mat-datepicker-toggle matSuffix [for]="month_picker"></mat-datepicker-toggle>
              <mat-datepicker #month_picker></mat-datepicker>
            </mat-form-field>
        </div>
    </div>
</div>
3
Can't you use viewChild?Asanka
I thought about viewChild, but viewChild variable is shared for all datepicker in my view, right? In this way every changes from component on this datepicker (viewChild variable) will apply for all datepicker fields in my viewMarcin.ka
No i can help you but I need some time.can you put your html and ts file.Asanka
Thank You!! I added parts of my code in my postMarcin.ka
No need of adding viewChildren. I'll post my answerAsanka

3 Answers

1
votes

Please try this. In your Html

        <mat-form-field>
          <input matInput [matDatepicker]="month_picker" (focus)="month_picker.open()" [value] = "selectedMonth" placeholder="Month">
          <mat-datepicker-toggle matSuffix [for]="month_picker"></mat-datepicker-toggle>
          <mat-datepicker #month_picker  
              startView="multi-year"
              (monthSelected)="chosenMonthHandler($event, month_picker)"></mat-datepicker>
        </mat-form-field>

In your .ts

    selectedMonth = new Date();

    chosenMonthHandler(normlizedMonth, datepicker) {
        var tempDate = JSON.stringify(normlizedMonth).replace("\"",'').split("-")
        var month = parseInt(tempDate[1])
        var year = month == 12?parseInt(tempDate[0])+1:parseInt(tempDate[0])
        var year = month == 12?parseInt(tempDate[0])+1:parseInt(tempDate[0])
        month = month == 12?1:month+1;
        this.selectedMonth = new Date(year + "-" + month)
        console.log(year + " " + month)
        datepicker.close();
      }

This works well.but show the selected date as 1 after select a month.But I think this fulfills your requirements.

1
votes
  1. If you're looking for a way to have a couple static formats, it is possible.

    Unfortunately, if you want to have it be dynamic based on a directive input (e.g. ) This won't work because there isn't currently a mechanism to tell the datepicker that the format has updated.

    More information can be found here

0
votes
http://brickydev.com/angular-material-datepicker-with-many-custom-date-formats/

I found this link and this solution worked for me.

step 1: Create a directive

ng generate directive customDateFormat

step 2:

import { Directive } from '@angular/core';
import { MAT_DATE_FORMATS } from '@angular/material/core';

export const FORMAT = {
  parse: {
    dateInput: 'DD-MM-YYYY',
  },
  display: {
    dateInput: 'DD-MM-YYYY',
    monthYearLabel: 'MMM YYYY',
    dateA11yLabel: 'LL',
    monthYearA11yLabel: 'MMMM YYYY',
  },
};

@Directive({
  selector: '[appCustomeDateFormats]',
  providers: [{ provide: MAT_DATE_FORMATS, useValue: FORMAT }],
})
export class CustomeDateFormatsDirective {
  constructor() {}
}

step 3: use this directive in the template.

     <mat-form-field class="example-full-width" appCustomeDateFormats>
            <mat-label>Start Date</mat-label>
            <input
              matInput
              [matDatepicker]="startDate"
              formControlName="from_date"
            />
            <mat-datepicker-toggle
              matSuffix
              [for]="startDate"
            ></mat-datepicker-toggle>
            <mat-datepicker touchUi #startDate></mat-datepicker>
          </mat-form-field>