Custom element to wrap Pikaday

I’m pretty much novice to Aurelia. I’m trying to wrap the Pikaday Date picker.

I started like this:

<!--calendar.html-->
<template>
  <input type="text" ref="calendar" readonly="true" /> 
</template> 

and:

// calendar.ts
import { bindable, bindingMode } from "aurelia-framework";

import * as Pikaday from "pikaday/pikaday";

export class CalendarCustomElement {
  @bindable({ defaultBindingMode: bindingMode.twoWay }) date: Date;
  calendar: Element;

  attached() {
    const picker = new Pikaday({
      field: this.calendar,
      format: "YYYY-MM-DD",
      keyboardInput: true,
       onSelect: date => {
         this.date = date;
       }
    });
    picker.setDate(this.date);
  }
}

I use it like this:

<!--example.html-->
<require from="./calendar"></require>
<calendar date.bind="day"></calendar>

I would like to be be call the clear method of the picker from example.ts. How could I implement this?

Another question, I tried to set the value of day from example.ts. To take the change into account, I tried to add a dateChanged method on CalendarCustomElement that this.picker.setDate(newValue) but it seems to make infinite loop between onSelect and dateChanged. I could test equality of newValue and oldValue, but I think that should be simpler, something better like React one way data flow. What would be the good approach?

Thanks!

1 Like

For the first question, just found that I can do:

<calendar date.bind="day" view-model.ref="calendar"></calendar>

and then:

this.calendar.picker.clear();
1 Like

Havent looked into the library but If you can get hold of the event in the onselected method you could check for isTrusted https://developer.mozilla.org/en-US/docs/Web/API/Event/isTrusted

1 Like

Note, to be safe, you’d better cleanup the instance you created to avoid possible memory leak.

attached() {
  this.picker = new Pickaday({...});
}
detached() {
  if (this.picker) {
    this.picker.destroy();
    delete this.picker; // or this.picker = undefined;
  }
}
1 Like