aurelia-materialize-bridge
Version:
Aurelia interface to http://materializecss.com/
202 lines (166 loc) • 5.97 kB
text/typescript
import * as au from "../aurelia";
.autoinject
.customElement("md-datepicker")
export class MdDatePicker {
constructor(private element: Element) { }
static id = 0;
controlId: string = `md-datepicker-${MdDatePicker.id++}`;
input: HTMLInputElement;
labelElement: HTMLLabelElement;
inputField: HTMLDivElement;
.ato.bindable.stringMd
label: string = "";
.ato.bindable.booleanMd
inline: boolean;
.ato.bindable.stringMd
placeholder: string = "";
.ato.bindable.booleanMd({ defaultBindingMode: au.bindingMode.oneTime })
autoClose: boolean;
.ato.bindable.stringMd({ defaultBindingMode: au.bindingMode.oneTime })
format: string;
.bindable({ defaultBindingMode: au.bindingMode.oneTime })
parse: (value: string, format: string) => Date;
.bindable({ defaultBindingMode: au.bindingMode.oneTime })
defaultDate: Date;
.ato.bindable.booleanMd({ defaultBindingMode: au.bindingMode.oneTime })
setDefaultDate: boolean;
.ato.bindable.booleanMd({ defaultBindingMode: au.bindingMode.oneTime })
disableWeekends: boolean;
.bindable({ defaultBindingMode: au.bindingMode.oneTime })
disableDayFn: (day: Date) => boolean;
.ato.bindable.numberMd({ defaultBindingMode: au.bindingMode.oneTime })
firstDay: number;
.bindable({ defaultBindingMode: au.bindingMode.oneTime })
minDate: Date;
.bindable({ defaultBindingMode: au.bindingMode.oneTime })
maxDate: Date;
.bindable({ defaultBindingMode: au.bindingMode.oneTime })
yearRange: number | number[];
.ato.bindable.booleanMd({ defaultBindingMode: au.bindingMode.oneTime })
isRtl: boolean;
.ato.bindable.booleanMd({ defaultBindingMode: au.bindingMode.oneTime })
showMonthAfterYear: boolean;
.ato.bindable.booleanMd({ defaultBindingMode: au.bindingMode.oneTime })
showDaysInNextAndPreviousMonths: boolean;
.bindable({ defaultBindingMode: au.bindingMode.oneTime })
container: Element | string;
.ato.bindable.booleanMd({ defaultBindingMode: au.bindingMode.oneTime })
showClearBtn: boolean;
.bindable({ defaultBindingMode: au.bindingMode.oneTime })
i18n: Partial<M.InternationalizationOptions>;
.bindable({ defaultBindingMode: au.bindingMode.oneTime })
events: string[];
.ato.bindable.booleanMd
showErrortext: boolean = true;
instance: M.Datepicker;
.bindable({ defaultBindingMode: au.bindingMode.twoWay })
value: Date;
valueChangedSuppress: boolean;
valueChanged() {
if (this.valueChangedSuppress) {
this.valueChangedSuppress = false;
au.updateLabel(this.input, this.labelElement);
return;
}
if (!this.instance) {
return;
}
this.instance.setDate(this.value);
// suppress done handler because setInputValue will trigger it, change value and possibly cause an infinite loop when a date has time components
this.suppressDone = true;
this.instance.setInputValue();
au.updateLabel(this.input, this.labelElement);
}
setValue(newValue: Date) {
if (this.value !== newValue) {
this.valueChangedSuppress = true;
this.value = newValue;
}
}
calendarIcon = null;
attached() {
if (this.placeholder) {
this.input.setAttribute("placeholder", this.placeholder);
}
let container = typeof this.container === "string" ? document.querySelector(this.container) : this.container;
let options: Partial<M.DatepickerOptions> = {
autoClose: this.autoClose,
format: this.format,
parse: this.parse,
defaultDate: this.defaultDate,
setDefaultDate: this.setDefaultDate,
disableWeekends: this.disableWeekends,
disableDayFn: this.disableDayFn,
firstDay: this.firstDay,
minDate: this.minDate,
maxDate: this.maxDate,
yearRange: this.yearRange,
isRTL: this.isRtl,
showMonthAfterYear: this.showMonthAfterYear,
showDaysInNextAndPreviousMonths: this.showDaysInNextAndPreviousMonths,
container,
showClearBtn: this.showClearBtn,
i18n: this.i18n,
events: this.events,
onSelect: selectedDate => au.fireMaterializeEvent(this.element, "select", { selectedDate }),
onOpen: () => au.fireMaterializeEvent(this.element, "open"),
onClose: () => au.fireMaterializeEvent(this.element, "close"),
onDraw: () => au.fireMaterializeEvent(this.element, "draw")
};
au.cleanOptions(options);
this.instance = new M.Datepicker(this.input, options);
this.instance.el.addEventListener("change", this.done);
this.element.mdUnrenderValidateResults = this.mdUnrenderValidateResults;
this.element.mdRenderValidateResults = this.mdRenderValidateResults;
this.valueChanged();
}
suppressDone: boolean;
done = (e: Event) => {
// we're only interested in events generated by the widget
if ((e as any).firedBy !== this.instance) {
return;
}
// stop propagation for widget triggered change to retrigger it later on an the element
e.stopPropagation();
if (this.suppressDone) {
this.suppressDone = false;
return;
}
this.setValue(this.instance.date);
au.fireEvent(this.element, "blur");
au.fireEvent(this.element, "change");
}
bind() {
//
}
detached() {
au.MaterializeFormValidationRenderer.removeValidation(this.inputField, this.input);
this.instance.destroy();
this.element.mdUnrenderValidateResults = undefined;
this.element.mdRenderValidateResults = undefined;
}
open() {
this.instance.open();
}
close() {
this.instance.close();
}
mdUnrenderValidateResults = (results: au.ValidateResult[], renderer: au.MaterializeFormValidationRenderer) => {
for (let result of results) {
if (!result.valid) {
renderer.removeMessage(this.inputField, result);
}
}
renderer.removeValidationClasses(this.input);
}
mdRenderValidateResults = (results: au.ValidateResult[], renderer: au.MaterializeFormValidationRenderer) => {
if (this.showErrortext && this.inputField) {
for (let result of results) {
if (!result.valid) {
renderer.addMessage(this.inputField, result);
}
}
}
renderer.addValidationClasses(this.input, !results.find(x => !x.valid));
}
}