【问题标题】:Angular Material Datepicker - Month & Year ONLYAngular Material Datepicker - 仅限月份和年份
【发布时间】:2019-11-03 02:32:52
【问题描述】:

我希望我的角度材料日期选择器只显示月/年。没有天。

这是我的日期选择器:

<mat-form-field>
    <input matInput [matDatepicker]="picker" placeholder="Choose a date">
    <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
    <mat-datepicker #picker></mat-datepicker>
</mat-form-field>

我看到之前的帖子说将模式设置为:

md-mode="month"

以上不再起作用。现在有什么解决办法?

【问题讨论】:

  • 创建两个选择,一个带有月份,另一个带有年份。这将是最简单的解决方案。去日历的原因主要是为了天映射。例如 DOB 字段请参考 facebook 注册页面。
  • 使用选择需要多年的手动输入?
  • @user10181542 - 您可以使用this article 中建议的方法填充数组,并在模板中使用*ngFor 将这些options 添加到select 元素中。
  • 我做了一个堆栈闪电战,对循环年的考虑最少。几个月来,我建议硬编码名称,如果不使用,则根据要求进行本地翻译。 stackblitz.com/edit/angular-uyyqpn

标签: angular typescript angular-material


【解决方案1】:

这是一个对我有用的代码。我看到你正在尝试类似的东西。希望对您有所帮助。

.html 文件:

<mat-form-field>
    <input matInput [matDatepicker]="dp2" [min]="sixMonthsAgo" [max]="today" placeholder="Select a Date" (click)="openDatePicker(dp2)">
    <mat-datepicker-toggle matSuffix [for]="dp2"></mat-datepicker-toggle>
    <mat-datepicker #dp2 startView="multi-year" (monthSelected)="closeDatePicker($event, dp2)"></mat-datepicker>
  </mat-form-field>

来自.ts文件的sn-p:

  this.today = new Date();
  this.sixMonthsAgo = new Date();
  this.sixMonthsAgo.setMonth(this.today.getMonth() - 6);

  openDatePicker(dp) {
    dp.open();
  }

  closeDatePicker(eventData: any, dp?:any) {
    // get month and year from eventData and close datepicker, thus not allowing user to select date
    dp.close();    
  }

【讨论】:

【解决方案2】:

要求是在输入元素上显示“MMMM YYYY”格式。 “MMMM YYYY”格式为“月年”。 想要创建自定义日期格式并应用于 mat-datepicker。

在 HTML 中

<mat-label>For the Month</mat-label>
<input matInput [matDatepicker]="picker1" name="CalMonth" formControlName="CalMonth">
<mat-datepicker-toggle matSuffix [for]="picker1"></mat-datepicker-toggle>
<mat-datepicker #picker1 disabled="false"></mat-datepicker>

在 .ts 打字稿中

想要导入 ma​​terial-moment-adapterma​​terial/core时刻

安装材料力矩适配器

npm i @angular/material-moment-adapter

npm i 角矩

import {MomentDateAdapter, MAT_MOMENT_DATE_ADAPTER_OPTIONS} from '@angular/material-moment-adapter';
import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '@angular/material/core';
import * as moment from 'moment';

export const MY_FORMATS = {
  parse: {
    dateInput: 'LL', 
  },
  display: {
    dateInput: 'MMMM YYYY', // this is the format showing on the input element
    monthYearLabel: 'MMMM YYYY', // this is showing on the calendar 
  },
};

然后添加到组件中

@Component({
  selector: 'app-monthselector',
  templateUrl: './monthselector.component.html',
  styleUrls: ['./monthselector.component.scss'],
  providers: [
    {
      provide: DateAdapter,
      useClass: MomentDateAdapter,
      deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS]
    },

    {provide: MAT_DATE_FORMATS, useValue: MY_FORMATS},
  ],
})

然后将格式添加到相关控制器

this.UIForm = new FormGroup({
      CalMonth: new FormControl(moment()),
    }); 

按照上面的步骤,你可以自定义日期格式为“月年”

您也可以更改任何其他日期格式,仅更改此

日期输入:'MMMM YYYY',

谢谢,

印度洋

【讨论】:

  • 我这样做了,它改变了组件中的所有日期选择器,所以在视图中我看到所有选择器都是这样的:“01/2022”。如何将其仅应用于一个,而其他选择器格式将保持默认,如下所示:''01/01/2022"
【解决方案3】:

我已经制定了一个解决方案,完全依赖官方 Angular Material 文档中给出的示例:

https://material.angular.io/components/datepicker/overview#watching-the-views-for-changes-on-selected-years-and-months

带有代码的示例可以正常工作,但是当用户单击标题中的年份时,日历中仍然会导航到“月”视图

这里有个转机:在自定义组件的TS里

&lt;mat-datepicker #dp startView="multi-year" (yearSelected)="chosenYearHandler($event)" (monthSelected)="chosenMonthHandler($event, datePicker)"&gt;&lt;/mat-datepicker&gt;

在 Angular Material 链接中声明,我添加:

@ViewChild('datePicker') public dp;

ngAfterViewInit(): void {
  this.dp.openedStream.subscribe(async _ => {
    while (this.dp._popupComponentRef.instance._calendar == null)
      await this.__delay__(100)

    this.dp._popupComponentRef.instance._calendar._calendarHeaderPortal._attachedHost._attachedRef.instance.currentPeriodClicked = function () {        
    
        // redefine here calendar navigation in header
        
        if (this.calendar.currentView == 'month')
            this.calendar.currentView = 'year'
        
        this.calendar.currentView = this.calendar.currentView == 'year' ? 'multi-year' : 'year';
    }
  })
}

