Skip to content

Instantly share code, notes, and snippets.

@scorredoira
Created November 7, 2021 19:34
Show Gist options
  • Save scorredoira/7b43a7c291eeee90eff7fcbaa07eced1 to your computer and use it in GitHub Desktop.
Save scorredoira/7b43a7c291eeee90eff7fcbaa07eced1 to your computer and use it in GitHub Desktop.
namespace A {
export class PeriodPicker extends Input {
private closeIconPanel: Control
input: HTMLInputElement
popup: Popup
constructor() {
super("A-PeriodPicker")
this.input = document.createElement("input") as HTMLInputElement
this.input.type = "text"
this.element.appendChild(this.input)
this.input.readOnly = true
this.addDOMEventListener("keydown", e => this.onKeydown(e))
this.appendChild(getIcon("downChevron", 14, 14))
this.closeIconPanel = new Span("closeIcon", this)
this.nullable = true
this.addFinalListener("click", () => this.togle())
}
private _nullable: boolean
public get nullable(): boolean {
return this._nullable
}
public set nullable(v: boolean) {
this._nullable = v
}
private updateClearIcon() {
this.closeIconPanel.clear()
if (this.nullable && this.value) {
let icon = getIcon("close", 14, 14)
this.closeIconPanel.appendChild(icon)
icon.addFinalListener("click", () => {
this.value = null
this.refresh()
this.fireSignal("input", this.value)
this.close()
})
}
}
private _value: A.DatePeriodModel
get value(): A.DatePeriodModel {
return this._value;
}
set value(v: A.DatePeriodModel) {
this._value = v;
if (v) {
if (v.start) {
v.start = new A.DateTime(v.start)
}
if (v.end) {
v.end = new A.DateTime(v.end)
}
}
this.refresh()
}
public get placeholder(): string {
return this.input.placeholder;
}
public set placeholder(v: string) {
this.input.placeholder = v
}
private refresh() {
let value = this.value
this.updateClearIcon()
if (!value) {
this.input.value = ""
return
}
if (value.range) {
let p = A.PeriodTypes.first(t => t.name == value.range)
this.input.value = i18n.T(p.label)
let period = p.func()
value.start = period.start
value.end = period.end
} else {
if (value.start && value.end) {
if (value.start.isSameDay(value.end)) {
this.input.value = value.start.format("d")
} else {
this.input.value = value.start.format("d") + " - " + value.end.format("d")
}
} else if (value.start) {
this.input.value = value.start.format("d") + " - "
} else if (value.end) {
this.input.value = " - " + value.end.format("d")
}
}
}
togle() {
if (this.popup) {
this.close()
return
}
this.show()
}
show() {
if (this.popup) {
this.popup.show()
return
}
this.popup = new Popup("periodPicker-popup")
this.appendWindow(this.popup)
this.popup.offsetY = 5
this.popup.activator = this
this.popup.onClose = () => {
this.popup = null
}
if (!this.value || this.value.range) {
this.showButtons()
} else {
this.showRange()
}
this.popup.show()
}
private showButtons() {
this.popup.clear()
let g = new A.ButtonGroup(true, this.popup)
g.addAction({
label: "@@Today",
click: () => {
this.value = { range: "today" }
this.fireSignal("input", this.value)
this.close()
}
})
g.addAction({
label: "@@Yesterday",
click: () => {
this.value = { range: "yesterday" }
this.fireSignal("input", this.value)
this.close()
}
})
g.addAction({
label: "@@Tomorrow",
click: () => {
this.value = { range: "tomorrow" }
this.fireSignal("input", this.value)
this.close()
}
})
g = new A.ButtonGroup(true, this.popup)
g.addAction({
label: "@@This month",
click: () => {
this.value = { range: "thisMonth" }
this.fireSignal("input", this.value)
this.close()
}
})
g.addAction({
label: "@@Last month",
click: () => {
this.value = { range: "lastMonth" }
this.fireSignal("input", this.value)
this.close()
}
})
g.addAction({
label: "@@Next month",
click: () => {
this.value = { range: "nextMonth" }
this.fireSignal("input", this.value)
this.close()
}
})
g = new A.ButtonGroup(true, this.popup)
g.addAction({
label: "@@This year",
click: () => {
this.value = { range: "thisYear" }
this.fireSignal("input", this.value)
this.close()
}
})
g.addAction({
label: "@@Last year",
click: () => {
this.value = { range: "lastYear" }
this.fireSignal("input", this.value)
this.close()
}
})
g.addAction({
label: "@@Next year",
click: () => {
this.value = { range: "nextYear" }
this.fireSignal("input", this.value)
this.close()
}
})
g = new A.ButtonGroup(true, this.popup)
g.addAction({
label: "@@Range",
click: () => this.showRange()
})
g.addAction({
label: "@@In the past",
click: () => {
this.value = { range: "past" }
this.fireSignal("input", this.value)
this.close()
}
})
g.addAction({
label: "@@In the future",
click: () => {
this.value = { range: "future" }
this.fireSignal("input", this.value)
this.close()
}
})
}
private showRange() {
this.popup.clear()
let pp = new PeriodPanel()
pp.value = this.value
this.popup.appendChild(pp)
let buttons = new ButtonGroup()
buttons.style.justifyContent = "space-between"
this.popup.appendChild(buttons)
buttons.appendChild(new Button(i18n.T("@@Periods"), null, () => {
this.showButtons()
}))
buttons.appendChild(new Button(i18n.T("@@Accept"), "highlighted", () => {
this.value = pp.value
this.fireSignal("input", this.value)
this.close()
}))
}
close() {
if (!this.popup) {
return
}
this.popup.close()
this.popup = null
}
private onKeydown(e: KeyboardEvent) {
if (e.key == "Enter") {
this.fireSignal("submit")
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment