Angular + NG-ZORRO 实现自定义年、月、周、日器范围选择器。

由于业务需求,需要实现能根据选择的查询时间类别进行不同类别的查询。上次做的nz-range-picker虽然能够满足需求,但是用起来体验就不是很好。那么我觉得优化用户的体验就是非常必要的,毕竟自己这里都过不了,谈何给别人使用呢?这是上次做的

nz-range-picker:nz-range-picker 默认展示当前月和上个月,不可选用日期为今日之后和180天之前。

根据选择的统计类别不同选择的时间控件也不同,起始时间选择器打开默认展示上一年,结束时间展示当前年(这边做的交互后面代码有,就不做演示了)。

话不多说搞上代码:

1.首先实现下拉选择框:

html:

          <nz-select [(ngModel)]="queryType" [nzMode]="'default'"  [nzAllowClear]="false"
             nzShowSearch nzAllowClear [nzPlaceHolder]="'统计类别'"
            class="inpute-w175 margin7">
            <nz-option *ngFor="let option of selectType" nzCustomContent [nzValue]="option.value"
              [nzLabel]="option.name">
              {{option.name}}
            </nz-option>
          </nz-select>

.ts:

  /**
   * 统计类型
   */
  slectType: Array<{ name: string; value: string }> = [
    {
      name: '按年统计',
      value: '1'
    },
    {
      name: '按季度统计',
      value: '2'
    },
    {
      name: '按月统计',
      value: '3'
    },
    {
      name: '按周统计',
      value: '4'
    },
    {
      name: '按年日统计',
      value: '5'
    },
  ];

/**
   * 选择的统计类型
   */
  queryType: any = '1';
2.实现日期选择器:

html:

          <!-- 下面根据ngif展示对应的事件选择器控件 -->
          <nz-year-picker *ngIf="queryType === '1'" 
            [(ngModel)]="startYear" [nzDisabledDate]="disabledStartYear" (ngModelChange)="onChangeStartYear($event)"
            nzPlaceHolder="开始时间" (nzOnOpenChange)=" handleStartOpenChangeYear($event)">
          </nz-year-picker>
          <nz-month-picker *ngIf="queryType === '2' || queryType === '3'"
            " [(ngModel)]="startMonth" tart
            (ngModelChange)="onChangeStartMonth($event)" [nzDisabledDate]="disabledStartMonth" nzPlaceHolder="开始时间"
            (nzOnOpenChange)=" handleStartOpenChangeMonth($event)">
          </nz-month-picker>
          <nz-week-picker *ngIf="queryType === '4'" 
            nzPlaceHolder="开始时间" [(ngModel)]="startWeek" (ngModelChange)="onChangeStartWeek($event)"
            [nzDisabledDate]="disabledStartWeek" (nzOnOpenChange)=" handleStartOpenChangeWeek($event)">
          </nz-week-picker>
          <nz-date-picker *ngIf="queryType === '5'" 
            nzPlaceHolder="开始时间" [(ngModel)]="startDate" (ngModelChange)="onChangeStartDate($event)"
            [nzDisabledDate]="disabledStartDate" (nzOnOpenChange)=" handleStartOpenChangeDate($event)">
          </nz-date-picker>
          ~
          <nz-year-picker *ngIf="queryType === '1'" 
            [(ngModel)]="endYear" [nzDisabledDate]="disabledEndYear" (ngModelChange)="onChangeEndYear($event)"
            nzPlaceHolder="结束时间" class="margin7">
          </nz-year-picker>
          <nz-month-picker *ngIf="queryType === '2' || queryType === '3'"
            [nzSize]="appService.formInputSize" [(ngModel)]="endMonth" tart (ngModelChange)="onChangeEndMonth($event)"
            [nzDisabledDate]="disabledEndMonth" nzPlaceHolder="结束时间" class="margin7">
          </nz-month-picker>
          <nz-week-picker *ngIf="queryType === '4'" 
            nzPlaceHolder="结束时间" [(ngModel)]="endWeek" (ngModelChange)="onChangeEndWeek($event)"
            [nzDisabledDate]="disabledEndWeek" class="margin7">
          </nz-week-picker>
          <nz-date-picker *ngIf="queryType === '5'" 
            nzPlaceHolder="结束时间" [(ngModel)]="endDate" (ngModelChange)="onChangeEndDate($event)"
            [nzDisabledDate]="disabledEndDate" class="margin7">
          </nz-date-picker>