这样您就可以从标题自定义导航...

【讨论】:

    【解决方案4】:

    这出人意料地不简单..我在这里找到了“官方”方式

    https://stackblitz.com/angular/ekjvrbglvnb?file=src%2Fapp%2Fdatepicker-views-selection-example.ts

    【讨论】:

      【解决方案5】:

      .html 中的代码

      <mat-form-field>
        <input matInput [matDatepicker]="picker" placeholder="Choose a date">
        <mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
        <mat-datepicker #picker></mat-datepicker>
      </mat-form-field>
      

      .ts 中的代码

      import {MatDatepicker} from '@angular/material/datepicker';
      
      
       @ViewChild('picker') datePickerElement = MatDatepicker;
      
        ngOnInit() {
          console.log(this.datePickerElement) 
          console.log(this.datePickerElement['opened'])  
         
          setTimeout(() => {
                this.datePickerElement['_datepickerInput']._dateFormats = {
        parse: {
          dateInput: 'LL', 
        },
        display: {
          dateInput: 'MMMM YYYY',
          monthYearLabel: 'MMMM YYYY', 
        },
      };
          },1000)
      
      
        }
      

      这对我来说很好用。 日期格式将显示如下截图

      【讨论】:

      • _datepickerInput 中的错误
      【解决方案6】:

      您可以使用这两个处理程序 (chosenYearHandler & chosenMonthHandler) 以及仅显示月份和年份的格式:

      TS:

      import {Component} from '@angular/core';
      import {FormControl} from '@angular/forms';
      import {MomentDateAdapter, MAT_MOMENT_DATE_ADAPTER_OPTIONS} from '@angular/material-moment-adapter';
      import {DateAdapter, MAT_DATE_FORMATS, MAT_DATE_LOCALE} from '@angular/material/core';
      import {MatDatepicker} from '@angular/material/datepicker';
      
      // Depending on whether rollup is used, moment needs to be imported differently.
      // Since Moment.js doesn't have a default export, we normally need to import using the `* as`
      // syntax. However, rollup creates a synthetic default module and we thus need to import it using
      // the `default as` syntax.
      import * as _moment from 'moment';
      // tslint:disable-next-line:no-duplicate-imports
      import {default as _rollupMoment, Moment} from 'moment';
      
      const moment = _rollupMoment || _moment;
      
      // See the Moment.js docs for the meaning of these formats:
      // https://momentjs.com/docs/#/displaying/format/
      export const MY_FORMATS = {
        parse: {
          dateInput: 'MM/YYYY',
        },
        display: {
          dateInput: 'MM/YYYY',
          monthYearLabel: 'MMM YYYY',
          dateA11yLabel: 'LL',
          monthYearA11yLabel: 'MMMM YYYY',
        },
      };
      
      /** @title Datepicker emulating a Year and month picker */
      @Component({
        selector: 'datepicker-views-selection-example',
        templateUrl: 'datepicker-views-selection-example.html',
        styleUrls: ['datepicker-views-selection-example.css'],
        providers: [
          // `MomentDateAdapter` can be automatically provided by importing `MomentDateModule` in your
          // application's root module. We provide it at the component level here, due to limitations of
          // our example generation script.
          {
            provide: DateAdapter,
            useClass: MomentDateAdapter,
            deps: [MAT_DATE_LOCALE, MAT_MOMENT_DATE_ADAPTER_OPTIONS]
          },
      
          {provide: MAT_DATE_FORMATS, useValue: MY_FORMATS},
        ],
      })
      export class DatepickerViewsSelectionExample {
        date = new FormControl(moment());
      
        chosenYearHandler(normalizedYear: Moment) {
          const ctrlValue = this.date.value;
          ctrlValue.year(normalizedYear.year());
          this.date.setValue(ctrlValue);
        }
      
        chosenMonthHandler(normalizedMonth: Moment, datepicker: MatDatepicker<Moment>) {
          const ctrlValue = this.date.value;
          ctrlValue.month(normalizedMonth.month());
          this.date.setValue(ctrlValue);
          datepicker.close();
        }
      }
      

      HTML:

      <mat-form-field appearance="fill">
        <mat-label>Month and Year</mat-label>
        <input matInput [matDatepicker]="dp" [formControl]="date">
        <mat-datepicker-toggle matSuffix [for]="dp"></mat-datepicker-toggle>
        <mat-datepicker #dp
                        startView="multi-year"
                        (yearSelected)="chosenYearHandler($event)"
                        (monthSelected)="chosenMonthHandler($event, dp)"
                        panelClass="example-month-picker">
        </mat-datepicker>
      </mat-form-field>
      

      CSS:

      .example-month-picker .mat-calendar-period-button {
        pointer-events: none;
      }
      
      .example-month-picker .mat-calendar-arrow {
        display: none;
      }
      

      更多解释:https://material.angular.io/components/datepicker/examples

      【讨论】:

        【解决方案7】:

        在我的情况下,我有大量的动态输入,因此我无法像文档中那样将数据插入到表单控件中: https://material.angular.io/components/datepicker/overview#datepicker-views-selection

        这是我的解决方案:

          setDateHandler(dateEvent: Moment,datepicker: MatDatepicker<any>) {
        datepicker._selectedChanged.next(dateEvent);
        datepicker.close(); }
        

        【讨论】:

          猜你喜欢
          • 2013-02-05
          • 2018-07-05
          • 2020-02-26
          • 1970-01-01
          • 2023-04-08
          • 2018-06-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多