Commit | Line | Data |
---|---|---|
435371c7 | 1 | Vue.component("statements", { |
8a51dbf7 BA |
2 | // 'answers' is an object containing |
3 | // 'inputs'(array), | |
e49ec3e4 | 4 | // 'displayAll'(bool), //TODO: should be in questions! |
8a51dbf7 BA |
5 | // 'showSolution'(bool), |
6 | // 'indices': order of appearance | |
7 | // 'index': current integer index (focused question) | |
8 | props: ['questions','answers'], | |
435371c7 BA |
9 | // TODO: general render function for nested exercises |
10 | // There should be a questions navigator below, or next (visible if display=='all') | |
11 | // Full questions tree is rendered, but some parts hidden depending on display settings | |
12 | render(h) { | |
8a51dbf7 | 13 | // TODO: render nothing if answers is empty |
71d1ca9c | 14 | let domTree = (this.questions || [ ]).map( (q,i) => { |
435371c7 BA |
15 | let questionContent = [ ]; |
16 | questionContent.push( | |
17 | h( | |
18 | "div", | |
19 | { | |
20 | "class": { | |
21 | wording: true, | |
22 | }, | |
23 | domProps: { | |
24 | innerHTML: q.wording, | |
25 | }, | |
26 | } | |
27 | ) | |
28 | ); | |
29 | let optionsOrder = _.range(q.options.length); | |
30 | if (!q.fixed) | |
31 | optionsOrder = _.shuffle(optionsOrder); | |
32 | let optionList = [ ]; | |
33 | optionsOrder.forEach( idx => { | |
34 | let option = [ ]; | |
35 | option.push( | |
36 | h( | |
37 | "input", | |
38 | { | |
39 | domProps: { | |
8a51dbf7 | 40 | checked: this.answers.inputs.length > 0 && this.answers.inputs[i][idx], |
435371c7 BA |
41 | disabled: monitoring, |
42 | }, | |
43 | attrs: { | |
44 | id: this.inputId(i,idx), | |
45 | type: "checkbox", | |
46 | }, | |
47 | on: { | |
8a51dbf7 | 48 | change: e => { this.answers.inputs[i][idx] = e.target.checked; }, |
435371c7 BA |
49 | }, |
50 | }, | |
8a2b3260 | 51 | [ '' ] //to work in Firefox 45.9 ESR @ ENSTA... |
435371c7 BA |
52 | ) |
53 | ); | |
54 | option.push( | |
55 | h( | |
56 | "label", | |
57 | { | |
58 | domProps: { | |
59 | innerHTML: q.options[idx], | |
60 | }, | |
61 | attrs: { | |
62 | "for": this.inputId(i,idx), | |
63 | }, | |
64 | } | |
65 | ) | |
66 | ); | |
67 | optionList.push( | |
68 | h( | |
69 | "div", | |
70 | { | |
71 | "class": { | |
72 | option: true, | |
8a51dbf7 | 73 | choiceCorrect: this.answers.showSolution && this.questions[i].answer.includes(idx), |
71d1ca9c | 74 | choiceWrong: this.answers.showSolution && this.answers.inputs[i][idx] && !q.answer.includes(idx), |
435371c7 BA |
75 | }, |
76 | }, | |
77 | option | |
78 | ) | |
79 | ); | |
80 | }); | |
81 | questionContent.push( | |
82 | h( | |
83 | "div", | |
84 | { | |
85 | "class": { | |
86 | optionList: true, | |
87 | }, | |
88 | }, | |
89 | optionList | |
90 | ) | |
91 | ); | |
e49ec3e4 BA |
92 | if (this.answers.displayAll && i < this.questions.length-1) |
93 | questionContent.push( h("hr") ); | |
435371c7 BA |
94 | return h( |
95 | "div", | |
96 | { | |
97 | "class": { | |
98 | "question": true, | |
71d1ca9c | 99 | "hide": !this.answers.displayAll && this.answers.indices[this.answers.index] != i, |
435371c7 BA |
100 | }, |
101 | }, | |
102 | questionContent | |
103 | ); | |
104 | }); | |
105 | return h( | |
106 | "div", | |
107 | { | |
108 | attrs: { | |
109 | id: "statements", | |
110 | }, | |
111 | }, | |
71d1ca9c | 112 | domTree |
435371c7 BA |
113 | ); |
114 | }, | |
3b8117c5 BA |
115 | mounted: function() { |
116 | statementsLibsRefresh(); | |
117 | }, | |
435371c7 BA |
118 | updated: function() { |
119 | // TODO: next line shouldn't be required: questions wordings + answer + options | |
120 | // are processed earlier; their content should be updated at this time. | |
121 | statementsLibsRefresh(); | |
122 | }, | |
123 | methods: { | |
124 | inputId: function(i,j) { | |
125 | return "q" + i + "_" + "input" + j; | |
126 | }, | |
127 | }, | |
128 | }); |