Tempus Dominus周视图实现:企业日历功能扩展教程
企业级应用中,传统月视图日历难以满足团队日程管理需求。Tempus Dominus作为功能强大的日期时间选择器组件,虽原生未提供周视图,但可通过扩展实现企业级周视图功能。本文将详细介绍如何基于Tempus Dominus实现周视图,包括视图渲染、日期选择与企业级功能扩展。
周视图实现基础
Tempus Dominus的日期显示逻辑主要由DateDisplay类控制,该类负责日历网格的创建与更新。核心文件为src/js/display/calendar/date-display.ts,其中getPicker()方法构建日历容器,_update()方法处理日期渲染与状态更新。
周视图实现需修改日历网格生成逻辑,将默认的月视图(42天网格)调整为周视图(7天网格)。原月视图通过循环生成42个日期单元格(6行×7列),周视图需改为仅生成7个单元格(1行×7列),并调整日期导航逻辑。
图:Tempus Dominus原生月视图,周视图将基于此结构改造
核心代码实现
1. 修改日历容器生成
在DateDisplay类的getPicker()方法中,调整日期单元格生成逻辑,仅创建7个单元格:
// 修改src/js/display/calendar/date-display.ts
getPicker(): HTMLElement {
const container = document.createElement('div');
container.classList.add(Namespace.css.daysContainer);
container.append(...this._daysOfTheWeek());
if (this.optionsStore.options.display.calendarWeeks) {
const div = document.createElement('div');
div.classList.add(Namespace.css.calendarWeeks, Namespace.css.noHighlight);
container.appendChild(div);
}
const { rangeHoverEvent, rangeHoverOutEvent } = this.handleMouseEvents(container);
// 周视图仅生成7个日期单元格
for (let i = 0; i < 7; i++) {
if (i !== 0 && i % 7 === 0) {
if (this.optionsStore.options.display.calendarWeeks) {
const div = document.createElement('div');
div.classList.add(Namespace.css.calendarWeeks, Namespace.css.noHighlight);
container.appendChild(div);
}
}
const div = document.createElement('div');
div.setAttribute('data-action', ActionTypes.selectDay);
container.appendChild(div);
if (matchMedia('(hover: hover)').matches && this.optionsStore.options.dateRange) {
div.addEventListener('mouseover', rangeHoverEvent);
div.addEventListener('mouseout', rangeHoverOutEvent);
}
}
return container;
}
2. 调整日期渲染逻辑
在_update()方法中,修改日期生成范围,仅显示当前周的日期:
// 修改src/js/display/calendar/date-display.ts
_update(widget: HTMLElement, paint: Paint): void {
const container = widget.getElementsByClassName(Namespace.css.daysContainer)[0] as HTMLElement;
this._updateCalendarView(container);
// 周视图:从当前视图日期的周一(或周日)开始,生成7天
const startOfWeek = this.optionsStore.viewDate.clone
.startOf('weekDay', this.optionsStore.options.localization.startOfTheWeek)
.manipulate(12, Unit.hours);
const endOfWeek = startOfWeek.clone.manipulate(6, Unit.date);
this._handleCalendarWeeks(container, startOfWeek.clone);
container.querySelectorAll(`[data-action="${ActionTypes.selectDay}"]`).forEach((element: HTMLElement, index) => {
const currentDate = startOfWeek.clone.manipulate(index, Unit.date);
const classes: string[] = [Namespace.css.day];
// 日期状态处理(选中、禁用、今天等)
if (!this.optionsStore.unset && !this.optionsStore.options.dateRange && this.dates.isPicked(currentDate, Unit.date)) {
classes.push(Namespace.css.active);
}
if (!this.validation.isValid(currentDate, Unit.date)) {
classes.push(Namespace.css.disabled);
}
if (currentDate.isSame(new DateTime(), Unit.date)) {
classes.push(Namespace.css.today);
}
if (currentDate.weekDay === 0 || currentDate.weekDay === 6) {
classes.push(Namespace.css.weekend);
}
this._handleDateRange(currentDate, classes);
paint(Unit.date, currentDate, classes, element);
element.classList.remove(...element.classList);
element.classList.add(...classes);
element.setAttribute('data-value', this._dateToDataValue(currentDate));
element.setAttribute('data-day', `${currentDate.date}`);
element.innerText = currentDate.date.toString();
});
}
3. 配置周视图显示选项
在src/docs/partials/options/display.html中,添加周视图配置选项:
<div class='row'>
<h2 id='viewMode'>viewMode<a class='anchor-link' aria-label='Anchor' href='#viewMode'><i
class='fa-solid fa-anchor' aria-hidden='true'></i></a></h2>
<p>
<strong>Accepts:</strong> 'clock' | 'calendar' | 'months' | 'years' | 'decades' | 'week'
<strong>Defaults:</strong> calendar<br />
添加'week'选项以启用周视图。
</p>
</div>
企业级功能扩展
1. 日期范围选择限制
企业应用中常需限制可选择的日期范围,例如仅允许选择未来7天内的日期。可通过配置restrictions选项实现,核心文件为src/docs/partials/options/restrictions.html。
new tempusDominus.TempusDominus(document.getElementById('datetimepicker'), {
display: {
viewMode: 'week' // 启用周视图
},
restrictions: {
minDate: new Date(), // 最小日期为今天
maxDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 最大日期为7天后
daysOfWeekDisabled: [0, 6] // 禁用周末
}
});
2. 周数显示与ISO周历支持
Tempus Dominus支持显示周数,通过配置calendarWeeks: true启用,效果如图所示:
图:启用周数显示的日历视图,周视图可结合此功能显示当前周编号
配置代码:
new tempusDominus.TempusDominus(document.getElementById('datetimepicker'), {
display: {
viewMode: 'week',
calendarWeeks: true // 显示周数
}
});
3. 多日期选择与事件标记
企业日历常需支持多日期选择与事件标记,可通过扩展Paint接口实现。在_update()方法中,通过paint()函数自定义日期单元格样式,标记包含事件的日期:
// 自定义事件标记逻辑
paint(Unit.date, currentDate, classes, element) {
// 检查当前日期是否包含事件(示例:从API获取事件数据)
const hasEvent = eventData.some(event =>
new Date(event.date).toDateString() === currentDate.toDate().toDateString()
);
if (hasEvent) {
element.classList.add('has-event');
element.title = '包含事件';
}
}
集成与使用指南
1. 引入周视图配置
修改初始化代码,设置viewMode: 'week'启用周视图:
<div class="input-group" id="datetimepicker" data-td-target-input="nearest" data-td-target-toggle="nearest">
<input type="text" class="form-control" data-td-target="#datetimepicker" />
<span class="input-group-text" data-td-target="#datetimepicker" data-td-toggle="datetimepicker">
<span class="fa-solid fa-calendar"></span>
</span>
</div>
<script>
new tempusDominus.TempusDominus(document.getElementById('datetimepicker'), {
display: {
viewMode: 'week', // 启用周视图
calendarWeeks: true // 显示周数
}
});
</script>
2. 导航控制扩展
周视图需添加周导航按钮,通过修改工具栏实现。参考src/docs/assets/toolbar.png中的工具栏结构,添加“上一周”和“下一周”按钮:
图:Tempus Dominus工具栏,可扩展添加周导航按钮
总结与注意事项
周视图实现需注意以下几点:
- 日期计算逻辑:确保周起始日(周一/周日)符合本地化设置,参考
localization.startOfTheWeek配置。 - 性能优化:周视图仅渲染7个日期单元格,相比月视图性能更优,适合高频更新场景。
- 兼容性:需同步更新日期选择逻辑,确保与原生API(如
dates.isPicked())兼容。
通过本文方法,可基于Tempus Dominus快速实现企业级周视图日历,满足团队日程管理、排班系统等场景需求。更多高级功能可参考官方文档src/docs/partials/index.html。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考






