Tempus Dominus周视图实现:企业日历功能扩展教程

Tempus Dominus周视图实现:企业日历功能扩展教程

【免费下载链接】tempus-dominus A powerful Date/time picker widget. 【免费下载链接】tempus-dominus 项目地址: https://gitcode.com/gh_mirrors/te/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工具栏,可扩展添加周导航按钮

总结与注意事项

周视图实现需注意以下几点:

  1. 日期计算逻辑:确保周起始日(周一/周日)符合本地化设置,参考localization.startOfTheWeek配置。
  2. 性能优化:周视图仅渲染7个日期单元格,相比月视图性能更优,适合高频更新场景。
  3. 兼容性:需同步更新日期选择逻辑,确保与原生API(如dates.isPicked())兼容。

通过本文方法,可基于Tempus Dominus快速实现企业级周视图日历,满足团队日程管理、排班系统等场景需求。更多高级功能可参考官方文档src/docs/partials/index.html

【免费下载链接】tempus-dominus A powerful Date/time picker widget. 【免费下载链接】tempus-dominus 项目地址: https://gitcode.com/gh_mirrors/te/tempus-dominus

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值