J'ai importé un sélecteur de date dans un projet et je me demandais s'il existait un composant officiel récent de angular) et du matériel permettant également d'inclure le temps dans le calendrier.
J'ai souvent vu des sélecteurs de temps dans la documentation matérielle et effectué des recherches dans de nombreuses sources tierces, mais elles semblent très complexes.
Malheureusement, la réponse à votre question, à savoir s'il existe un support Material officiel pour la sélection de l'heure, est "Non", mais il s'agit actuellement d'un problème en suspens dans le référentiel Material2 GitHub: https://github.com/angular/ material2/issues/5648
J'espère que cela changera bientôt, en attendant, vous devrez vous battre avec ceux de tiers que vous avez déjà découverts. Dans ce numéro de GitHub, quelques personnes fournissent des solutions que vous pouvez utiliser.
Vous pouvez avoir un sélecteur de date/heure lorsque vous utilisez matInput
avec le type datetime-local
ainsi:
<mat-form-field>
<input matInput type="datetime-local" placeholder="start date">
</mat-form-field>
Vous pouvez cliquer sur chaque partie de l'espace réservé pour définir le jour, le mois, l'année, les heures, les minutes et indiquer si son heure est AM ou PM.
Tant qu'il n'y a pas de date officielle et de sélecteur de temps à partir de angular lui-même, je conseillerais de faire une combinaison de valeur par défaut angular angulaire) et ceci Timepicker de matériau angulaire . J'ai choisi celui-ci car tous les autres que j'ai trouvés à ce le temps manque de support pour les problèmes, sont obsolètes ou ne fonctionnent pas bien dans les versions les plus récentes angular. Ce mec semble être très réactif.
Je les ai tous deux emballés dans un seul composant, de sorte qu'il semble que ce soit une unité. Vous devez juste vous assurer de faire quelques choses:
Quand aucune entrée n'a encore été donnée, je conseillerais:
touchUi = true
sur le sélecteur de date, de manière à ce que le sélecteur de date et le sélecteur de temps apparaissent sous forme de dialogue l'un après l'autre.Lorsqu'une valeur a été donnée, il est clair qu'une partie contient l'heure et l'autre partie contient la date. A ce moment, il est clair que l'utilisateur doit cliquer sur l'heure pour changer l'heure et sur la date pour changer la date. Mais avant cela, donc lorsque les deux champs sont vides (et "attachés" l'un à l'autre sous la forme d'un seul champ), vous devez vous assurer que l'utilisateur ne peut pas être confondu en faisant les recommandations ci-dessus.
Mon composant n'est pas encore complet, je vais essayer de me rappeler de partager le code ultérieurement. Tirez un commentaire si cette question a plus d'un mois ou plus.
Edition: Résultat
<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);
}
}
Une source importante: https://github.com/Agranom/ngx-material-timepicker/issues/126
Je pense que cela mérite encore quelques ajustements, car je pense que cela peut fonctionner un peu mieux si je dispose de plus de temps pour créer ceci. Plus important encore, j'ai essayé de résoudre le problème UTC. Toutes les dates doivent donc être affichées en heure locale, mais doivent être envoyées au serveur au format UTC (ou au moins enregistrées avec le fuseau horaire correct ajouté).
Je vous suggère de passer à la caisse https://vlio20.github.io/angular-datepicker/