ion-datetime 中的禁用日期(Ionic 4、Ionic 5)
Disabled dates in ion-datetime (Ionic 4, Ionic 5)
我 ion-datetime
实施的方案要求可以禁用某些日期。封锁日期。这在一般应用程序中相当普遍,例如 Airbnb.
据我所知,Ionic 附带的 ion-datetime
模块不支持禁用日期,而且我找不到支持日期和时间的外部库 selection进入 Ionic 和工作的现代迭代。
有没有人以优雅的方式解决这个问题或有任何解决方案使 [Ionic] 本机日期选择器从 select 轮禁用某些 picker-opt 天?
最后我不得不调整自己的解决方案,因为没有线索。我想我会分享这个以防其他人遇到类似情况(直到 Ionic 不可避免地向其核心添加一些东西)。
这些说明假设您已经有了设置阻止日期的解决方案,我建议使用 ion2-calendar(及其多选模式)
所以在你的 HTML 中你会有这样的东西:
<ion-datetime
#orderDatePicker
(click)="setUpListeners()"
(ionChange)="setSelectedDateTime( orderDatePicker.value )"
displayFormat="DD MMM YYYY HH:mm"
max="2021"
minuteValues="0,15,30,45"
[min]="todaysDate"
placeholder="SELECT"></ion-datetime>
您的 TS (underscore) 中需要导入一些内容:
import * as _ from 'underscore/underscore';
并且在您的 TS 文件中,您必须在构造函数上方添加您的默认变量才能普遍使用:
@ViewChild('orderDatePicker', {read: ElementRef}) public orderDatePicker: ElementRef;
dayChangeObserver: any = null;
monthChangeObserver: any = null;
current_month_blockout_dates: any = null;
您需要一种方法来筛选出选定月份的阻止日期。
checkMonth( monthNumber: number ) {
let dates = this.product.blockout_dates;
if(dates) {
let current_dates = dates.filter(dateObj => dateObj.months == monthNumber);
return current_dates;
}
return [];
}
然后你会注意到我在 ion-datetime 的点击事件上设置了一个方法,所以它会设置一些监听器,准确地说是变异观察器。
我已经评论了代码来解释它,但本质上,滚动器使用样式来上下变换它们的 X 轴,因此突变观察者观察这些事件以了解何时进行更改 - 作为本机可用的 ionChange 事件仅在选择过程中触发。
完成 按钮因此显示或隐藏。我正在使用 jQuery 来更快地选择 javascript(至少对我而言)。我还使用下划线工具带对突变观察器进行去抖动,否则它们在滚动时会触发太多次。
setUpListeners() {
const self = this;
if(!this.monthChangeObserver && this.current_month_blockout_dates.length > 0) {
setTimeout(() => {
const day_scroller = $('.picker-col:nth-of-type(1) .picker-opt-selected');
const month_scroller = $('.picker-col:nth-of-type(2) .picker-opt-selected');
// Whenever a month is scrolled
this.monthChangeObserver = new MutationObserver(_.debounce(function() {
let monthNumeric = (1+Number($('.picker-col:nth-of-type(2) .picker-opt-selected').attr('opt-index')));
// Retrieve the blocked dates for the selected month
this.current_month_blockout_dates = self.checkMonth(monthNumeric); // uses 'self' to step outside of mutation scope
let bdates = this.current_month_blockout_dates;
// Enable all days for the current month
$(`.picker-col:nth-of-type(1) button.disabled`).removeClass('disabled');
// Create an array of the blocked days
let bdays = [];
if(bdates.length > 0){
bdates.reduce(function(previousVal, currentVal) { bdays.push(currentVal.date); }, 0);
}
// Cycle through that array and disable those day dates (visually)
if(bdays.length > 0){
bdays.reduce(function(prv, cur) {
$(`.picker-col:nth-of-type(1) .picker-opt[opt-index=${cur}]`).addClass('disabled');
}, 0);
}
// Disable or enable the "Done" button depending on whether or not the selected day is 'disabled' (after month is scrolled)
if($(`.picker-col:nth-of-type(1) button.picker-opt-selected`).hasClass('disabled')) {
$('.picker-toolbar-button:not(.picker-toolbar-cancel)').hide();
} else {
$('.picker-toolbar-button:not(.picker-toolbar-cancel)').show();
}
}, 100));
// Whenever a day is scrolled
this.dayChangeObserver = new MutationObserver(_.debounce(function() {
let selected_day = $('.picker-col:nth-of-type(1) .picker-opt-selected');
let dayNumeric = (1+Number(selected_day.attr('opt-index')));
// Disable or enable the "Done" button depending on whether or not the selected day is 'disabled'
if(selected_day.hasClass('disabled')) {
$('.picker-toolbar-button:not(.picker-toolbar-cancel)').hide();
} else {
$('.picker-toolbar-button:not(.picker-toolbar-cancel)').show();
}
}, 100));
this.dayChangeObserver.observe(day_scroller[0], { attributes : true, attributeFilter : ['style'], childList: false, characterData:false , subtree:false });
this.monthChangeObserver.observe(month_scroller[0], { attributes : true, attributeFilter : ['style'], childList: false, characterData:false , subtree:false });
}, 100); // Slight delay to allow the DOM to render
}
}
最后只需将 CSS 添加到您的 global.scss 文件中:
ion-picker-column {
.picker-opts {
.picker-opt {
&.disabled {
opacity: 0.25;
text-decoration: line-through !important;
}
}
}
}
你可以使用简单的方法 [disabled]="true"
<ion-input placeholder="Pick a due date" [(ngModel)]="selectDate" id="open-date-input-1">
</ion-input>
<ion-modal class="date-time-modal" trigger="open-date-input-1">
<ng-template>
<ion-content>
<ion-datetime showDefaultButtons="true" presentation="date" #popoverDatetime1
(ionChange)="selectDate = formatDate(popoverDatetime1.value)" min="1947-12-30"
pickerFormat="DD MMM YYYY:HH:mm" max="2050-12-31" [disabled]="true">
<div slot="title">Pick a due date</div>
</ion-datetime>
</ion-content>
</ng-template>
</ion-modal>
我 ion-datetime
实施的方案要求可以禁用某些日期。封锁日期。这在一般应用程序中相当普遍,例如 Airbnb.
据我所知,Ionic 附带的 ion-datetime
模块不支持禁用日期,而且我找不到支持日期和时间的外部库 selection进入 Ionic 和工作的现代迭代。
有没有人以优雅的方式解决这个问题或有任何解决方案使 [Ionic] 本机日期选择器从 select 轮禁用某些 picker-opt 天?
最后我不得不调整自己的解决方案,因为没有线索。我想我会分享这个以防其他人遇到类似情况(直到 Ionic 不可避免地向其核心添加一些东西)。
这些说明假设您已经有了设置阻止日期的解决方案,我建议使用 ion2-calendar(及其多选模式)
所以在你的 HTML 中你会有这样的东西:
<ion-datetime
#orderDatePicker
(click)="setUpListeners()"
(ionChange)="setSelectedDateTime( orderDatePicker.value )"
displayFormat="DD MMM YYYY HH:mm"
max="2021"
minuteValues="0,15,30,45"
[min]="todaysDate"
placeholder="SELECT"></ion-datetime>
您的 TS (underscore) 中需要导入一些内容:
import * as _ from 'underscore/underscore';
并且在您的 TS 文件中,您必须在构造函数上方添加您的默认变量才能普遍使用:
@ViewChild('orderDatePicker', {read: ElementRef}) public orderDatePicker: ElementRef;
dayChangeObserver: any = null;
monthChangeObserver: any = null;
current_month_blockout_dates: any = null;
您需要一种方法来筛选出选定月份的阻止日期。
checkMonth( monthNumber: number ) {
let dates = this.product.blockout_dates;
if(dates) {
let current_dates = dates.filter(dateObj => dateObj.months == monthNumber);
return current_dates;
}
return [];
}
然后你会注意到我在 ion-datetime 的点击事件上设置了一个方法,所以它会设置一些监听器,准确地说是变异观察器。
我已经评论了代码来解释它,但本质上,滚动器使用样式来上下变换它们的 X 轴,因此突变观察者观察这些事件以了解何时进行更改 - 作为本机可用的 ionChange 事件仅在选择过程中触发。
完成 按钮因此显示或隐藏。我正在使用 jQuery 来更快地选择 javascript(至少对我而言)。我还使用下划线工具带对突变观察器进行去抖动,否则它们在滚动时会触发太多次。
setUpListeners() {
const self = this;
if(!this.monthChangeObserver && this.current_month_blockout_dates.length > 0) {
setTimeout(() => {
const day_scroller = $('.picker-col:nth-of-type(1) .picker-opt-selected');
const month_scroller = $('.picker-col:nth-of-type(2) .picker-opt-selected');
// Whenever a month is scrolled
this.monthChangeObserver = new MutationObserver(_.debounce(function() {
let monthNumeric = (1+Number($('.picker-col:nth-of-type(2) .picker-opt-selected').attr('opt-index')));
// Retrieve the blocked dates for the selected month
this.current_month_blockout_dates = self.checkMonth(monthNumeric); // uses 'self' to step outside of mutation scope
let bdates = this.current_month_blockout_dates;
// Enable all days for the current month
$(`.picker-col:nth-of-type(1) button.disabled`).removeClass('disabled');
// Create an array of the blocked days
let bdays = [];
if(bdates.length > 0){
bdates.reduce(function(previousVal, currentVal) { bdays.push(currentVal.date); }, 0);
}
// Cycle through that array and disable those day dates (visually)
if(bdays.length > 0){
bdays.reduce(function(prv, cur) {
$(`.picker-col:nth-of-type(1) .picker-opt[opt-index=${cur}]`).addClass('disabled');
}, 0);
}
// Disable or enable the "Done" button depending on whether or not the selected day is 'disabled' (after month is scrolled)
if($(`.picker-col:nth-of-type(1) button.picker-opt-selected`).hasClass('disabled')) {
$('.picker-toolbar-button:not(.picker-toolbar-cancel)').hide();
} else {
$('.picker-toolbar-button:not(.picker-toolbar-cancel)').show();
}
}, 100));
// Whenever a day is scrolled
this.dayChangeObserver = new MutationObserver(_.debounce(function() {
let selected_day = $('.picker-col:nth-of-type(1) .picker-opt-selected');
let dayNumeric = (1+Number(selected_day.attr('opt-index')));
// Disable or enable the "Done" button depending on whether or not the selected day is 'disabled'
if(selected_day.hasClass('disabled')) {
$('.picker-toolbar-button:not(.picker-toolbar-cancel)').hide();
} else {
$('.picker-toolbar-button:not(.picker-toolbar-cancel)').show();
}
}, 100));
this.dayChangeObserver.observe(day_scroller[0], { attributes : true, attributeFilter : ['style'], childList: false, characterData:false , subtree:false });
this.monthChangeObserver.observe(month_scroller[0], { attributes : true, attributeFilter : ['style'], childList: false, characterData:false , subtree:false });
}, 100); // Slight delay to allow the DOM to render
}
}
最后只需将 CSS 添加到您的 global.scss 文件中:
ion-picker-column {
.picker-opts {
.picker-opt {
&.disabled {
opacity: 0.25;
text-decoration: line-through !important;
}
}
}
}
你可以使用简单的方法 [disabled]="true"
<ion-input placeholder="Pick a due date" [(ngModel)]="selectDate" id="open-date-input-1">
</ion-input>
<ion-modal class="date-time-modal" trigger="open-date-input-1">
<ng-template>
<ion-content>
<ion-datetime showDefaultButtons="true" presentation="date" #popoverDatetime1
(ionChange)="selectDate = formatDate(popoverDatetime1.value)" min="1947-12-30"
pickerFormat="DD MMM YYYY:HH:mm" max="2050-12-31" [disabled]="true">
<div slot="title">Pick a due date</div>
</ion-datetime>
</ion-content>
</ng-template>
</ion-modal>