带范围选择的角度材料日期选择器 [英] Angular Material Datepicker with Range Selection
问题描述
我使用的是 angular 8,我想实现一个日期选择器,并突出显示 daterage:在此处输入图片描述我正在寻找这样的包:https://www.npmjs.com/package/土星日期选择器不幸的是,它已被弃用,目前我找不到其他类似的.你知道什么是为了我的目的吗?谢谢你.
I'm using angular 8 and I wanted implement a datepicker with daterage highlighted: enter image description here I was looking for some package like this one: https://www.npmjs.com/package/saturn-datepicker Unfortunately it has been deprecated and currently I cannot find others like that. Do you know something for my purpose? Thank you.
推荐答案
重要更新,太好了!!谷歌有很多像我这样的控件!(记住:谷歌是我的朋友,谷歌是我的朋友...)
IMPORTANT UPDATE, My good!! google is plenty full of controls like mine! (remember: Google is my friend, google is my friend...)
我正在这个 stackblitz,我会在之后尝试解释
I'm making a datePicker range in this stackblitz, i'll try to explain after
更新我改进了stackblitz和简要说明
Update I improve the stackblitz and a brief explanation
mat-date-picker 有一点很重要,即无法创建日模板.所以有必要使用Renderer2来添加监听器、添加类或删除类.我需要使用 document.querySelectorAll,因为它显示在 这是另一个SO
There are a point important with the mat-date-picker that it's not possible create a day-template. So it's necesary use Renderer2 to add listener, add classes or remove classes. I need use document.querySelectorAll as it's show in this another SO
这个想法是,用选定的单元格创建一个对象数组
The idea is, with the cells selected create an array of object
{
date: //will be a getTime of the date,
element: //will be the nativeElement x,
change: //a boolean to indicate this cell has an aditional class
x.listen: //the listener added to allow us remove the listener
}
还有一个函数可以帮助我们根据两个变量添加/删除类:this._dateTo 和另一个变量,即 this._dateFrom 或另一个变量(我们很早就发现了原因)
And a function who help us to add/remove class acording two variables: this._dateTo and another variable that will be this._dateFrom or another one (early we discovered why)
redrawCells(timeTo: number) {
timeTo = timeTo || this._dateTo;
if (timeTo<this._dateFrom)
timeTo=this._dateFrom
this.cells.forEach(x => {
const change = x.date >= this._dateFrom && x.date <= timeTo;
if (change || x.change) {
x.change = change;
const addInside = x.change ? "addClass" : "removeClass";
const addFrom = x.date == this._dateFrom? "addClass":
x.date == timeTo && this._dateFrom==timeTo? "addClass":
"removeClass";
const addTo = x.date == timeTo? "addClass":
x.date == this._dateFrom && this._dateFrom==timeTo? "addClass":
"removeClass";
this.renderer[addInside](x.element, "inside");
this.renderer[addFrom](x.element, "from");
this.renderer[addTo](x.element, "to");
}
});
}
一个新函数 setCell 将管理 td 以添加/删除鼠标悬停的侦听器.必须包含在 setTimeout 中,因为我们在绘制日历之前调用此函数
A new function setCell will be who manage the td to add/remove listener of mouse over. It's necesary enclosed in a setTimeout because we call this function before the calendar is drawed
setCells() {
setTimeout(() => {
if (this.cells) {
this.cells.forEach(x => {
x.listen(); //<---remove the listener
});
}
this.dateOver = null;
//get the elements
let elements = document.querySelectorAll(".calendar");
if (!elements || elements.length == 0) return;
const cells = elements[0].querySelectorAll(".mat-calendar-body-cell");
this.cells = [];
//with each element we fill our array "this.cells"
cells.forEach((x, index) => {
const date = new Date(x.getAttribute("aria-label"));
const time=new Date(date.getFullYear() +"-" +(date.getMonth() + 1) +
"-" +date.getDate()).getTime()
this.cells.push({
date: time,
element: x,
change:time>=this._dateFrom && time<=this._dateTo
});
});
this.cells.forEach(x => {
if (!x.listen) {
//we add a listener "mouseover"
x.listen = this.renderer.listen(x.element, "mouseover", () => {
if (!this._dateTo && this.dateOver != x.date) {
this.dateOver = x.date;
this.redrawCells(this.dateOver); //who call to redrawCells
}
});
}
});
});
}
好吧,解析和格式化日期以及使用 mat-menu 打开 mat-calendar 所需的其余功能来自 这是另一个 SO.在这最后一个 SO 中,日历没有关闭,因此,我们可以使用强制两次点击来获取 dateFrom 和 dateTo
Well, the rest of function necesary to parse and format a date and open a mat-calendar using a mat-menu is from this another SO. In this last SO, the calendar not close, so, we can use to force two clicks to get a dateFrom and a dateTo
select(date: any) {
date = new Date(
date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate()
);
if (
!this.from.value ||
(this.from.value && this.to.value) ||
this._dateFrom > date.getTime()
) {
this.dateFrom = date;
this.dateTo = null;
this.redrawCells(date.getTime());
} else {
this.dateTo = date;
this.trigger.closeMenu();
}
}
我喜欢创建一个 mat 自定义组件.这允许我们在 mat-form-field 中使用组件,比如
I like create a mat custom component. This allow us use the component in a mat-form-field, some like
<mat-form-field class="full-width" >
<mat-label>Select dates</mat-label>
<date-picker-range [formControl]="control" placeholder="DD/MM/YYYY" ></date-picker-range>
<mat-error>required</mat-error>
</mat-form-field>
并允许例如我们使用 [disabled] 来禁用 formControl,并且标签像另一个 mat-input 一样移动.为此,我们需要添加一些功能,请参阅(我保证这是最后一个)这个 最近的SO
And allow e.g. us use [disabled] to disabled the formControl, and the label move like another mat-input. For this we need add some functions, see (I promise it's the last) this last recent SO
注意:控件是原样",没有任何保证,并且允许:批评它、改进、修改、使用或将其作为坏例子
NOTE: The control is "AS IS" without any warranty and it's allowed: critics it, improve, modify, use or put it as bad example
这篇关于带范围选择的角度材料日期选择器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!