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,但是会越来越好的。