<template>
<BoilerplateElement :id="this.id">
<template #german>
<q-input :lazy-rules="true" rounded outlined v-model="elementData.dateTime" :label="$t('appointmentElement.dateTime')" :rules="validation.dateTime" bg-color="white">
<template v-slot:prepend>
<q-icon name="event" class="cursor-pointer" >
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-date v-model="elementData.dateTime" mask="DD.MM.YYYY HH:mm">
<div class="row items-center justify-end">
<q-btn v-close-popup :label="$t('appointmentElement.close')" color="primary" flat ref="dateCloseButton" />
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</template>
<template v-slot:append>
<q-icon name="access_time" class="cursor-pointer">
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-time v-model="elementData.dateTime" mask="DD.MM.YYYY HH:mm" format24h>
<div class="row items-center justify-end">
<q-btn v-close-popup :label="$t('appointmentElement.close')" color="primary" flat ref="timeCloseButton"/>
</div>
</q-time>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
<q-badge color="primary">
{{ $t('appointmentElement.duration') }}: {{ elementData.duration > 0 ? elementData.duration + ' ' + $t('appointmentElement.hours') : $t('appointmentElement.notSpecified')}}
</q-badge>
<q-slider v-model="elementData.duration" :min="0" :max="10" :step="0.25"/>
<q-input :lazy-rules="true" rounded outlined v-model="elementData.german.title" :label="$t('appointmentElement.title')" bg-color="white" :rules="validation.title" />
<q-input :lazy-rules="true" rounded outlined v-model="elementData.german.place" :label="$t('appointmentElement.place')" bg-color="white" :rules="validation.place" />
<q-input :lazy-rules="true" rounded outlined v-model="elementData.german.person" :label="$t('appointmentElement.person')" bg-color="white" :rules="validation.person" />
<h3 class="elipsis q-field__label">Freitext</h3>
<q-editor v-model="elementData.german.freeText"
ref="germanEditor"
:toolbar="[
['left', 'center', 'right', 'justify'],
['bold', 'italic', 'underline', 'strike'],
['link', 'unordered'],
['removeFormat'],
['undo', 'redo']
]"
@paste="(event) => removeUnwantedFormatting(event, $refs.germanEditor)"
></q-editor>
</template>
<template #english>
<q-input :lazy-rules="true" rounded outlined v-model="elementData.dateTime" :label="$t('appointmentElement.dateTime')" :rules="validation.dateTime" bg-color="white">
<template v-slot:prepend>
<q-icon name="event" class="cursor-pointer">
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-date v-model="elementData.dateTime" mask="DD.MM.YYYY HH:mm">
<div class="row items-center justify-end">
<q-btn v-close-popup :label="$t('appointmentElement.close')" color="primary" flat ref="dateCloseButton"/>
</div>
</q-date>
</q-popup-proxy>
</q-icon>
</template>
<template v-slot:append>
<q-icon name="access_time" class="cursor-pointer">
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-time v-model="elementData.dateTime" mask="DD.MM.YYYY HH:mm" format24h>
<div class="row items-center justify-end">
<q-btn v-close-popup :label="$t('appointmentElement.close')" color="primary" flat ref="timeCloseButton"/>
</div>
</q-time>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
<q-badge color="primary">
{{ $t('appointmentElement.duration') }}: {{ elementData.duration > 0 ? elementData.duration + ' ' + $t('appointmentElement.hours') : $t('appointmentElement.notSpecified')}}
</q-badge>
<q-slider v-model="elementData.duration" :min="0" :max="10" :step="0.25"/>
<q-input :lazy-rules="true" rounded outlined v-model="elementData.english.title" :label="$t('appointmentElement.title')" bg-color="white" :rules="validation.title" />
<q-input :lazy-rules="true" rounded outlined v-model="elementData.english.place" :label="$t('appointmentElement.place')" bg-color="white" :rules="validation.place" />
<q-input :lazy-rules="true" rounded outlined v-model="elementData.english.person" :label="$t('appointmentElement.person')" bg-color="white" :rules="validation.person" />
<h3 class="elipsis q-field__label">Freitext</h3>
<q-editor v-model="elementData.english.freeText"
ref="englishEditor"
:toolbar="[
['left', 'center', 'right', 'justify'],
['bold', 'italic', 'underline', 'strike'],
['link', 'unordered'],
['removeFormat'],
['undo', 'redo']
]"
@paste="(event) => removeUnwantedFormatting(event, $refs.englishEditor)"
></q-editor>
</template>
</BoilerplateElement>
</template>
<script>
import BoilerplateElement from 'src/components/BoilerplateElement.vue'
export default {
data () {
return {
elementData: this.data,
validation: {
dateTime: [
(v) => {
// error: dateTime is required
const eId = 1
const errorExists = this.elementData.errors.some(error => error.id === eId)
// using Date and Time close button to determin if popup is currently open (exists) if so ongoing selection and therefore no error and erly return true
if (this.$refs.dateCloseButton != null || this.$refs.timeCloseButton != null) {
return true
}
if (v) {
this.elementData.errors = this.elementData.errors.filter((error) => error.id !== eId)
return true
} else {
if (!errorExists) {
this.elementData.errors.push({ id: eId, message: this.$t('appointmentElement.error1') })
}
return this.$t('appointmentElement.error1')
}
},
(v) => {
// error: incorrect dateTime format
const eId = 2
const errorExists = this.elementData.errors.some(error => error.id === eId)
// using Date and Time close button to determin if popup is currently open (exists) if so ongoing selection and therefore no error and erly return true
if (this.$refs.dateCloseButton != null || this.$refs.timeCloseButton != null) {
return true
}
if (v && v.match(/^\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}$/)) {
this.elementData.errors = this.elementData.errors.filter((error) => error.id !== eId)
return true
} else {
if (!errorExists) {
this.elementData.errors.push({ id: eId, message: this.$t('appointmentElement.error2') })
}
return this.$t('appointmentElement.error2')
}
}
],
title: [
(v) => {
// error: title is required
const eId = 3
const errorExists = this.elementData.errors.some(error => error.id === eId)
if (v) {
this.elementData.errors = this.elementData.errors.filter((error) => error.id !== eId)
return true
} else {
if (!errorExists) {
this.elementData.errors.push({ id: eId, message: this.$t('appointmentElement.error3') })
}
return this.$t('appointmentElement.error3')
}
}
],
place: [
(v) => {
// error: place is required
const eId = 4
const errorExists = this.elementData.errors.some(error => error.id === eId)
if (v) {
this.elementData.errors = this.elementData.errors.filter((error) => error.id !== eId)
return true
} else {
if (!errorExists) {
this.elementData.errors.push({ id: eId, message: this.$t('appointmentElement.error4') })
}
return this.$t('appointmentElement.error4')
}
}
],
person: [
(v) => {
// error: person is required
const eId = 5
const errorExists = this.elementData.errors.some(error => error.id === eId)
if (v) {
this.elementData.errors = this.elementData.errors.filter((error) => error.id !== eId)
return true
} else {
if (!errorExists) {
this.elementData.errors.push({ id: eId, message: this.$t('appointmentElement.error5') })
}
return this.$t('appointmentElement.error5')
}
}
]
}
}
},
props: {
id: {
required: true
},
data: {
type: Object,
required: true
}
},
components: {
BoilerplateElement
},
methods: {
// Remove unwanted formatting when pasting text based on official quasar docs modified with chatgpt
removeUnwantedFormatting (evt, editor) {
// Let inputs do their thing, so we don't break pasting of links.
if (evt.target.nodeName === 'INPUT') return
let text, html, onPasteStripFormattingIEPaste
evt.preventDefault()
evt.stopPropagation()
if (evt.originalEvent && evt.originalEvent.clipboardData) {
// Check if HTML data is available in the clipboard
if (evt.originalEvent.clipboardData.types.includes('text/html')) {
html = evt.originalEvent.clipboardData.getData('text/html')
// Remove font size-related styles
html = html.replace(/font-size:\s*\d+(\.\d+)?(px|pt|em|rem|%);?/gi, '')
editor.runCmd('insertHTML', html)
} else {
// If no HTML, fall back to plain text
text = evt.originalEvent.clipboardData.getData('text/plain')
editor.runCmd('insertText', text)
}
} else if (evt.clipboardData) {
if (evt.clipboardData.types.includes('text/html')) {
html = evt.clipboardData.getData('text/html')
// Remove font size-related styles
html = html.replace(/font-size:\s*\d+(\.\d+)?(px|pt|em|rem|%);?/gi, '')
editor.runCmd('insertHTML', html)
} else {
text = evt.clipboardData.getData('text/plain')
editor.runCmd('insertText', text)
}
} else if (window.clipboardData) {
// Internet Explorer handling
if (!onPasteStripFormattingIEPaste) {
onPasteStripFormattingIEPaste = true
html = window.clipboardData.getData('Text')
// Apply a similar approach to remove font size styles if IE supports HTML
html = html.replace(/font-size:\s*\d+(\.\d+)?(px|pt|em|rem|%);?/gi, '')
editor.runCmd('ms-pasteHTML', html)
}
onPasteStripFormattingIEPaste = false
}
}
}
}
</script>