pglejzer / timepicker-ui

timepicker-ui is an easy library with timepicker. Fully wrote with TypeScript. This library is based on Material Design from Google.
MIT License
62 stars 18 forks source link

Can it be used in Angular11? #4

Open duyuxuan opened 3 years ago

q448x commented 3 years ago

I think it is possible but I don't know Angular so I can't help with that right now.

mertdy commented 1 year ago

It is possible with all the versions of Angular. You just need to access the native DOM element in the TS file and create TimepickerUI instance in ngAfterViewInit() hook.

HTML

<div #inputWrapper>
  <input type="text" class="timepicker-ui-input" value="12:00 AM" />
</div>

Typescript

import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core';

import { TimepickerUI } from 'timepicker-ui';

@Component({
  selector: 'app-input-time',
  templateUrl: './input-time.component.html',
  styleUrls: ['./input-time.component.scss']
})
export class InputTimeComponent implements AfterViewInit {
  @ViewChild('inputWrapper') inputWrapper: ElementRef<HTMLDivElement>;

  ngAfterViewInit(): void {
    const timepickerElm = this.inputWrapper?.nativeElement;

    if (timepickerElm) {
      const timepicker = new TimepickerUI(timepickerElm, {
        clockType: '24h'
      });
      timepicker.create();

      timepickerElm.addEventListener('accept', ev => {
        const detail = (ev as CustomEvent).detail as {
          hour: number;
          minutes: number;
        };

        // your input handler should be here
        console.log(detail.hour, detail.minutes)
      });
    }
  }
}
allannienhuis commented 1 year ago

@mertdy I'm using the same approach, and it's mostly working, but for some reason the (input) or (change) events on the input aren't firing for me after the accept event fires. (because I allow the user to also edit the input field via the keyboard, I'd prefer to listen to one event for the updates instead of handling both accept and change events). Are you using either the (input) or (change) events, or are you just not binding to events on the input control?

mertdy commented 1 year ago

@allannienhuis I have the same problem as well. Probably, it is because the library changes the value but does not trigger any event on Input element. Thus, to catch the changes on input, I use the way the library suggests. I have added an example by editing the comment above (addEventListener).

Alternatively, if you want to handle only one event, I suggest you to trigger a custom event manually on the input element. Example:


      timepickerElm.addEventListener('accept', ev => {
        const detail = (ev as CustomEvent).detail as {
          hour: number;
          minutes: number;
        };

        const event = new CustomEvent('input', { detail });
        inputDOMElement.dispatchEvent(event); // you can bring the element by using ViewChild
      });
allannienhuis commented 1 year ago

@mertdy thanks for the reply! triggering a custom event is a great workaround. In my case I'll just trigger a simple string value as that's what the input and change events from keyboard events would fire normally, so I don't have to special case my event handler. But this is a good approach.

Ideally, the library would trigger those events, as it is actually changing the value in the input element. But this is a good workaround. Thanks!