55
55
</template >
56
56
</NcButton >
57
57
</div >
58
-
58
+ <NcModal v-if =" isModalOpen"
59
+ size =" normal"
60
+ title =" Add multiple options"
61
+ :out-transition =" true"
62
+ :has-next =" false"
63
+ :has-previous =" false"
64
+ @close =" closeModal" >
65
+ <div class =" modal__content" >
66
+ <h1 >Add multiple options {{ isModalOpen }}</h1 >
67
+ <textarea ref =" input"
68
+ v-model =" inputedOptions"
69
+ :aria-label =" t('forms', 'An answer for the {index} option', { index: index + 1 })"
70
+ :placeholder =" t('forms', 'Answer number {index}', { index: index + 1 })"
71
+ class =" question__input"
72
+ type =" text" />
73
+ <div class =" options" >
74
+ <div v-for =" (option, i) in multipleOptions" :key =" i" class =" single_option" >
75
+ <p >{{ option }}</p >
76
+ </div >
77
+ </div >
78
+ <div >
79
+ <NcButton @click =" onMultipleOptions" >
80
+ Add options
81
+ </NcButton >
82
+ </div >
83
+ </div >
84
+ </NcModal >
59
85
<!-- Header -->
60
86
<div class =" question__header" >
61
87
<div class =" question__header__title" >
118
144
</template >
119
145
{{ t('forms', 'Copy question') }}
120
146
</NcActionButton >
147
+ <NcActionButton @click =" openModal" >
148
+ <template #icon >
149
+ <IconContentPaste :size =" 20" />
150
+ </template >
151
+ {{ t('forms', 'Multiple Options') }}
152
+ </NcActionButton >
121
153
<NcActionButton @click =" onDelete" >
122
154
<template #icon >
123
155
<IconDelete :size =" 20" />
@@ -151,13 +183,16 @@ import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
151
183
import NcActionCheckbox from ' @nextcloud/vue/dist/Components/NcActionCheckbox.js'
152
184
import NcActionInput from ' @nextcloud/vue/dist/Components/NcActionInput.js'
153
185
import NcButton from ' @nextcloud/vue/dist/Components/NcButton.js'
186
+ import NcModal from ' @nextcloud/vue/dist/Components/NcModal.js'
187
+ import { showError } from ' @nextcloud/dialogs'
154
188
155
189
import IconAlertCircleOutline from ' vue-material-design-icons/AlertCircleOutline.vue'
156
190
import IconArrowDown from ' vue-material-design-icons/ArrowDown.vue'
157
191
import IconArrowUp from ' vue-material-design-icons/ArrowUp.vue'
158
192
import IconAsterisk from ' vue-material-design-icons/Asterisk.vue'
159
193
import IconContentCopy from ' vue-material-design-icons/ContentCopy.vue'
160
194
import IconDelete from ' vue-material-design-icons/Delete.vue'
195
+ import IconContentPaste from ' vue-material-design-icons/ContentPaste.vue'
161
196
import IconDragHorizontalVariant from ' vue-material-design-icons/DragHorizontalVariant.vue'
162
197
import IconDotsHorizontal from ' vue-material-design-icons/DotsHorizontal.vue'
163
198
import IconIdentifier from ' vue-material-design-icons/Identifier.vue'
@@ -172,6 +207,7 @@ export default {
172
207
IconArrowUp,
173
208
IconAsterisk,
174
209
IconContentCopy,
210
+ IconContentPaste,
175
211
IconDelete,
176
212
IconDragHorizontalVariant,
177
213
IconDotsHorizontal,
@@ -182,6 +218,7 @@ export default {
182
218
NcActionCheckbox,
183
219
NcActionInput,
184
220
NcButton,
221
+ NcModal,
185
222
},
186
223
187
224
inject: [' $markdownit' ],
@@ -241,6 +278,13 @@ export default {
241
278
},
242
279
},
243
280
281
+ data () {
282
+ return {
283
+ isModalOpen: false ,
284
+ inputedOptions: ' ' ,
285
+ }
286
+ },
287
+
244
288
computed: {
245
289
/**
246
290
* Extend text with asterisk if question is required
@@ -278,12 +322,40 @@ export default {
278
322
hasDescription () {
279
323
return this .description !== ' '
280
324
},
325
+ multipleOptions () {
326
+ const allOptions = this .inputedOptions .split (/ \r ? \n / g )
327
+ return allOptions .filter (answer => { return answer .trim ().length > 0 })
328
+ },
281
329
},
282
330
// Ensure description is sized correctly on initial render
283
331
mounted () {
284
332
this .$nextTick (() => this .resizeDescription ())
285
333
},
286
334
methods: {
335
+ closeModal () {
336
+ this .isModalOpen = false
337
+ },
338
+
339
+ openModal () {
340
+ this .isModalOpen = true
341
+ },
342
+
343
+ onMultipleOptions () {
344
+ this .isModalOpen = false
345
+ this .$nextTick (() => {
346
+ this .$emit (' update:edit' , true )
347
+ if (this .multipleOptions .length > 1 ) {
348
+ // extract all options entries to parent
349
+ this .$emit (' multiple-answers' , this .multipleOptions )
350
+ this .inputedOptions = ' '
351
+ return
352
+ }
353
+ // in case of only one option, just show an error message because it is probably missuse of the feature
354
+ showError (t (' forms' , ' Options should seperated by new line!' ))
355
+ })
356
+
357
+ },
358
+
287
359
onTitleChange ({ target }) {
288
360
this .$emit (' update:text' , target .value )
289
361
},
@@ -481,5 +553,26 @@ export default {
481
553
}
482
554
}
483
555
}
556
+ .modal__content {
557
+ padding : 20px ;
558
+ display : flex ;
559
+ flex-direction : column ;
560
+ }
561
+ .options {
562
+ display : flex !important ;
563
+ flex-wrap : wrap ;
564
+ width : 100% ;
565
+ padding : 10px ;
566
+ justify-content : flex-start ;
567
+ max-height : 300px ;
568
+ overflow-y : auto ;
569
+ margin : 5px 0px ;
570
+ }
571
+ .single_option {
572
+ width : max-content ;
573
+ padding : 5px ;
574
+ margin : 5px ;
575
+ border : 1px solid var (--color-primary );
576
+ }
484
577
485
578
</style >
0 commit comments