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