Simplify draft monitoring + sockets logic
[qomet.git] / public / javascripts / components / statements.js
1 Vue.component("statements", {
2 // 'answers' is an object containing
3 // 'inputs'(array),
4 // 'displayAll'(bool),
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 )
52 );
53 option.push(
54 h(
55 "label",
56 {
57 domProps: {
58 innerHTML: q.options[idx],
59 },
60 attrs: {
61 "for": this.inputId(i,idx),
62 },
63 }
64 )
65 );
66 optionList.push(
67 h(
68 "div",
69 {
70 "class": {
71 option: true,
72 choiceCorrect: this.answers.showSolution && this.questions[i].answer.includes(idx),
73 choiceWrong: this.answers.showSolution && this.inputs[i][idx] && !q.answer.includes(idx),
74 },
75 },
76 option
77 )
78 );
79 });
80 questionContent.push(
81 h(
82 "div",
83 {
84 "class": {
85 optionList: true,
86 },
87 },
88 optionList
89 )
90 );
91 return h(
92 "div",
93 {
94 "class": {
95 "question": true,
96 "hide": !this.answers.displayAll && this.answers.index != i,
97 },
98 },
99 questionContent
100 );
101 });
102 return h(
103 "div",
104 {
105 attrs: {
106 id: "statements",
107 },
108 },
109 questions
110 );
111 },
112 updated: function() {
113 // TODO: next line shouldn't be required: questions wordings + answer + options
114 // are processed earlier; their content should be updated at this time.
115 statementsLibsRefresh();
116 },
117 methods: {
118 inputId: function(i,j) {
119 return "q" + i + "_" + "input" + j;
120 },
121 },
122 });