xambey

Datepicker with custom ControlValueAccessor

Nov 30th, 2020
100
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. @Component({
  2.   selector: 'adm-datepicker',
  3.   templateUrl: './datepicker.component.html',
  4.   styleUrls: ['./datepicker.component.less'],
  5.   providers: [
  6.     {
  7.       provide: NG_VALUE_ACCESSOR,
  8.       useExisting: forwardRef(() => DatepickerComponent),
  9.       multi: true,
  10.     },
  11.   ],
  12.   // viewProviders: [
  13.   //   {
  14.   //     provide: ControlContainer,
  15.   //     useFactory: (container: ControlContainer) => container,
  16.   //     deps: [[ControlContainer, new Optional(), new Host(), new SkipSelf()]]
  17.   //   }
  18.   // ],
  19.   changeDetection: ChangeDetectionStrategy.OnPush
  20. })
  21. export class DatepickerComponent implements OnInit, OnDestroy, ControlValueAccessor {
  22.   onChange: (value: Date) => void;
  23.   onTouched: () => void;
  24.  
  25.   @Input() maskConfig: TextMaskConfig = {
  26.     mask: false
  27.   };
  28.   Icons = Icons;
  29.  
  30.   @ViewChild(BsDatepickerDirective, { static: true })
  31.   protected bsDatepickerDirective: BsDatepickerDirective;
  32.   /**
  33.    * Filter on paste from clipboard
  34.    */
  35.   @Input() inputFilter: InputFilter;
  36.   /**
  37.    * Placeholder
  38.    */
  39.   @Input() placeholder: string;
  40.   /**
  41.    * Size of input field
  42.    */
  43.   @Input() nzSize: NzSizeLDSType = 'default';
  44.   /**
  45.    * Disable input field
  46.    */
  47.   @Input() disabled: boolean;
  48.   /**
  49.    * Config object for datepicker
  50.    */
  51.   @Input() bsConfig: Partial<BsDatepickerConfig> = {
  52.     dateInputFormat: DateTimeFormat.DATE,
  53.   };
  54.   /**
  55.    * Placement of a datepicker. Accepts: "top", "bottom", "left", "right"
  56.    */
  57.   @Input() placement: 'top' | 'bottom' | 'left' | 'right' = 'bottom';
  58.   /**
  59.    * Specifies events that should trigger. Supports a space separated list of
  60.    * event names.
  61.    */
  62.   @Input() triggers: string = 'click';
  63.   /**
  64.    * Close datepicker on outside click
  65.    */
  66.   @Input() outsideClick: boolean = true;
  67.   /**
  68.    * A selector specifying the element the datepicker should be appended to.
  69.    */
  70.   @Input() container: string = 'body';
  71.   /**
  72.    * Close picker on click ESC button
  73.    */
  74.   @Input() outsideEsc: boolean = true;
  75.   /**
  76.    * Minimum date which is available for selection
  77.    */
  78.   @Input() minDate: Date;
  79.   /**
  80.    * Maximum date which is available for selection
  81.    */
  82.   @Input() maxDate: Date;
  83.   /**
  84.    * Minimum view mode : day, month, or year
  85.    */
  86.   @Input() minMode: BsDatepickerViewMode;
  87.   /**
  88.    * Disable Certain days in the week
  89.    */
  90.   @Input() daysDisabled: number[];
  91.   /**
  92.    * Disable specific dates
  93.    */
  94.   @Input() datesDisabled: Date[];
  95.   /**
  96.    * Enable specific dates
  97.    */
  98.   @Input() datesEnabled: Date[];
  99.   /**
  100.    * Date custom classes
  101.    */
  102.   @Input() dateCustomClasses: DatepickerDateCustomClasses[];
  103.   /**
  104.    * Emits an event when the datepicker is shown
  105.    */
  106.   @Output() onShown: EventEmitter<any> = new EventEmitter<any>();
  107.   /**
  108.    * Emits an event when the datepicker is hidden
  109.    */
  110.   @Output() onHidden: EventEmitter<any> = new EventEmitter<any>();
  111.   value: Date;
  112.   /**
  113.    *
  114.    */
  115.   set bsValue(value: Date) {
  116.     if(value !== this.value) {
  117.       this.value = this.normalizeValue(value);
  118.  
  119.       // if (isNaN(this.value.getTime())) {
  120.       //   this?.ngControl?.control?.setErrors({
  121.       //     invalid: 'Неверный формат даты'
  122.       //   });
  123.       // } else {
  124.       //   this?.ngControl?.control?.setErrors({ });
  125.       // }
  126.       //
  127.       // this?.ngControl?.control?.setValue?.(this.value);
  128.       // this?.ngControl?.control?.markAsTouched({ onlySelf: true });
  129.  
  130.       this.onChange?.(this.value);
  131.     }
  132.   }
  133.   get bsValue(): Date {
  134.     return this.value;
  135.   }
  136.   /**
  137.    * Picker's value
  138.    */
  139.   /**
  140.    * Returns whether or not the datepicker is currently being shown
  141.    */
  142.   get isOpen(): boolean {
  143.     return this?.bsDatepickerDirective?.isOpen;
  144.   }
  145.   /**
  146.    * Indicates whether datepicker's content is enabled or not
  147.    */
  148.   get isDisabled(): boolean {
  149.     return this?.bsDatepickerDirective?.isDisabled;
  150.   }
  151.   set isDisabled(value: boolean) {
  152.     this.bsDatepickerDirective.isDisabled = value;
  153.   }
  154.  
  155.   constructor(
  156.     protected bsLocaleService: BsLocaleService,
  157.     protected cdr: ChangeDetectorRef,
  158.     // @Optional() @Self() protected ngControl: NgControl,
  159.   ) {
  160.     // ngControl.valueAccessor = this;
  161.   }
  162.  
  163.   ngOnDestroy(): void {
  164.         throw new Error('Method not implemented.');
  165.     }
  166.  
  167.   ngOnInit() {
  168.     this.bsLocaleService.use('ru');
  169.  
  170.     // this?.ngControl?.control?.setValidators()
  171.     // this?.ngControl?.valueChanges?.pipe?.(
  172.     //   untilDestroyed(this)
  173.     // ).subscribe(value => this.writeValue(value));
  174.   }
  175.  
  176.   /**
  177.    * Opens an element’s datepicker. This is considered a “manual” triggering of the datepicker.
  178.    */
  179.   show() {
  180.     this?.bsDatepickerDirective?.show?.();
  181.     this.detectChanges();
  182.   }
  183.  
  184.   /**
  185.    * Closes an element’s datepicker. This is considered a “manual” triggering of the datepicker.
  186.    */
  187.   hide() {
  188.     this?.bsDatepickerDirective?.hide?.();
  189.     this.detectChanges();
  190.   }
  191.  
  192.   /**
  193.    * Toggles an element’s datepicker. This is considered a “manual” triggering of the datepicker.
  194.    */
  195.   toggle() {
  196.     this?.bsDatepickerDirective?.toggle?.();
  197.     this.detectChanges();
  198.   }
  199.  
  200.   detectChanges() {
  201.     this.cdr.markForCheck();
  202.   }
  203.  
  204.   registerOnChange(fn: any): void {
  205.     this.onChange = fn;
  206.   }
  207.  
  208.   registerOnTouched(fn: any): void {
  209.     this.onTouched = fn;
  210.   }
  211.  
  212.   setDisabledState(isDisabled: boolean): void {
  213.     this.disabled = isDisabled;
  214.     this.isDisabled = isDisabled;
  215.  
  216.     this.detectChanges();
  217.   }
  218.  
  219.   protected normalizeValue(value: Date) {
  220.     if (value) {
  221.       return typeof value === 'string' ? new Date(value) : value;
  222.     }
  223.  
  224.     return null;
  225.   }
  226.  
  227.   writeValue(value: Date): void {
  228.     if(value !== this.value) {
  229.       this.value = this.normalizeValue(value);
  230.       this.detectChanges();
  231.     }
  232.   }
  233.  
  234.   @HostListener('blur')
  235.   onBlur() {
  236.     this?.onTouched?.();
  237.     // this?.ngControl?.control?.markAsTouched({ onlySelf: true });
  238.   }
  239. }
  240.  
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×