nfp_sites/filadelfia_web/app/input.js

144 lines
4.0 KiB
JavaScript

const m = require('mithril')
const api = require('./api')
const tempus = require('@eonasdan/tempus-dominus')
const tempusLocalization = {
locale: 'is',
startOfTheWeek: 0,
hourCycle: 'h23',
dateFormats: {
LTS: 'H:mm:ss',
LT: 'H:mm',
L: 'dd.MM.yyyy',
LL: 'd [de] MMMM [de] yyyy',
LLL: 'd [de] MMMM [de] yyyy H:mm',
LLLL: 'dddd, d [de] MMMM [de] yyyy H:mm',
},
}
const Input = {
oninit: function(vnode) {
this.tempus = null
this.subscription = null
this.input = null
this.preview = null
},
onremove: function(vnode) {
if (this.subscription) this.subscription.unsubscribe()
if (this.tempus) {
this.tempus.dispose()
this.tempus = null
}
if (this.preview) {
this.preview.clear()
}
},
onupdate: function(vnode) {
if (this.tempus && vnode.attrs.form[vnode.attrs.formKey]) {
if (vnode.attrs.form[vnode.attrs.formKey].getTime() !== this.tempus.viewDate?.getTime()) {
this.tempus.dates.setValue(new tempus.DateTime(vnode.attrs.form[vnode.attrs.formKey]))
}
}
},
imageChanged: function(vnode, e) {
let file = e.currentTarget.files?.[0] || null
this.updateValue(vnode, file)
if (this.preview) {
this.preview.clear()
this.preview = null
}
if (!file) return
if (file.type.startsWith('image')) {
this.preview = {
file: file,
preview: URL.createObjectURL(file),
clear: function() {
URL.revokeObjectURL(this.preview)
},
}
}
},
updateValue: function(vnode, value) {
vnode.attrs.form[vnode.attrs.formKey] = value
if (typeof(vnode.attrs.oninput) === 'function') {
vnode.attrs.oninput(vnode.attrs.form[vnode.attrs.formKey])
}
return false
},
getInput: function(vnode) {
switch (vnode.attrs.utility) {
case 'file':
return m('div.form-row', [
m('input', {
type: 'text',
disabled: api.loading,
value: vnode.attrs.form[vnode.attrs.formKey]?.name || '',
}),
m('button.fal', { class: vnode.attrs.button || 'file' }),
m('input.cover', {
type: 'file',
accept: vnode.attrs.accept,
disabled: api.loading,
oninput: (e) => this.updateValue(vnode, e.currentTarget.files?.[0] || null),
}),
])
case 'datetime':
return m('div.form-row', [
m('input', {
type: 'text',
disabled: api.loading,
oncreate: (e) => {
this.tempus = new tempus.TempusDominus(e.dom, {
localization: tempusLocalization,
})
this.tempus.dates.setValue(new tempus.DateTime(vnode.attrs.form[vnode.attrs.formKey]))
this.subscription = this.tempus.subscribe(tempus.Namespace.events.change, (e) => {
this.updateValue(vnode, e.date)
});
},
}),
m('button.fal.fa-calendar', {
onclick: () => { this.tempus.toggle(); return false },
})
])
case 'image':
let imageLink = this.preview && this.preview.preview || vnode.attrs.form[vnode.attrs.formKey]
return m('div.form-row.image-banner', {
style: {
'background-image': typeof imageLink === 'string' ? 'url("' + (imageLink) + '")' : null,
},
}, [
m('input.cover', {
type: 'file',
accept: vnode.attrs.accept,
disabled: api.loading,
onchange: this.imageChanged.bind(this, vnode),
}),
])
default:
return m('input', {
disabled: api.loading,
type: vnode.attrs.type || 'text',
value: vnode.attrs.form[vnode.attrs.formKey],
oninput: (e) => this.updateValue(vnode, e.currentTarget.value),
})
}
},
view: function(vnode) {
return [
vnode.attrs.label ? m('label', vnode.attrs.label) : null,
this.getInput(vnode),
]
},
}
module.exports = Input