0

When pasting a valid date string into the PrimeNG Calendar control, the value is ignored if there is any surrounding whitespace. When I started looking into this the value would also be ignored even if it was a valid date string until I saw this post.

primeNg input controls context menu paste - ngModel

If I add the following to afterviewinit it will solve the problem of pasting valid dates.

this.calendarRef.inputfieldViewChild.nativeElement.onpaste = (event: ClipboardEvent) => {
    this.calendarRef.isKeydown = true;
}

Now I would like to remove any whitespace for the date string being pasted. Using the calendar.ts source code on GitHub I was able to come up with this.

this.calendarRef.inputfieldViewChild.nativeElement.onpaste = (event: ClipboardEvent) => {
    const clipboardData = event.clipboardData.getData('text').trim();
    this.calendarRef.writeValue(clipboardData );
    this.calendarRef.isKeydown = true;
}

Well this kind of works. I have seen three outcomes. 1. It works as expected 2. It shows the date string twice in the input until the calendar loses focus and then it shows the correct trimmed value 3. it does not work at all.

I have tired other variations using different methods on the calendar.ts component like updateInputfield, updateUI, and updateModel but the results are the same. If anyone has any suggestions for how I can trim the whitespace from a valid date string being pasted into the PrimeNG calendar control your comments would be greatly appreciated.

Thanks

Eric
  • 343
  • 4
  • 14

2 Answers2

1

To handle the paste event in PrimeNG's p-calendar component and update the value accordingly with trim whitespaces, follow these steps:

  1. Implements AfterViewInIt in your component
  2. Add template reference to p-calendar component #calendarRef :
    <p-calendar #calendarRef inputId="basic" [(ngModel)]="date1"></p-calendar>
  1. Create a function to a handle paste event:
 handelPasteEvent(event: ClipboardEvent) {
   setTimeout(() => {
     const input = event.target as HTMLInputElement;
     const pastedValue = input.value;
     const trimmedValue = pastedValue.replace(/\s+/g, ''); // Remove white spaces

     // Update the input value with the trimmed value if necessary
     if (trimmedValue !== pastedValue) {
       this.date1 = new Date(trimmedValue);
     }
   }, 0);
 }
  1. Bind the event to the inputfieldViewChild nativeElement inside the ngAfterViewInIt()
    (this.calendarRef.inputfieldViewChild.nativeElement as HTMLInputElement).addEventListener('paste', this.handelPasteEvent.bind(this));

Mouayad_Al
  • 1,086
  • 2
  • 13
1

The post from Mouayad_Al helped but I ended up doing the following.

@ViewChild('calendarDateStart') calendarDateStartRef: Calendar;

ngAfterViewInit(): void {
    this.calendarDateStartRef.inputfieldViewChild.nativeElement.onpaste = (event: ClipboardEvent) => {
        const clipboardData = event.clipboardData.getData('text')?.trim();
        setTimeout(() => {
            this.dateStart = this.calendarDateStartRef.parseValueFromString(clipboardData) as Date;
        });
        this.calendarDateStartRef.isKeydown = true;
    };
}

I wanted to use the internal code of the Calendar control to create the date just to leverage the PrimeNg code. The downside is that the parseValueFromString() is not part of their public API (as far as I know) so it's subject to change at any time. I also really do NOT like the setTimeout() but it was the only solution I could find that would allow the PrimeNg code to finish before trying to change the date value.

Eric
  • 343
  • 4
  • 14