@windward/games 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/content/DatableEditor.vue +0 -3
- package/components/content/blocks/crosswordPuzzle/Crossword.ts +231 -153
- package/components/content/blocks/crosswordPuzzle/CrosswordClues.vue +91 -0
- package/components/content/blocks/crosswordPuzzle/CrosswordElements.ts +8 -6
- package/components/content/blocks/crosswordPuzzle/CrosswordPuzzle.vue +502 -371
- package/components/content/blocks/matchingGame/MatchingGame.vue +12 -1
- package/components/content/blocks/multipleChoice/MultipleChoice.vue +187 -127
- package/components/content/blocks/multipleChoice/QuestionDialog.vue +37 -13
- package/components/content/blocks/sevenStrikes/SevenStikes.vue +368 -0
- package/components/content/blocks/sevenStrikes/keyboard.vue +71 -0
- package/components/content/blocks/wordJumble/Jumble.vue +2 -10
- package/components/settings/CrosswordPuzzleSettingsManager.vue +12 -15
- package/components/settings/MatchingGameManager.vue +1 -1
- package/components/settings/MultipleChoiceSettingsManager.vue +21 -7
- package/components/settings/SevenStrikesSettingsManager.vue +288 -0
- package/i18n/en-US/components/content/blocks/crossword.ts +18 -3
- package/i18n/en-US/components/content/blocks/index.ts +2 -0
- package/i18n/en-US/components/content/blocks/multiple_choice.ts +2 -4
- package/i18n/en-US/components/content/blocks/seven_strikes.ts +6 -0
- package/i18n/en-US/components/settings/crossword.ts +2 -1
- package/i18n/en-US/components/settings/index.ts +2 -0
- package/i18n/en-US/components/settings/multiple_choice.ts +1 -1
- package/i18n/en-US/components/settings/seven_strikes.ts +8 -0
- package/i18n/en-US/shared/content_blocks.ts +1 -0
- package/i18n/en-US/shared/settings.ts +1 -0
- package/package.json +2 -1
- package/plugin.js +21 -0
- package/test/blocks/sevenStrikes/sevenStrikes.spec.js +24 -0
- package/test/settings/SevenStrikesManager.spec.js +53 -0
|
@@ -118,6 +118,7 @@
|
|
|
118
118
|
>
|
|
119
119
|
<v-card-text>
|
|
120
120
|
<draggable
|
|
121
|
+
v-if="mainPrompt['file']"
|
|
121
122
|
class="dragArea list-group"
|
|
122
123
|
:key="mainPrompt['prompt']"
|
|
123
124
|
v-bind="dragOptions"
|
|
@@ -393,7 +394,17 @@ export default {
|
|
|
393
394
|
solvedQuestions: [],
|
|
394
395
|
status: 'default',
|
|
395
396
|
allowDrag: true,
|
|
396
|
-
mainPrompt: {
|
|
397
|
+
mainPrompt: {
|
|
398
|
+
altText: '',
|
|
399
|
+
answer: {},
|
|
400
|
+
file: {
|
|
401
|
+
asset: {
|
|
402
|
+
public_url: '',
|
|
403
|
+
},
|
|
404
|
+
name: '',
|
|
405
|
+
},
|
|
406
|
+
prompt: '',
|
|
407
|
+
},
|
|
397
408
|
editedPrompt: {},
|
|
398
409
|
startingIndex: 0,
|
|
399
410
|
}
|
|
@@ -11,19 +11,16 @@
|
|
|
11
11
|
<v-carousel height="600">
|
|
12
12
|
<v-container>
|
|
13
13
|
<v-carousel-item
|
|
14
|
-
v-for="
|
|
15
|
-
|
|
16
|
-
:key="index"
|
|
14
|
+
v-for="question in block.metadata.config.questions"
|
|
15
|
+
:key="question.id"
|
|
17
16
|
>
|
|
18
17
|
<v-col class="d-flex justify-center">
|
|
19
18
|
<p class="questionBody">{{ question.body }}</p>
|
|
20
19
|
</v-col>
|
|
21
20
|
<v-container :key="updateKey">
|
|
22
21
|
<v-row
|
|
23
|
-
v-for="
|
|
24
|
-
|
|
25
|
-
) in question.answer_options"
|
|
26
|
-
:key="answerIndex"
|
|
22
|
+
v-for="answer in question.answer_options"
|
|
23
|
+
:key="answer.id"
|
|
27
24
|
class="mb-2"
|
|
28
25
|
>
|
|
29
26
|
<v-col
|
|
@@ -32,37 +29,15 @@
|
|
|
32
29
|
class="d-flex justify-end"
|
|
33
30
|
>
|
|
34
31
|
<v-icon
|
|
35
|
-
class="
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
.answer_options[answerIndex]
|
|
41
|
-
.chosen === true
|
|
42
|
-
"
|
|
43
|
-
>mdi-check-circle</v-icon
|
|
44
|
-
>
|
|
45
|
-
<v-icon
|
|
46
|
-
class="isCorrect"
|
|
47
|
-
v-if="
|
|
48
|
-
studentResponses[index] &&
|
|
49
|
-
answer.correctAnswer === true &&
|
|
50
|
-
studentResponses[index]
|
|
51
|
-
.answer_options[answerIndex]
|
|
52
|
-
.chosen !== true
|
|
53
|
-
"
|
|
54
|
-
>mdi-check-circle-outline</v-icon
|
|
55
|
-
>
|
|
56
|
-
<v-icon
|
|
57
|
-
class="isIncorrect"
|
|
58
|
-
v-if="
|
|
59
|
-
studentResponses[index] &&
|
|
60
|
-
answer.correctAnswer !== true &&
|
|
61
|
-
studentResponses[index]
|
|
62
|
-
.answer_options[answerIndex]
|
|
63
|
-
.chosen === true
|
|
32
|
+
:class="
|
|
33
|
+
handleIconClass(
|
|
34
|
+
question,
|
|
35
|
+
answer
|
|
36
|
+
)
|
|
64
37
|
"
|
|
65
|
-
>
|
|
38
|
+
>{{
|
|
39
|
+
handleIcon(question, answer)
|
|
40
|
+
}}</v-icon
|
|
66
41
|
>
|
|
67
42
|
</v-col>
|
|
68
43
|
<v-col cols="12" md="8" class="pa-0">
|
|
@@ -70,12 +45,15 @@
|
|
|
70
45
|
class="optionOutline pa-2"
|
|
71
46
|
:disabled="answer.disabled"
|
|
72
47
|
:class="
|
|
73
|
-
onIsThisCorrect(
|
|
48
|
+
onIsThisCorrect(
|
|
49
|
+
answer,
|
|
50
|
+
question
|
|
51
|
+
)
|
|
74
52
|
"
|
|
75
53
|
outlined
|
|
76
54
|
tile
|
|
77
55
|
@click="
|
|
78
|
-
onChooseAnswer(answer,
|
|
56
|
+
onChooseAnswer(answer, question)
|
|
79
57
|
"
|
|
80
58
|
>
|
|
81
59
|
<div
|
|
@@ -93,50 +71,24 @@
|
|
|
93
71
|
</p>
|
|
94
72
|
<div>
|
|
95
73
|
<v-icon
|
|
96
|
-
class="
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
] &&
|
|
101
|
-
answer.correctAnswer ===
|
|
102
|
-
true &&
|
|
103
|
-
studentResponses[
|
|
104
|
-
index
|
|
105
|
-
].answer_options[
|
|
106
|
-
answerIndex
|
|
107
|
-
].chosen !== true
|
|
108
|
-
"
|
|
109
|
-
@click="
|
|
110
|
-
onAnswerDescription(
|
|
111
|
-
question
|
|
74
|
+
:class="
|
|
75
|
+
handleInformationClass(
|
|
76
|
+
question,
|
|
77
|
+
answer
|
|
112
78
|
)
|
|
113
79
|
"
|
|
114
|
-
>mdi-information</v-icon
|
|
115
|
-
>
|
|
116
|
-
<v-icon
|
|
117
|
-
right
|
|
118
|
-
dark
|
|
119
|
-
nontranslate
|
|
120
|
-
v-if="
|
|
121
|
-
studentResponses[
|
|
122
|
-
index
|
|
123
|
-
] &&
|
|
124
|
-
answer.correctAnswer ==
|
|
125
|
-
true &&
|
|
126
|
-
studentResponses[
|
|
127
|
-
index
|
|
128
|
-
].answer_options[
|
|
129
|
-
answerIndex
|
|
130
|
-
].chosen === true
|
|
131
|
-
"
|
|
132
80
|
@click="
|
|
133
81
|
onAnswerDescription(
|
|
134
82
|
question
|
|
135
83
|
)
|
|
136
84
|
"
|
|
85
|
+
>{{
|
|
86
|
+
handleInformationOutline(
|
|
87
|
+
question,
|
|
88
|
+
answer
|
|
89
|
+
)
|
|
90
|
+
}}</v-icon
|
|
137
91
|
>
|
|
138
|
-
mdi-information-outline
|
|
139
|
-
</v-icon>
|
|
140
92
|
</div>
|
|
141
93
|
</div>
|
|
142
94
|
</v-card>
|
|
@@ -188,7 +140,7 @@
|
|
|
188
140
|
)
|
|
189
141
|
}}
|
|
190
142
|
<v-progress-linear
|
|
191
|
-
color="
|
|
143
|
+
color="success"
|
|
192
144
|
outlined
|
|
193
145
|
v-model="completedPercent"
|
|
194
146
|
rounded
|
|
@@ -198,10 +150,10 @@
|
|
|
198
150
|
</v-flex>
|
|
199
151
|
<v-flex xs4></v-flex>
|
|
200
152
|
</v-layout>
|
|
201
|
-
<v-layout class="mt-2" v-if="
|
|
153
|
+
<v-layout class="mt-2" v-if="mountCourseCounter">
|
|
202
154
|
<v-flex xs8></v-flex>
|
|
203
155
|
<v-flex xs4>
|
|
204
|
-
<v-col
|
|
156
|
+
<v-col>
|
|
205
157
|
<p>
|
|
206
158
|
{{
|
|
207
159
|
$t(
|
|
@@ -240,7 +192,7 @@
|
|
|
240
192
|
<div v-if="answerDescriptionModal">
|
|
241
193
|
{{
|
|
242
194
|
$t(
|
|
243
|
-
'plugin.games.components.content.blocks.multiple_choice.
|
|
195
|
+
'plugin.games.components.content.blocks.multiple_choice.answer_feedback'
|
|
244
196
|
)
|
|
245
197
|
}}
|
|
246
198
|
</div>
|
|
@@ -295,7 +247,6 @@ export default {
|
|
|
295
247
|
if (_.isEmpty(this.block.metadata.config.questions)) {
|
|
296
248
|
this.block.metadata.config.questions = []
|
|
297
249
|
}
|
|
298
|
-
this.updateTotals = 1
|
|
299
250
|
},
|
|
300
251
|
data() {
|
|
301
252
|
return {
|
|
@@ -308,14 +259,15 @@ export default {
|
|
|
308
259
|
answerDescription: '',
|
|
309
260
|
studentAmountCorrect: null,
|
|
310
261
|
totalQuestionsMultipleChoice: null,
|
|
311
|
-
updateTotals: 1,
|
|
312
262
|
studentResponses: [],
|
|
263
|
+
mountCourseCounter: false,
|
|
313
264
|
}
|
|
314
265
|
},
|
|
315
266
|
computed: {
|
|
316
267
|
...mapGetters({
|
|
317
268
|
organization: 'organization/get',
|
|
318
269
|
course: 'course/get',
|
|
270
|
+
enrollment: 'enrollment/get',
|
|
319
271
|
}),
|
|
320
272
|
completedAmount() {
|
|
321
273
|
if (this.completedItems) {
|
|
@@ -337,8 +289,15 @@ export default {
|
|
|
337
289
|
return 0
|
|
338
290
|
},
|
|
339
291
|
},
|
|
292
|
+
watch: {
|
|
293
|
+
render(newValue) {
|
|
294
|
+
if (newValue) {
|
|
295
|
+
this.onTotalAmountOfQuestions()
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
},
|
|
340
299
|
mounted() {
|
|
341
|
-
this.
|
|
300
|
+
this.mountCourseCounter = false
|
|
342
301
|
this.onAmountCorrect()
|
|
343
302
|
this.onTotalAmountOfQuestions()
|
|
344
303
|
},
|
|
@@ -348,6 +307,7 @@ export default {
|
|
|
348
307
|
// grabs user state to get the total amount of questions a studentanswered correctly
|
|
349
308
|
let userState = await UserContentBlockState.where({
|
|
350
309
|
'metadata->block->tag': 'plugin-games-multiple-choice',
|
|
310
|
+
course_user_id: this.enrollment.id,
|
|
351
311
|
}).get()
|
|
352
312
|
userState.forEach((state) => {
|
|
353
313
|
state.metadata.studentResponses.forEach((element) => {
|
|
@@ -356,12 +316,12 @@ export default {
|
|
|
356
316
|
}
|
|
357
317
|
})
|
|
358
318
|
})
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
319
|
+
// need to wait till correct has the new value to set the var
|
|
320
|
+
setTimeout(() => {
|
|
321
|
+
// sets total
|
|
322
|
+
this.studentAmountCorrect = correct
|
|
323
|
+
this.mountCourseCounter = true
|
|
324
|
+
}, 1000)
|
|
365
325
|
},
|
|
366
326
|
async onTotalAmountOfQuestions() {
|
|
367
327
|
let multipleChoiceTotalQuestions = 0
|
|
@@ -388,27 +348,28 @@ export default {
|
|
|
388
348
|
this.answerDescriptionModal = true
|
|
389
349
|
this.answerDescription = question.answer_description
|
|
390
350
|
},
|
|
391
|
-
onChooseAnswer(answer,
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
this.studentResponses[questionIndex] = _.cloneDeep(
|
|
400
|
-
this.block.metadata.config.questions[questionIndex]
|
|
401
|
-
)
|
|
351
|
+
onChooseAnswer(answer, question) {
|
|
352
|
+
let studRep
|
|
353
|
+
this.studentResponses.find((obj) => {
|
|
354
|
+
if (obj.id === question.id) {
|
|
355
|
+
studRep = obj
|
|
356
|
+
}
|
|
357
|
+
})
|
|
358
|
+
if (_.isEmpty(this.studentResponses) || _.isEmpty(studRep)) {
|
|
402
359
|
// lets html side know whish answer was chosen, this is important in determine css
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
360
|
+
answer.chosen = true
|
|
361
|
+
// clones question block into the correct index in the studentResponses araay
|
|
362
|
+
const clonedQuestion = _.cloneDeep(question)
|
|
363
|
+
clonedQuestion.student_response = answer
|
|
364
|
+
|
|
365
|
+
if (answer.correctAnswer === true) {
|
|
366
|
+
this.studentAmountCorrect = this.studentAmountCorrect + 1
|
|
367
|
+
clonedQuestion.isStudentCorrect = true
|
|
368
|
+
} else {
|
|
369
|
+
clonedQuestion.isStudentCorrect = false
|
|
370
|
+
}
|
|
408
371
|
|
|
409
|
-
|
|
410
|
-
const question =
|
|
411
|
-
this.block.metadata.config.questions[questionIndex]
|
|
372
|
+
this.studentResponses.push(clonedQuestion)
|
|
412
373
|
// ensure the object is not already in the completed items array if not push into the array
|
|
413
374
|
const questionDone = this.completedItems.find(
|
|
414
375
|
(item) => item === question
|
|
@@ -417,26 +378,24 @@ export default {
|
|
|
417
378
|
if (!questionDone) {
|
|
418
379
|
this.completedItems.push(question)
|
|
419
380
|
}
|
|
420
|
-
if (answer.correctAnswer === true) {
|
|
421
|
-
this.studentAmountCorrect = this.studentAmountCorrect + 1
|
|
422
|
-
this.studentResponses[questionIndex].isStudentCorrect = true
|
|
423
|
-
}
|
|
424
381
|
|
|
425
382
|
this.updateKey = Crypto.id()
|
|
426
383
|
}
|
|
427
384
|
},
|
|
428
|
-
onIsThisCorrect(answer,
|
|
385
|
+
onIsThisCorrect(answer, question) {
|
|
386
|
+
const studentsQuestionResponse = this.studentResponses.find(
|
|
387
|
+
(obj) => {
|
|
388
|
+
if (obj.id === question.id) {
|
|
389
|
+
return obj
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
)
|
|
429
393
|
// check if student already responded
|
|
430
|
-
if (
|
|
431
|
-
!_.isEmpty(
|
|
432
|
-
this.studentResponses[questionIndex] &&
|
|
433
|
-
this.studentResponses[questionIndex].student_response
|
|
434
|
-
)
|
|
435
|
-
) {
|
|
394
|
+
if (studentsQuestionResponse) {
|
|
436
395
|
// checks if answer is correct and applies class
|
|
437
396
|
if (
|
|
438
|
-
|
|
439
|
-
|
|
397
|
+
studentsQuestionResponse.student_response.correctAnswer ===
|
|
398
|
+
true
|
|
440
399
|
) {
|
|
441
400
|
if (answer.correctAnswer === true) {
|
|
442
401
|
return 'studentAnswerCorrect'
|
|
@@ -444,17 +403,115 @@ export default {
|
|
|
444
403
|
return ''
|
|
445
404
|
}
|
|
446
405
|
} else if (
|
|
447
|
-
|
|
448
|
-
|
|
406
|
+
studentsQuestionResponse.student_response.correctAnswer !==
|
|
407
|
+
true &&
|
|
408
|
+
studentsQuestionResponse.student_response.id === answer.id
|
|
449
409
|
) {
|
|
450
|
-
if (
|
|
451
|
-
|
|
452
|
-
} else if (
|
|
453
|
-
this.studentResponses[questionIndex].student_response
|
|
410
|
+
if (
|
|
411
|
+
studentsQuestionResponse.student_response
|
|
454
412
|
.correctAnswer !== true
|
|
455
413
|
) {
|
|
456
414
|
return 'incorrectBorder'
|
|
457
415
|
}
|
|
416
|
+
} else if (
|
|
417
|
+
studentsQuestionResponse.student_response.correctAnswer !==
|
|
418
|
+
true
|
|
419
|
+
) {
|
|
420
|
+
if (answer.correctAnswer === true) {
|
|
421
|
+
return 'correctBorder'
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
handleIcon(question, answer) {
|
|
427
|
+
const studentsQuestionResponse = this.studentResponses.find(
|
|
428
|
+
(obj) => {
|
|
429
|
+
if (obj.id === question.id) {
|
|
430
|
+
return obj
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
)
|
|
434
|
+
if (studentsQuestionResponse) {
|
|
435
|
+
// requirements for correct and chosen
|
|
436
|
+
if (
|
|
437
|
+
answer.id ===
|
|
438
|
+
studentsQuestionResponse.student_response.id &&
|
|
439
|
+
answer.correctAnswer === true &&
|
|
440
|
+
studentsQuestionResponse.student_response.chosen === true
|
|
441
|
+
) {
|
|
442
|
+
return 'mdi-check-circle'
|
|
443
|
+
}
|
|
444
|
+
//requirements for correct and unchosen
|
|
445
|
+
if (answer.correctAnswer === true && answer.chosen === false) {
|
|
446
|
+
return 'mdi-check-circle-outline'
|
|
447
|
+
}
|
|
448
|
+
// requirements for wrong and chosen
|
|
449
|
+
if (answer.correctAnswer !== true && answer.chosen === true) {
|
|
450
|
+
return 'mdi-alpha-x-circle'
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
},
|
|
454
|
+
handleIconClass(question, answer) {
|
|
455
|
+
const studentsQuestionResponse = this.studentResponses.find(
|
|
456
|
+
(obj) => {
|
|
457
|
+
return obj.id === question.id
|
|
458
|
+
}
|
|
459
|
+
)
|
|
460
|
+
if (studentsQuestionResponse) {
|
|
461
|
+
// requirements for correct and chosen
|
|
462
|
+
if (
|
|
463
|
+
answer.id ===
|
|
464
|
+
studentsQuestionResponse.student_response.id &&
|
|
465
|
+
answer.correctAnswer === true &&
|
|
466
|
+
studentsQuestionResponse.student_response.chosen === true
|
|
467
|
+
) {
|
|
468
|
+
return 'isCorrect'
|
|
469
|
+
}
|
|
470
|
+
//requirements for correct and unchosen
|
|
471
|
+
if (answer.correctAnswer === true && answer.chosen === false) {
|
|
472
|
+
return 'isCorrect'
|
|
473
|
+
}
|
|
474
|
+
// requirements for wrong and chosen
|
|
475
|
+
if (answer.correctAnswer !== true && answer.chosen === true) {
|
|
476
|
+
return 'isIncorrect'
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
},
|
|
480
|
+
handleInformationOutline(question, answer) {
|
|
481
|
+
const studentsQuestionResponse = this.studentResponses.find(
|
|
482
|
+
(obj) => {
|
|
483
|
+
if (obj.id === question.id) {
|
|
484
|
+
return obj
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
)
|
|
488
|
+
if (studentsQuestionResponse) {
|
|
489
|
+
if (answer.correctAnswer === true && answer.chosen === true) {
|
|
490
|
+
return 'mdi-information'
|
|
491
|
+
} else if (
|
|
492
|
+
answer.correctAnswer === true &&
|
|
493
|
+
answer.chosen === false
|
|
494
|
+
) {
|
|
495
|
+
return 'mdi-information-outline'
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
},
|
|
499
|
+
handleInformationClass(question, answer) {
|
|
500
|
+
const studentsQuestionResponse = this.studentResponses.find(
|
|
501
|
+
(obj) => {
|
|
502
|
+
if (obj.id === question.id) {
|
|
503
|
+
return obj
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
)
|
|
507
|
+
if (studentsQuestionResponse) {
|
|
508
|
+
if (answer.correctAnswer === true && answer.chosen === true) {
|
|
509
|
+
return 'informationCorrect'
|
|
510
|
+
} else if (
|
|
511
|
+
answer.correctAnswer === true &&
|
|
512
|
+
answer.chosen === false
|
|
513
|
+
) {
|
|
514
|
+
return 'isCorrect'
|
|
458
515
|
}
|
|
459
516
|
}
|
|
460
517
|
},
|
|
@@ -475,7 +532,7 @@ export default {
|
|
|
475
532
|
this.hint = true
|
|
476
533
|
// sets text for modal, cannot just reference question.hint in html because
|
|
477
534
|
// the carousel loads all elements regardless of if they are on a different slide or not
|
|
478
|
-
// when
|
|
535
|
+
// when mountCourseCounter so it always shows the last question if referenced question.hint
|
|
479
536
|
this.hintText = question.hint
|
|
480
537
|
},
|
|
481
538
|
onFifty(question) {
|
|
@@ -549,6 +606,9 @@ export default {
|
|
|
549
606
|
.isIncorrect {
|
|
550
607
|
color: var(--v-error-base);
|
|
551
608
|
}
|
|
609
|
+
.informationCorrect {
|
|
610
|
+
color: white;
|
|
611
|
+
}
|
|
552
612
|
.iconStudentCorrect {
|
|
553
613
|
color: var(--v-success-base);
|
|
554
614
|
border-radius: 25px;
|
|
@@ -29,20 +29,21 @@
|
|
|
29
29
|
v-model="question.answer_description"
|
|
30
30
|
:label="
|
|
31
31
|
$t(
|
|
32
|
-
'plugin.games.components.settings.multiple_choice.
|
|
32
|
+
'plugin.games.components.settings.multiple_choice.answer_feedback'
|
|
33
33
|
)
|
|
34
34
|
"
|
|
35
35
|
rows="2"
|
|
36
36
|
:rules="validation.textRules"
|
|
37
37
|
prepend-inner-icon="mdi-comment"
|
|
38
38
|
></v-textarea>
|
|
39
|
-
<
|
|
39
|
+
<br />
|
|
40
|
+
<h4 class="pb-2">
|
|
40
41
|
{{
|
|
41
42
|
$t(
|
|
42
43
|
'plugin.games.components.settings.multiple_choice.answer_options'
|
|
43
44
|
)
|
|
44
45
|
}}
|
|
45
|
-
</
|
|
46
|
+
</h4>
|
|
46
47
|
<p>
|
|
47
48
|
{{
|
|
48
49
|
$t(
|
|
@@ -63,16 +64,20 @@
|
|
|
63
64
|
@mouseover="onHover"
|
|
64
65
|
@mouseleave="onHoverLeave"
|
|
65
66
|
>
|
|
66
|
-
<v-
|
|
67
|
-
v-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
<v-radio-group v-model="question.correctAnswer">
|
|
68
|
+
<v-radio
|
|
69
|
+
:ref="'checkbox' + index"
|
|
70
|
+
v-on:keydown.enter="onSetAnswer(answer, true)"
|
|
71
|
+
:value="answer.id"
|
|
72
|
+
@click="onSetAnswer(answer)"
|
|
73
|
+
></v-radio>
|
|
74
|
+
</v-radio-group>
|
|
71
75
|
</v-col>
|
|
72
76
|
<v-col cols="12" md="10">
|
|
73
77
|
<v-textarea
|
|
74
78
|
flat
|
|
75
79
|
solo
|
|
80
|
+
:autofocus="answer.focus"
|
|
76
81
|
v-model="answer.value"
|
|
77
82
|
:outlined="setOutline(answer)"
|
|
78
83
|
hide-details
|
|
@@ -142,23 +147,32 @@ export default {
|
|
|
142
147
|
this.question = {
|
|
143
148
|
answer_options: [
|
|
144
149
|
{
|
|
145
|
-
id:
|
|
150
|
+
id: Crypto.id(),
|
|
146
151
|
value: '',
|
|
147
152
|
correctAnswer: true,
|
|
148
153
|
disabled: false,
|
|
154
|
+
chosen: false,
|
|
155
|
+
focus: false,
|
|
149
156
|
},
|
|
150
157
|
{
|
|
151
|
-
id:
|
|
158
|
+
id: Crypto.id(),
|
|
152
159
|
value: '',
|
|
153
160
|
correctAnswer: false,
|
|
154
161
|
disabled: false,
|
|
162
|
+
chosen: false,
|
|
163
|
+
focus: false,
|
|
155
164
|
},
|
|
156
165
|
],
|
|
166
|
+
// needed to add this bc radio group needs the id of the answer to set correct
|
|
167
|
+
correctAnswer: 1,
|
|
157
168
|
body: '',
|
|
158
169
|
hint: '',
|
|
159
170
|
answer_description: '',
|
|
160
171
|
}
|
|
161
172
|
}
|
|
173
|
+
if (newValue && newValue.body === '') {
|
|
174
|
+
this.$refs.form.resetValidation()
|
|
175
|
+
}
|
|
162
176
|
},
|
|
163
177
|
},
|
|
164
178
|
},
|
|
@@ -198,7 +212,10 @@ export default {
|
|
|
198
212
|
}
|
|
199
213
|
},
|
|
200
214
|
mounted() {
|
|
201
|
-
if (
|
|
215
|
+
if (this.value.body === '') {
|
|
216
|
+
this.$refs.form.resetValidation()
|
|
217
|
+
this.question = _.cloneDeep(this.value)
|
|
218
|
+
} else if (!_.isEmpty(this.value)) {
|
|
202
219
|
this.question = _.cloneDeep(this.value)
|
|
203
220
|
}
|
|
204
221
|
// refreshes data for modal on mount
|
|
@@ -218,9 +235,14 @@ export default {
|
|
|
218
235
|
this.$emit('input', emittedQuestion)
|
|
219
236
|
this.$emit('saveAndNew')
|
|
220
237
|
},
|
|
221
|
-
onSetAnswer(answer) {
|
|
238
|
+
onSetAnswer(answer, onEnter = null) {
|
|
239
|
+
if (onEnter) {
|
|
240
|
+
this.question.correctAnswer = answer.id
|
|
241
|
+
}
|
|
222
242
|
// changes all inputs that aren't the choosen correct answer to be unchecked
|
|
223
243
|
const index = this.question.answer_options.indexOf(answer)
|
|
244
|
+
// programatically set to true here, was orginally set up as checkboxs so that was previously happening in the html
|
|
245
|
+
this.question.answer_options[index].correctAnswer = true
|
|
224
246
|
this.question.answer_options.forEach((element) => {
|
|
225
247
|
const loopIndex = this.question.answer_options.indexOf(element)
|
|
226
248
|
if (loopIndex !== index) {
|
|
@@ -234,10 +256,12 @@ export default {
|
|
|
234
256
|
onAddAnswer() {
|
|
235
257
|
// pushes new answer object into answer options
|
|
236
258
|
const answerObject = {
|
|
237
|
-
id:
|
|
259
|
+
id: Crypto.id(),
|
|
238
260
|
value: '',
|
|
239
261
|
correctAnswer: false,
|
|
240
262
|
disabled: false,
|
|
263
|
+
chosen: false,
|
|
264
|
+
focus: true,
|
|
241
265
|
}
|
|
242
266
|
this.question.answer_options.push(answerObject)
|
|
243
267
|
},
|