.ts:这里代码代码比较多,但是方法是一样的,就用年份选择器演示,其余的选择器根据绑定的方法更改一下绑定值就行了。唯一区别:年、月选择器起始时间默认展示去年,周、日选择器起始时间默认展示上月。

  isFirstYear: boolean = true;
  isFirstMonth: boolean = true;
  isFirstWeek: boolean = true;
  isFirstDate: boolean = true; 
/**
   * 年份选择器绑定
   */
  startYear: any = null;

  endYear: any = null;

  startMonth: any = null;

  endMonth: any = null;

  startWeek: any = null;

  endWeek: any = null;

  startDate: any = null;

  endDate: any = null;
/*******************************下面这段用于时间选择器的联动逻辑控制************************************ */

  /**
   * 开始日期数据变动
   */
  onChangeStartYear(date: Date): void {
    this.startYear = date;
    this.isFirstYear = false;
    if (!date) {
      this.isFirstYear = true;
    }
  }

  /**
   * 结束日期数据变动
   */
  onChangeEndYear(date: Date): void {
    this.endYear = date;
  }

  /**
   * 设置开始年份选择器不可选择范围
   */
  disabledStartYear = (startYear: Date): boolean => {
    if (!startYear || !this.endYear) {
      return differenceInCalendarDays(startYear, new Date()) > 0;
    }
    return startYear.getTime() > this.endYear.getTime();
  }

  /**
   * 设置结束年份选择器不可选择范围
   */
  disabledEndYear = (endYear: Date): boolean => {
    if (!endYear || !this.startYear) {
      return differenceInCalendarDays(endYear, new Date()) > 0;
    }
    return endYear.getTime() <= this.startYear.getTime() || differenceInCalendarDays(endYear, new Date()) > 0;
  }

  /**
   *
   * 年份选择器打开的时候控制选择的年份为去年
   * @param {*} e
   * @memberof FinaFlowStatComponent
   */
  handleStartOpenChangeYear(e: any): void {
    // isFirst用于判断是否第一次打开日期面板
    if (e && this.isFirstYear === true) {
      setTimeout(() => {
        const pre: any = document.getElementsByClassName('ant-calendar-year-panel-prev-decade-btn');
        pre[0].click();
      }, 0);
      setTimeout(() => { // 这一段一定要注意,不然会是第一个上翻a标签触发两次。
        const next: any = document.getElementsByClassName('ant-calendar-year-panel-prev-decade-btn');
        if (next[1]) {
          next[1].click();
        }
      }, 10);
    }
  }

//其余省略
/************* */
/*******************************上面这段用于时间选择器的联动逻辑控制************************************ */

 增加一个日期起始时间打开

/**
   * 日期选择器打开的时候控制选择的日期为上月日期
   *
   * @param {*} e
   * @memberof FinaFlowStatComponent
   */
  handleStartOpenChangeDate(e: any): void {
    // isFirstDate用于判断是否第一次打开日期面板
    if (e && this.isFirstDate === true) {
      setTimeout(() => {
        const pre: any = document.getElementsByClassName('ant-calendar-prev-month-btn');
        pre[0].click();
      }, 0);
      setTimeout(() => { // 这一段一定要注意,不然会是第一个上翻a标签触发两次。
        const next: any = document.getElementsByClassName('ant-calendar-prev-month-btn');
        if (next[1]) {
          next[1].click();
        }
      }, 10);
    }
  }  

到这里就差不多结束了,代码是空闲时从项目里整理出来的然后删除了一些东西,简化了一些东西,如果有问题欢迎留言指出,我会进行更正。

成长是一步一步的,可能会很low,但是会越来越好的。

posted @ 2020-09-11 09:41  执念的代码之路  阅读(2471)  评论(0编辑  收藏  举报