Harmonize with web version, better style, fix for Firefox 45.9.0 ESR
[qomet.git] / public / javascripts / components / statements.js
1 Vue.component("statements", {
2 // 'answers' is an object containing
3 // 'inputs'(array),
4 // 'displayAll'(bool), //TODO: should be in questions!
5 // 'showSolution'(bool),
6 // 'indices': order of appearance
7 // 'index': current integer index (focused question)
8 props: ['questions','answers'],
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) {
13 // TODO: render nothing if answers is empty
14 let domTree = (this.questions || [ ]).map( (q,i) => {
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: {
40 checked: this.answers.inputs.length > 0 && this.answers.inputs[i][idx],
41 disabled: monitoring,
42 },
43 attrs: {
44 id: this.inputId(i,idx),
45 type: "checkbox",
46 },
47 on: {
48 change: e => { this.answers.inputs[i][idx] = e.target.checked; },
49 },
50 },
51 [ '' ] //to work in Firefox 45.9 ESR @ ENSTA...
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,
73 choiceCorrect: this.answers.showSolution && this.questions[i].answer.includes(idx),
74 choiceWrong: this.answers.showSolution && this.answers.inputs[i][idx] && !q.answer.includes(idx),
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 );
92 if (this.answers.displayAll && i < this.questions.length-1)
93 questionContent.push( h("hr") );
94 return h(
95 "div",
96 {
97 "class": {
98 "question": true,
99 "hide": !this.answers.displayAll && this.answers.indices[this.answers.index] != i,
100 },
101 },
102 questionContent
103 );
104 });
105 return h(
106 "div",
107 {
108 attrs: {
109 id: "statements",
110 },
111 },
112 domTree
113 );
114 },
115 mounted: function() {
116 statementsLibsRefresh();
117 },
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 });