aboutsummaryrefslogtreecommitdiff
path: root/resources/vue/components/questionnaires/RangescaleEdit.vue
diff options
context:
space:
mode:
authorPhilipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de>2024-09-24 10:53:31 +0200
committerPhilipp Schüttlöffel <schuettloeffel@zqs.uni-hannover.de>2024-09-24 10:53:31 +0200
commit4459dd7917f4d1c34f40bb68f0e991e9c3d53e4c (patch)
tree5c07151ae61276d334e88f6309c30d439a85c12e /resources/vue/components/questionnaires/RangescaleEdit.vue
parentda0022e5c1abbf9825ae76debaabdff7e8623bb4 (diff)
parent97a188592c679890a25c37ab78463add76a52ff7 (diff)
Merge branch 'main' into issue-3911issue-3911
Diffstat (limited to 'resources/vue/components/questionnaires/RangescaleEdit.vue')
-rw-r--r--resources/vue/components/questionnaires/RangescaleEdit.vue216
1 files changed, 43 insertions, 173 deletions
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;
}
}
}