期间模式需要datepicker

时间:2017-07-10 13:57:25

标签: angular datepicker required

我的datepicker中有required属性。如果我触摸了日期选择器而我没有选择任何内容,那就无效了。这是一个公认的场景,我想要那样。

但是,如果我只选择一个日期并退出日期选择器,那也是有效的,但我希望它只有在日期是一个句点时才有效。

我的datepicker有很多代码。因此,创造Plunker更舒适。

我使用我的组件:

 <div style="width: 200px;">
  <mae-datepicker mode="period" [(ngModel)]="period" label="Period picker" required></mae-datepicker>
</div>

&#13;
&#13;
// tslint:disable:no-forward-ref
@Component({
  selector: 'mae-datepicker',
  templateUrl: './datepicker.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => DatepickerComponent),
      multi: true
    },
    DatepickerService
  ],
  host: {
    class: 'datepicker input-form',
    '[attr.tabindex]': 'getTabIndex()'
  }
})
export class DatepickerComponent implements AfterViewInit, OnInit, OnChanges, OnDestroy, ControlValueAccessor {

  @Input('required') isRequired: boolean = false
  @Input() mode: string

  @Input() availableDates: Date[]
  @Input() availableDatesFn: (d: Date) => boolean
  @Input() minDate: Date
  @Input() maxDate: Date

  @Output() onClose: EventEmitter<any> = new EventEmitter()

  @ViewChild('datePickerPopup') datePickerPopup: DropdownDirective

  selectionLabel: string
  subscriptions: Subscription[] = []

  private _model: Date | Date[]
  private initialized: boolean = false

  constructor(
    private datepickerService: DatepickerService,
    private cd: ChangeDetectorRef,
    private ms: MomentService,
    private _elementRef: ElementRef
  ) {
  }

 
  ngOnInit() {
    if (!this.model) {
      // init placeholder
      this.model = null
    }
    if (!this.initialized) {
      this.datepickerService.update(this.isRequired, this.availableDates, this.availableDatesFn, this.minDate, this.maxDate)
      this.initialized = true
    }
    if (this.mode === 'period') {
      this.datepickerService.updateSelectedPeriod(this.model ? this.model[0] : null, this.model ? this.model[1] : null)
    } else {
      this.datepickerService.updateSelectedDate(this.model)
    }
  ngOnChanges(): void {
    this.isRequired = this.isRequired !== undefined && this.isRequired !== false
    this.datepickerService.update(this.isRequired, this.availableDates, this.availableDatesFn, this.minDate, this.maxDate)
  }

  set model(val: Date | Date[]) {
    if (val === this._model) {
      return
    }
    this.updateModel(val)
    this.onChange(val)
  }

  get model() {
    return this._model
  }

  _updateDisplayedLabel(): void {
    let val = this.model
    if (this.mode === 'period') {
      if (!Array.isArray(val) || val.length !== 2 || !val[0] || !val[1] ) {
        this.selectionLabel = this.placeholder
      } else {
        this.selectionLabel = this.format(val[0]) + ' - ' + this.format(val[1])
      }
    } 
  }

  updateModel(val: any) {
    this._model = val
    if (this.mode === 'period') {
      //noinspection TypeScriptUnresolvedVariable
      if (!Array.isArray(val) || val.length !== 2) {
        val = [null, null]
      }
      this.datepickerService.updateSelectedPeriod(val[0], val[1])
    } }

  public selectDate = (date) => {
    if (this.mode === 'period') {
      const dates = this.model ? [this.model[0], this.model[1]] : [null, null]
      if (!dates[0] || dates[1]) {
        dates[0] = date
        dates[1] = null
      } else {
        dates[1] = date
      }
      if (dates[0] && dates[1] && dates[0].getTime() > dates[1].getTime()) {
        const d = dates[0]
        dates[0] = dates[1]
        dates[1] = d
      }
      this.model = dates
    } else if (this.mode === 'multi') {
      if (!this.model) {
        this.model = [date]
      } else {
        const idx = (<Date[]> this.model).map(d => d.getTime()).indexOf(date.getTime())
        const dates = [...(<Date[]> this.model)]
        if (idx >= 0) {
          dates.splice(idx, 1)
        } else {
          dates.push(date)
        }
        this.model = dates
      }
    } else {
      this.model = date
      this.closePopup()
    }
  }
}
&#13;
**#datepicker.service.ts#**

import { Injectable } from '@angular/core'

import { MomentService } from '../../../shared/services/moment.service'

export interface DatepickerDay {
  currentMonth: boolean,
  date: Date,
  dateOfMonth: number,
  disabled: boolean
  inPeriod?: boolean,
  selected?: boolean,
  selectedPeriodStart: boolean,
  selectedPeriodEnd: boolean,
  today: boolean
}

@Injectable()
export class DatepickerService {
  public currentYear
  public currentMonth
  public currentDay
  public monthDays: DatepickerDay[] = []

  // mode === period
  private selectedPeriodStart
  private selectedPeriodEnd

  private notNull

  constructor(

  public update(required: boolean, availableDates: Date[], availableDatesFn: (d: Date) => boolean, minDate: Date, maxDate: Date) {
    this.notNull = required
    this.minAvailableDate = minDate ? this.ms.moment(minDate).startOf('day') : null
    this.maxAvailableDate = maxDate ? this.ms.moment(maxDate).startOf('day') : null
    this.updateMonthDays()
  }


  public updateSelectedPeriod = (selectedPeriodStart, selectedPeriodEnd) => {
    if (selectedPeriodStart
      && this.isAvailable(selectedPeriodStart)) {
      this.selectedPeriodStart = this.ms.moment(selectedPeriodStart).startOf('day')
    } else {
      this.selectedPeriodStart = selectedPeriodStart
    }
    if (selectedPeriodEnd
      && this.isAvailable(selectedPeriodEnd)) {
      this.selectedPeriodEnd = this.ms.moment(selectedPeriodEnd).startOf('day')
      this.currentYear = this.selectedPeriodEnd.year()
      this.currentMonth = this.selectedPeriodEnd.month()
    } else {
      this.selectedPeriodEnd = null
    }
    this.updateMonthDays()
  }
 
}
&#13;
&#13;
&#13;

谢谢!

0 个答案:

没有答案