Angular-Material DateTime Picker组件?

问题描述 投票:12回答:4

我在一个项目中导入了一个these,并想知道是否有任何官方的最新成分来自角度和材料以包括日历中的时间。我在材料文档中看到了大量的时间选择,并研究了很多第三方,但它们看起来非常复杂。任何帮助都会很棒!

angular datepicker angular-material2 datetimepicker timepicker
4个回答
12
投票

不幸的是,关于是否有正式材料支持选择时间的问题的答案是“否”,但它目前是官方Material2 GitHub回购的一个未决问题:https://github.com/angular/material2/issues/5648

希望这很快就会改变,与此同时,你将不得不与你已经发现的第三方战斗。 GitHub问题中有一些人提供了他们可以尝试的自制解决方法。


5
投票

当使用类型为matInputdatetime-local时,你可以有一个日期时间选择器,如下所示:

  <mat-form-field>
    <input matInput type="datetime-local" placeholder="start date">
  </mat-form-field>

您可以单击占位符的每个部分来设置日,月,年,小时,分钟以及是上午还是下午。


2
投票

只要没有正式的角色本身的日期和时间选择器,我建议组合default angular date picker和这个Angular Material Timepicker。我之所以选择那个,因为我在这个时候发现的所有其他内容都缺乏对问题的支持,在最近的角度版本中已经过时或运行不佳。这家伙似乎非常敏感。

我把它们都包装在一个组件中,看起来它就像一个单元。你必须确保做一些事情:

如果还没有给出任何意见,我会建议:

  • 单击该组件,应始终首先触发datepicker。
  • 在datepicker关闭后,自动弹出时间戳。
  • 在datepicker上使用touchUi = true,以便datepicker和timepicker相互之间成为对话框。
  • 确保在单击表单时(而不是仅在默认图标上)显示日期选择器。
  • 使用this solution也可以在材质形式中使用时间戳,当它们放在彼此后面时,它看起来就像是一种形式。

在给出一个值之后,很明显一个部分包含时间而另一个部分包含日期。此时很明显,用户必须点击时间来更改时间,并在日期更改日期。但在此之前,所以当两个字段都是空的(并且作为一个字段“彼此连接”)时,您应该确保用户不会因为执行上述建议而感到困惑。

我的组件尚未完成,我将尽力记住自己以后共享代码。如果此问题超过一个月左右,则发表评论。

编辑:结果

enter image description here

<div fxLayout="row">
  <div *ngIf="!dateOnly" [formGroup]="timeFormGroup">
    <mat-form-field>
      <input matInput [ngxTimepicker]="endTime" [format]="24"  placeholder="{{placeholderTime}}" formControlName="endTime" />
    </mat-form-field>
    <ngx-material-timepicker #endTime (timeSet)="timeChange($event)" [minutesGap]="10"></ngx-material-timepicker>
  </div>
  <div>
    <mat-form-field>
      <input id="pickerId" matInput [matDatepicker]="datepicker" placeholder="{{placeholderDate}}" [formControl]="dateForm"
             [min]="config.minDate" [max]="config.maxDate" (dateChange)="dateChange($event)">
      <mat-datepicker-toggle matSuffix [for]="datepicker"></mat-datepicker-toggle>
      <mat-datepicker #datepicker [disabled]="disabled" [touchUi]="config.touchUi" startView="{{config.startView}}"></mat-datepicker>
    </mat-form-field>
  </div>
</div>
import { Component, OnInit, Input, EventEmitter, Output } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { DateAdapter, MatDatepickerInputEvent } from '@angular/material';

import * as moment_ from 'moment';

const moment = moment_;

import { MAT_MOMENT_DATE_ADAPTER_OPTIONS } from '@angular/material-moment-adapter';

class DateConfig {
  startView: 'month' | 'year' | 'multi-year';
  touchUi: boolean;
  minDate: moment_.Moment;
  maxDate: moment_.Moment;
}

@Component({
  selector: 'cb-datetimepicker',
  templateUrl: './cb-datetimepicker.component.html',
  styleUrls: ['./cb-datetimepicker.component.scss'],
})
export class DatetimepickerComponent implements OnInit {

  @Input() disabled: boolean;
  @Input() placeholderDate: string;
  @Input() placeholderTime: string;
  @Input() model: Date;
  @Input() purpose: string;
  @Input() dateOnly: boolean;

  @Output() dateUpdate = new EventEmitter<Date>();

  public pickerId: string = "_" + Math.random().toString(36).substr(2, 9);

  public dateForm: FormControl;
  public timeFormGroup: FormGroup;
  public endTime: FormControl;

  public momentDate: moment_.Moment;
  public config: DateConfig;

  //myGroup: FormGroup;


  constructor(private adapter : DateAdapter<any>) { }

  ngOnInit() {

    this.adapter.setLocale("nl-NL");//todo: configurable
    this.config = new DateConfig();
    if (this.purpose === "birthday") {
      this.config.startView = 'multi-year';
      this.config.maxDate = moment().add('year', -15);
      this.config.minDate = moment().add('year', -90);
      this.dateOnly = true;
    } //add more configurations
    else {
      this.config.startView = 'month';
      this.config.maxDate = moment().add('year', 100);
      this.config.minDate = moment().add('year', -100);
    }


    if (window.screen.width < 767) {
      this.config.touchUi = true;
    }



    if (this.model) {
      var mom = moment(this.model);
      if (mom.isBefore(moment('1900-01-01'))) {
        this.momentDate = moment();
      } else {
        this.momentDate = mom;
      }
    } else {
      this.momentDate = moment();
    }

    this.dateForm = new FormControl(this.momentDate);
    if (this.disabled) {
      this.dateForm.disable();
    }
    this.endTime = new FormControl(this.momentDate.format("HH:mm"));

    this.timeFormGroup = new FormGroup({
      endTime: this.endTime
    });


  }


  public dateChange(date: MatDatepickerInputEvent<any>) {

    if (moment.isMoment(date.value)) {
      this.momentDate = moment(date.value);
      if (this.dateOnly) {
        this.momentDate = this.momentDate.utc(true);
      } 
      var newDate = this.momentDate.toDate();
      this.model = newDate;
      this.dateUpdate.emit(newDate);
    }

    console.log("datechange",date);
  }

  public timeChange(time: string) {

    var splitted = time.split(':');
    var hour = splitted[0];
    var minute = splitted[1];

    console.log("time change", time);
   this.momentDate = this.momentDate.set('hour', parseInt(hour));
    this.momentDate = this.momentDate.set('minute', parseInt(minute));

    var newDate = this.momentDate.toDate();
    this.model = newDate;
    this.dateUpdate.emit(newDate);
  }
}

一个重要来源:https://github.com/Agranom/ngx-material-timepicker/issues/126

我认为它仍然值得进行一些调整,因为我认为当我有更多时间创建它时,它可以更好地工作。最重要的是,我也尝试解决UTC问题,因此所有日期都应以当地时间显示,但应以UTC格式发送到服务器(或者至少保存时添加正确的时区)。


© www.soinside.com 2019 - 2024. All rights reserved.