jquery-ui datepicker with Aurelia

A question comes up quite often in the Aurelia gitter:

How do I data-bind a jQuery-UI datepicker???

All it the datepicker does is add some behavior to an input element... Aurelia handles data-binding input elements... why isn't my view-model property updated when I pick a date in the widget's calendar?

When you bind an input element's value property, Aurelia listens for the change and input DOM events. When these events fire the Aurelia binding system will write the element's value to the model.

The problem is these events only fire when the input's value is changed by the user, not when the input's value is changed by the jQuery-UI datepicker code.

Solution

There's a simple work-around: listen for jQuery's version of the change event and publish a DOM event to notify the Aurelia binding system.

Here's a datepicker custom attribute that uses this approach:

import {inject, customAttribute} from 'aurelia-framework';

@customAttribute('datepicker')
@inject(Element)
export class DatePicker {  
  constructor(element) {
    this.element = element;
  }

  attached() {
    $(this.element).datepicker()
      .on('change', e => fireEvent(e.target, 'input'));

  }

  detached() {
    $(this.element).datepicker('destroy')
      .off('change');
  }
}

function createEvent(name) {  
  var event = document.createEvent('Event');
  event.initEvent(name, true, true);
  return event;
}

function fireEvent(element, name) {  
  var event = createEvent(name);
  element.dispatchEvent(event);
}



The attribute will allow you convert an input into a bindable datepicker. Here's how it's used:

<input datepicker value.bind="dateValue">  



Here's a live sample in the Aurelia Plunker: