This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/app/components/date-input.js
2021-11-14 10:59:05 +01:00

168 lines
4.0 KiB
JavaScript

/* global Pikaday:true */
import discourseComputed, { on } from "discourse-common/utils/decorators";
import Component from "@ember/component";
import I18n from "I18n";
import { Promise } from "rsvp";
import { action } from "@ember/object";
import loadScript from "discourse/lib/load-script";
import { schedule } from "@ember/runloop";
function isInputDateSupported() {
const input = document.createElement("input");
const value = "a";
input.setAttribute("type", "date");
input.setAttribute("value", value);
return input.value !== value;
}
export default Component.extend({
classNames: ["d-date-input"],
date: null,
_picker: null,
@discourseComputed("site.mobileView")
inputType() {
return this.useNativePicker ? "date" : "text";
},
useNativePicker: isInputDateSupported(),
click(event) {
event.stopPropagation();
},
didInsertElement() {
this._super(...arguments);
schedule("afterRender", () => {
if (!this.element || this.isDestroying || this.isDestroying) {
return;
}
let promise;
const container = document.getElementById(this.containerId);
if (this.useNativePicker) {
promise = this._loadNativePicker(container);
} else {
promise = this._loadPikadayPicker(container);
}
promise.then((picker) => {
this._picker = picker;
if (this._picker && this.date) {
this._picker.setDate(moment(this.date).toDate(), true);
}
});
});
},
didUpdateAttrs() {
this._super(...arguments);
if (this._picker && this.date) {
this._picker.setDate(moment(this.date).toDate(), true);
}
if (this._picker && this.relativeDate) {
this._picker.setMinDate(moment(this.relativeDate).toDate(), true);
}
if (this._picker && !this.date) {
this._picker.setDate(null);
}
},
_loadPikadayPicker(container) {
return loadScript("/javascripts/pikaday.js").then(() => {
let defaultOptions = {
field: this.element.querySelector(".date-picker"),
container: container || this.element.querySelector(".picker-container"),
bound: container === null,
format: "LL",
firstDay: 1,
i18n: {
previousMonth: I18n.t("dates.previous_month"),
nextMonth: I18n.t("dates.next_month"),
months: moment.months(),
weekdays: moment.weekdays(),
weekdaysShort: moment.weekdaysShort(),
},
onSelect: (date) => this._handleSelection(date),
};
if (this.relativeDate) {
defaultOptions = Object.assign({}, defaultOptions, {
minDate: moment(this.relativeDate).toDate(),
});
}
return new Pikaday(Object.assign({}, defaultOptions, this._opts()));
});
},
_loadNativePicker(container) {
const wrapper = container || this.element;
const picker = wrapper.querySelector("input.date-picker");
picker.onchange = () => this._handleSelection(picker.value);
picker.hide = () => {
/* do nothing for native */
};
picker.destroy = () => {
/* do nothing for native */
};
picker.setDate = (date) => {
picker.value = date ? moment(date).format("YYYY-MM-DD") : null;
};
picker.setMinDate = (date) => {
picker.min = date;
};
if (this.date) {
picker.setDate(this.date);
}
return Promise.resolve(picker);
},
_handleSelection(value) {
if (!this.element || this.isDestroying || this.isDestroyed) {
return;
}
if (this.onChange) {
this.onChange(value ? moment(value) : null);
}
},
@on("willDestroyElement")
_destroy() {
if (this._picker) {
this._picker.destroy();
this._picker = null;
}
},
@discourseComputed("_placeholder")
placeholder: {
get(_placeholder) {
return _placeholder || I18n.t("dates.placeholder");
},
set(value) {
this.set("_placeholder", value);
return value;
},
},
_opts() {
return null;
},
@action
onChangeDate(event) {
this._handleSelection(event.target.value);
},
});