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,但是會越來越好的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM