diff options
Diffstat (limited to 'resources/vue/components/questionnaires')
6 files changed, 239 insertions, 579 deletions
diff --git a/resources/vue/components/questionnaires/FreetextEdit.vue b/resources/vue/components/questionnaires/FreetextEdit.vue index 29c6f34..58848ed 100644 --- a/resources/vue/components/questionnaires/FreetextEdit.vue +++ b/resources/vue/components/questionnaires/FreetextEdit.vue @@ -2,7 +2,7 @@ <div> <div class="formpart" tabindex="0" ref="autofocus"> {{ $gettext('Frage') }} - <studip-wysiwyg v-model="val_clone.description" :key="question_id"></studip-wysiwyg> + <StudipWysiwyg v-model="val_clone.description" /> </div> <label> @@ -13,40 +13,19 @@ </template> <script> -import StudipWysiwyg from "../StudipWysiwyg.vue"; +import { QuestionnaireComponent } from '../../mixins/QuestionnaireComponent'; export default { name: 'freetext-edit', - components: { - StudipWysiwyg + mixins: [ QuestionnaireComponent ], + created() { + this.setDefaultValues({ + description: '', + mandatory: '0', + }); }, - props: { - value: { - type: Object, - required: false, - default: function () { - return {}; - } - }, - question_id: { - type: String, - required: false - } - }, - data: function () { - return { - val_clone: '' - }; - }, - mounted: function () { - this.val_clone = this.value; + mounted() { this.$refs.autofocus.focus(); - }, - watch: { - value (new_val) { - this.val_clone = new_val; - } } - } </script> diff --git a/resources/vue/components/questionnaires/InputArray.vue b/resources/vue/components/questionnaires/InputArray.vue index 37fa6fc..896418f 100644 --- a/resources/vue/components/questionnaires/InputArray.vue +++ b/resources/vue/components/questionnaires/InputArray.vue @@ -1,177 +1,170 @@ <template> <div class="input-array"> <span aria-live="assertive" class="sr-only">{{ assistiveLive }}</span> - <draggable v-model="options" handle=".dragarea" tag="ol" class="clean options"> - <li v-for="(option, index) in options" :key="index"> - <a class="dragarea" - v-if="options.length > 1" - tabindex="0" - :ref="'draghandle_' + index" - :title="$gettextInterpolate('Sortierelement für Option %{option}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.', {option: option})" - @keydown="keyHandler($event, index)"> - <span class="drag-handle"></span> - </a> - <input type="text" - :placeholder="$gettext('Option')" - :ref="'option_' + index" - @paste="(ev) => onPaste(ev, index)" - v-model="options[index]"> - <button class="as-link" - :title="$gettext('Option löschen')" - @click.prevent="askForDeletingOption(index)"> - <studip-icon shape="trash" role="clickable" :size="20" alt=""></studip-icon> - </button> - <button v-if="index == options.length - 1" - class="as-link" - :title="$gettext('Option hinzufügen')" - @click.prevent="addOption"> - <studip-icon shape="add" role="clickable" :size="20" alt=""></studip-icon> - </button> - </li> - </draggable> - <studip-dialog - v-if="askForDeleting" - :title="$gettext('Bitte bestätigen Sie die Aktion.')" - :question="$gettext('Wirklich löschen?')" - :confirmText="$gettext('Ja')" - :closeText="$gettext('Nein')" - closeClass="cancel" - height="180" - @confirm="deleteOption" - @close="askForDeleting = false" - > - </studip-dialog> + <table class="default nohover"> + <colgroup> + <col style="width: 16px"> + <col> + <col v-for="i in additionalColspan" :key="`colspan-${i}`"> + <col style="width: 24px"> + </colgroup> + <thead> + <tr> + <th class="dragcolumn"></th> + <th>{{ labelPlural }}</th> + <slot name="header-cells" /> + <th class="actions"></th> + </tr> + </thead> + <Draggable v-model="options" handle=".dragarea" tag="tbody" class="statements"> + <tr v-for="(option, index) in options" :key="index"> + <td class="dragcolumn"> + <a class="dragarea" + tabindex="0" + :title="$gettextInterpolate($gettext(`Sortierelement für %{label} %{option}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.`), {option, label}, true)" + @keydown="keyHandler($event, index)" + ref="draghandle"> + <span class="drag-handle"></span> + </a> + </td> + <td> + <input type="text" + ref="inputs" + :placeholder="label" + @paste="(ev) => onPaste(ev, index)" + v-model="options[index]"> + </td> + <slot name="body-cells" /> + <td class="actions"> + <StudipIcon name="delete" + shape="trash" + :size="20" + @click.prevent="deleteOption(index)" + :title="$gettextInterpolate($gettext('%{label} löschen'), {label}, true)" + /> + </td> + </tr> + </Draggable> + <tfoot> + <tr> + <td :colspan="3 + additionalColspan"> + <button class="as-link" + :title="$gettextInterpolate($gettext('%{label} hinzufügen'), {label}, true)" + @click.prevent="addOption()"> + <StudipIcon shape="add" :size="20" alt="" /> + </button> + </td> + </tr> + </tfoot> + </table> </div> </template> <script> -import StudipIcon from "../StudipIcon.vue"; -import StudipDialog from "../StudipDialog.vue"; -import draggable from 'vuedraggable'; +import Draggable from 'vuedraggable'; +import { $gettext } from '../../../assets/javascripts/lib/gettext'; + export default { name: 'input-array', - components: { - StudipIcon, - StudipDialog, - draggable - }, + components: { Draggable }, props: { - value: { - type: Array, - required: false - } + additionalColspan: { + type: Number, + default: 0, + }, + label: { + type: String, + default: $gettext('Option'), + }, + labelPlural: { + type: String, + default: $gettext('Optionen'), + }, + value: Array, }, - data: function () { + data() { return { options: [], - askForDeleting: false, - indexOfDeletingOption: 0, - unique_id: null, - assistiveLive: '' + assistiveLive: '', }; }, methods: { - addOption: function (val, position) { - let data = this.value; - if (val.target) { - val = ''; - } - if (typeof position === "undefined") { - data.push(val || ''); - position = this.value.length - 1 - } else { - data.splice(position, 0, val || ''); - } - this.$emit('input', data); - let v = this; - this.$nextTick(function () { - v.$refs['option_' + position][0].focus(); + addOption(val = '', position = this.options.length) { + this.$set(this.options, position, val.trim()); + + this.$nextTick(() => { + this.$refs.inputs[position].focus(); }); }, - askForDeletingOption: function (index) { - this.indexOfDeletingOption = index; - if (this.value[index]) { - this.askForDeleting = true; - } else { - this.deleteOption(); - } - }, - deleteOption: function () { - this.$delete(this.value, this.indexOfDeletingOption); - this.askForDeleting = false; + deleteOption(index) { + const question = this.options[index] ? this.$gettext('Wirklich löschen?') : true; + STUDIP.Dialog.confirm(question).done(() => { + this.$delete(this.options, index); + }); }, - onPaste: function (ev, position) { - let data = ev.clipboardData.getData("text").split("\n"); - for (let i = 0; i < data.length; i++) { - if (data[i].trim()) { - this.addOption(data[i], position + i); - } - } + onPaste(ev, position) { + ev.clipboardData + .getData('text') + .split("\n") + .filter(str => str.trim().length > 0) + .forEach((value, index) => this.addOption(value, position + index)); + ev.preventDefault(); }, keyHandler(e, index) { - switch (e.keyCode) { - case 38: // up - e.preventDefault(); - if (index > 0) { - this.moveUp(index); - this.$nextTick(function () { - this.$refs['draghandle_' + (index - 1)][0].focus(); - this.assistiveLive = this.$gettextInterpolate( - 'Aktuelle Position in der Liste: %{pos} von %{listLength}.' - , {pos: index, listLength: this.options.length} - ); - }); - } - break; - case 40: // down - e.preventDefault(); - if (index < this.options.length - 1) { - this.moveDown(index); - this.$nextTick(function () { - this.$refs['draghandle_' + (index + 1)][0].focus(); - this.assistiveLive = this.$gettextInterpolate( - 'Aktuelle Position in der Liste: %{pos} von %{listLength}.' - , {pos: index + 2, listLength: this.options.length} - ); - }); - } - break; - } - }, - moveDown: function (index) { - if (index == this.options.length - 1) { + if (e.keyCode !== 38 && e.keyCode !== 40) { return; } - let option = this.options[index]; - this.options[index] = this.options[index + 1]; - this.options[index + 1] = option; - this.$forceUpdate(); + + e.preventDefault(); + + const moveUp = e.keyCode === 38; + + this.moveElement(index, moveUp ? -1 : 1).then((newIndex) => { + this.assistiveLive = this.$gettextInterpolate( + this.$gettext('Aktuelle Position in der Liste: %{pos} von %{listLength}.'), + {pos: newIndex + 1, listLength: this.options.length} + ); + + this.$nextTick(() => { + this.$refs['draghandle'][newIndex].focus(); + }); + }) }, - moveUp: function (index) { - if (index === 0) { - return; + moveElement(index, direction) { + if (this.options[index + direction] === undefined) { + return Promise.resolve(index); } - let option = this.options[index]; - this.options[index] = this.options[index - 1]; - this.options[index - 1] = option; - this.$forceUpdate(); + + const indices = [index, index + direction].sort(); + + this.options.splice( + Math.min(...indices), + 2, + ...indices.reverse().map(idx => this.options[idx]) + ); + + return Promise.resolve(index + direction); } }, - mounted: function () { - this.options = this.value; - this.unique_id = 'array_input_' + Math.floor(Math.random() * 100000000); - }, watch: { - options (new_data, old_data) { - if (typeof old_data === 'undefined' || typeof new_data === 'undefined') { - return; - } - this.$emit('input', new_data); + options: { + handler(current) { + this.$emit('input', current); + }, + deep: true }, - value (new_val) { - this.options = new_val; + value: { + handler(current) { + this.options = current; + }, + immediate: true } } } </script> +<style scoped> +.input-array input[type="text"] { + max-width: unset; +} +</style> diff --git a/resources/vue/components/questionnaires/LikertEdit.vue b/resources/vue/components/questionnaires/LikertEdit.vue index c87f9fe..736be6b 100644 --- a/resources/vue/components/questionnaires/LikertEdit.vue +++ b/resources/vue/components/questionnaires/LikertEdit.vue @@ -1,66 +1,27 @@ <template> <div class="likert_edit"> - <div class="formpart" tabindex="0" ref="autofocus"> {{ $gettext('Einleitungstext' )}} - <studip-wysiwyg v-model="val_clone.description"></studip-wysiwyg> + <StudipWysiwyg v-model="val_clone.description" /> </div> - <span aria-live="assertive" class="sr-only">{{ assistiveLive }}</span> + <InputArray v-model="val_clone.statements" + :label="$gettext('Aussage')" + :label-plural="$gettext('Aussagen')" + :additional-colspan="val_clone.options.length" + > + <template #header-cells> + <th v-for="(option, index) in val_clone.options" class="option-cell" :key="index"> + {{ option }} + </th> + </template> - <table class="default nohover"> - <thead> - <tr> - <th class="dragcolumn"></th> - <th>{{ $gettext('Aussagen') }}</th> - <th v-for="(option, index) in val_clone.options" :key="index">{{ option }}</th> - <th class="actions"></th> - </tr> - </thead> - <draggable v-model="val_clone.statements" handle=".dragarea" tag="tbody" class="statements"> - <tr v-for="(statement, index) in val_clone.statements" :key="index"> - <td class="dragcolumn"> - <a class="dragarea" - tabindex="0" - :title="$gettextInterpolate($gettext('Sortierelement für Aussage %{statement}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.'), {statement: statement})" - @keydown="keyHandler($event, index)" - :ref="'draghandle_' + index"> - <span class="drag-handle"></span> - </a> - </td> - <td> - <input type="text" - :ref="'statement_' + index" - :placeholder="$gettext('Aussage')" - @paste="(ev) => onPaste(ev, index)" - v-model="val_clone.statements[index]"> - </td> - <td v-for="(option, index2) in val_clone.options" :key="index2"> - <input type="radio" disabled :title="option"> - </td> - <td class="actions"> - <studip-icon name="delete" - shape="trash" - :size="20" - @click.prevent="deleteStatement(index)" - :title="$gettext('Aussage löschen')" - ></studip-icon> - </td> - </tr> - </draggable> - <tfoot> - <tr> - <td :colspan="val_clone.options.length + 3"> - <studip-icon name="add" - shape="add" - :size="20" - @click.prevent="addStatement()" - :title="$gettext('Aussage hinzufügen')" - ></studip-icon> - </td> - </tr> - </tfoot> - </table> + <template #body-cells> + <td v-for="(option, index) in val_clone.options" class="option-cell" :key="index"> + <input type="radio" disabled :title="option"> + </td> + </template> + </InputArray> <label> <input type="checkbox" v-model.number="val_clone.mandatory" true-value="1" false-value="0"> @@ -73,17 +34,18 @@ <div> <div>{{ $gettext('Antwortmöglichkeiten konfigurieren') }}</div> - <input-array v-model="val_clone.options"></input-array> + <InputArray v-model="val_clone.options" /> </div> </div> </template> <script> -import draggable from 'vuedraggable'; -import InputArray from "./InputArray.vue"; import { $gettext } from '../../../assets/javascripts/lib/gettext'; +import InputArray from "./InputArray.vue"; +import { QuestionnaireComponent } from '../../mixins/QuestionnaireComponent'; -const default_value = () => ({ +// This is necesssar since $gettext does not seem to work in data() or created() +const default_values = () => ({ description: '', statements: ['', '', '', ''], mandatory: 0, @@ -96,115 +58,16 @@ const default_value = () => ({ $gettext('trifft nicht zu'), ], }); + export default { name: 'likert-edit', - components: { - draggable, - InputArray - }, - props: { - value: { - type: Object, - required: false, - default() { - return {...default_value()}; - } - }, - question_id: { - type: String, - required: false - } - }, - data() { - return { - val_clone: null, - assistiveLive: '' - }; - }, - methods: { - addStatement(val = '', position = null) { - if (position === null) { - this.val_clone.statements.push(val || ''); - } else { - this.val_clone.statements.splice(position, 0, val || ''); - } - this.$nextTick(() => { - this.$refs['statement_' + (this.val_clone.statements.length - 1)][0].focus(); - }); - }, - deleteStatement(index) { - STUDIP.Dialog.confirm(this.$gettext('Wirklich löschen?')).done(() => { - this.$delete(this.val_clone.statements, index); - }); - }, - onPaste(ev, position) { - let data = ev.clipboardData.getData("text").split("\n"); - for (let i = 0; i < data.length; i++) { - if (data[i].trim()) { - this.addStatement(data[i], position + i); - } - } - }, - keyHandler(e, index) { - switch (e.keyCode) { - case 38: // up - e.preventDefault(); - if (index > 0) { - this.moveUp(index); - this.$nextTick(() => { - this.$refs['draghandle_' + (index - 1)][0].focus(); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext('Aktuelle Position in der Liste: %{pos} von %{listLength}.'), - {pos: index, listLength: this.val_clone.statements.length} - ); - }); - } - break; - case 40: // down - e.preventDefault(); - if (index < this.val_clone.statements.length - 1) { - this.moveDown(index); - this.$nextTick(() => { - this.$refs['draghandle_' + (index + 1)][0].focus(); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext('Aktuelle Position in der Liste: %{pos} von %{listLength}.'), - {pos: index + 2, listLength: this.val_clone.statements.length} - ); - }); - } - break; - } - }, - moveDown(index) { - this.val_clone.statements.splice( - index, - 2, - this.val_clone.statements[index + 1], - this.val_clone.statements[index] - ) - }, - moveUp(index) { - this.val_clone.statements.splice( - index - 1, - 2, - this.val_clone.statements[index], - this.val_clone.statements[index - 1] - ) - } - }, + components: { InputArray }, + mixins: [ QuestionnaireComponent ], created() { - this.val_clone = Object.assign({}, default_value(), this.value ?? {}); + this.setDefaultValues(default_values()); }, mounted() { this.$refs.autofocus.focus(); - }, - watch: { - val_clone: { - handler(current) { - this.$emit('input', current); - }, - deep: true - } } } </script> diff --git a/resources/vue/components/questionnaires/QuestionnaireInfoEdit.vue b/resources/vue/components/questionnaires/QuestionnaireInfoEdit.vue index bc5e829..83d5fa2 100644 --- a/resources/vue/components/questionnaires/QuestionnaireInfoEdit.vue +++ b/resources/vue/components/questionnaires/QuestionnaireInfoEdit.vue @@ -8,39 +8,26 @@ <div class="formpart"> {{ $gettext('Hinweistext (optional)') }} - <studip-wysiwyg v-model="val_clone.description" :key="question_id"></studip-wysiwyg> + <StudipWysiwyg v-model="val_clone.description" /> </div> </div> </template> <script> -import StudipWysiwyg from "../StudipWysiwyg.vue"; +import { QuestionnaireComponent } from '../../mixins/QuestionnaireComponent'; export default { name: 'questionnaire-info-edit', - components: { - StudipWysiwyg + mixins: [ QuestionnaireComponent ], + created() { + this.setDefaultValues({ + url: '', + description: '' + }); }, - props: { - value: { - type: Object, - required: false, - default() { - return { - url: '', - description: '' - }; - } - }, - question_id: { - type: String, - required: false - } - }, - data () { - return { - val_clone: this.value, - }; + mounted() { + this.$refs.infoUrl.focus(); + this.checkValidity(); }, methods: { checkValidity() { @@ -53,15 +40,6 @@ export default { this.$refs.infoUrl.reportValidity(); } } - }, - mounted() { - this.$refs.infoUrl.focus(); - this.checkValidity(); - }, - watch: { - value (new_val) { - this.val_clone = new_val; - } } } </script> diff --git a/resources/vue/components/questionnaires/RangescaleEdit.vue b/resources/vue/components/questionnaires/RangescaleEdit.vue index 91aec1c..cd7ce3b 100644 --- a/resources/vue/components/questionnaires/RangescaleEdit.vue +++ b/resources/vue/components/questionnaires/RangescaleEdit.vue @@ -3,68 +3,25 @@ <div class="formpart" tabindex="0" ref="autofocus"> {{ $gettext('Einleitungstext') }} - <studip-wysiwyg v-model="val_clone.description"></studip-wysiwyg> + <StudipWysiwyg v-model="val_clone.description" /> </div> - <span aria-live="assertive" class="sr-only">{{ assistiveLive }}</span> - - <table class="default nohover"> - <thead> - <tr> - <th class="dragcolumn"></th> - <th>{{ $gettext('Aussagen') }}</th> - <th v-for="i in (val_clone.maximum - val_clone.minimum + 1)" :key="i" class="number">{{ (val_clone.minimum - 1 + i) }}</th> - <th v-if="val_clone.alternative_answer.trim().length > 0">{{ val_clone.alternative_answer }}</th> - <th class="actions"></th> - </tr> - </thead> - <draggable v-model="val_clone.statements" handle=".dragarea" tag="tbody" class="statements"> - <tr v-for="(statement, index) in val_clone.statements" :key="index"> - <td class="dragcolumn"> - <a class="dragarea" - tabindex="0" - :title="$gettextInterpolate($gettext('Sortierelement für Aussage %{statement}. Drücken Sie die Tasten Pfeil-nach-oben oder Pfeil-nach-unten, um dieses Element in der Liste zu verschieben.'), {statement: statement})" - @keydown="keyHandler($event, index)" - :ref="'draghandle_' + index"> - <span class="drag-handle"></span> - </a> - </td> - <td> - <input type="text" - :ref="'statement_' + index" - :placeholder="$gettext('Aussage')" - @paste="(ev) => onPaste(ev, index)" - v-model="val_clone.statements[index]"> - </td> - <td v-for="i in (val_clone.maximum - val_clone.minimum + 1)" :key="i"> - <input type="radio" disabled :title="i + val_clone.minimum - 1"> - </td> - <td v-if="val_clone.alternative_answer.trim().length > 0"> - <input type="radio" disabled :title="val_clone.alternative_answer"> - </td> - <td class="actions"> - <studip-icon name="delete" - shape="trash" - :size="20" - @click.prevent="deleteStatement(index)" - :title="$gettext('Aussage löschen')" - ></studip-icon> - </td> - </tr> - </draggable> - <tfoot> - <tr> - <td :colspan="val_clone.maximum - val_clone.minimum + 4 + (val_clone.alternative_answer.trim().length > 0 ? 1 : 0)"> - <studip-icon name="add" - shape="add" - :size="20" - @click.prevent="addStatement()" - :title="$gettext('Aussage hinzufügen')" - ></studip-icon> - </td> - </tr> - </tfoot> - </table> + <InputArray v-model="val_clone.statements" + :label="$gettext('Aussage')" + :label-plural="$gettext('Aussagen')" + :additional-colspan="options.length" + > + <template #header-cells> + <th v-for="(option, index) in options" class="option-cell" :key="index"> + {{ option }} + </th> + </template> + <template #body-cells> + <td v-for="(option, index) in options" class="option-cell" :key="index"> + <input type="radio" disabled :title="option"> + </td> + </template> + </InputArray> <label> <input type="checkbox" v-model.number="val_clone.mandatory" true-value="1" false-value="0"> @@ -82,135 +39,48 @@ <label> {{ $gettext('Minimum') }} - <input type="number" v-model.number="val_clone.minimum" min="1"> + <input type="number" v-model.number="val_clone.minimum" min="1" :max="val_clone.maximum"> </label> <label> {{ $gettext('Ausweichantwort (leer lassen für keine)') }} - <input type="text" v-model="val_clone.alternative_answer"> + <input type="text" v-model.trim="val_clone.alternative_answer"> </label> </div> </template> <script> -import draggable from 'vuedraggable'; +import InputArray from './InputArray.vue'; +import { QuestionnaireComponent } from '../../mixins/QuestionnaireComponent'; -const default_value = () => ({ - description: '', - statements: ['', '', '', ''], - mandatory: 0, - randomize: 0, - minimum: 1, - maximum: 5, - alternative_answer: '' -}); export default { - name: 'likert-edit', - components: { - draggable, - }, - props: { - value: { - type: Object, - required: false, - default() { - return default_value(); - } - }, - question_id: { - type: String, - required: false - } - }, - data() { - return { - val_clone: null, - assistiveLive: '' - }; - }, - methods: { - addStatement(val = '', position = null) { - if (position === null) { - this.val_clone.statements.push(val || ''); - } else { - this.val_clone.statements.splice(position, 0, val || ''); - } - this.$nextTick(() => { - this.$refs['statement_' + (this.value.statements.length - 1)][0].focus(); - }); - }, - deleteStatement(index) { - STUDIP.Dialog.confirm(this.$gettext('Wirklich löschen?')).done(() => { - this.$delete(this.value.statements, index); - }); - }, - onPaste(ev, position) { - let data = ev.clipboardData.getData('text').split("\n"); - for (let i = 0; i < data.length; i++) { - if (data[i].trim()) { - this.addStatement(data[i], position + i); - } - } - }, - keyHandler(e, index) { - switch (e.keyCode) { - case 38: // up - e.preventDefault(); - if (index > 0) { - this.moveUp(index); - this.$nextTick(() => { - this.$refs['draghandle_' + (index - 1)][0].focus(); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext('Aktuelle Position in der Liste: %{pos} von %{listLength}.'), - {pos: index, listLength: this.val_clone.statements.length} - ); - }); - } - break; - case 40: // down - e.preventDefault(); - if (index < this.val_clone.statements.length - 1) { - this.moveDown(index); - this.$nextTick(() => { - this.$refs['draghandle_' + (index + 1)][0].focus(); - this.assistiveLive = this.$gettextInterpolate( - this.$gettext('Aktuelle Position in der Liste: %{pos} von %{listLength}.'), - {pos: index + 2, listLength: this.val_clone.statements.length} - ); - }); - } - break; - } - }, - moveDown(index) { - this.val_clone.statements.splice( - index, - 2, - this.val_clone.statements[index + 1], - this.val_clone.statements[index] - ); - }, - moveUp(index) { - this.val_clone.statements.splice( - index - 1, - 2, - this.val_clone.statements[index], - this.val_clone.statements[index - 1] - ); - }, - }, + name: 'rangescale-edit', + components: { InputArray }, + mixins: [ QuestionnaireComponent ], created() { - this.val_clone = Object.assign({}, default_value(), this.value ?? {}); + this.setDefaultValues({ + alternative_answer: '', + description: '', + mandatory: 0, + maximum: 5, + minimum: 1, + randomize: 0, + statements: ['', '', '', ''] + }); }, mounted() { this.$refs.autofocus.focus(); }, - watch: { - val_clone: { - handler(current) { - this.$emit('input', current); - }, - deep: true + computed: { + options() { + let result = []; + for (let i = this.val_clone.minimum; i <= this.val_clone.maximum; i += 1) { + result.push(i); + } + if (this.val_clone.alternative_answer.length > 0) { + result.push(this.val_clone.alternative_answer); + } + return result; } } } diff --git a/resources/vue/components/questionnaires/VoteEdit.vue b/resources/vue/components/questionnaires/VoteEdit.vue index 9acb01f..1d6d9cf 100644 --- a/resources/vue/components/questionnaires/VoteEdit.vue +++ b/resources/vue/components/questionnaires/VoteEdit.vue @@ -2,10 +2,10 @@ <div class="vote_edit"> <div class="formpart" tabindex="0" ref="autofocus"> {{ $gettext('Frage') }} - <studip-wysiwyg v-model="val_clone.description" :key="question_id"></studip-wysiwyg> + <StudipWysiwyg v-model="val_clone.description" /> </div> - <input-array v-model="val_clone.options"></input-array> + <InputArray v-model="val_clone.options" /> <label> <input type="checkbox" v-model.number="val_clone.multiplechoice" true-value="1" false-value="0"> @@ -24,47 +24,24 @@ </template> <script> -import StudipWysiwyg from "../StudipWysiwyg.vue"; import InputArray from "./InputArray.vue"; +import { QuestionnaireComponent } from '../../mixins/QuestionnaireComponent'; export default { name: 'vote-edit', - components: { - StudipWysiwyg, - InputArray + components: { InputArray }, + mixins: [QuestionnaireComponent], + created() { + this.setDefaultValues({ + description: '', + mandatory: '0', + multiplechoice: '1', + options: ['', '', '', ''], + randomize: '0', + }); }, - props: { - value: { - type: Object, - required: false, - default: function () { - return {}; - } - }, - question_id: { - type: String, - required: false - } - }, - data: function () { - return { - val_clone: {} - }; - }, - mounted: function () { - this.val_clone = this.value; - if (!this.value.description) { - this.$emit('input', { - multiplechoice: 1, - options: ['', '', '', ''] - }); - } + mounted() { this.$refs.autofocus.focus(); - }, - watch: { - value (new_val) { - this.val_clone = new_val; - } } } </script> |
