prawda/falsz questions
[redakcja.git] / redakcja / static / edumed / js / edumed.js
1 (function() {
2   var $, Binding, EduModule, Excercise, Luki, PrawdaFalsz, Przyporzadkuj, Uporzadkuj, Wybor, Zastap, excercise,
3     __hasProp = Object.prototype.hasOwnProperty,
4     __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; };
5
6   $ = jQuery;
7
8   Binding = (function() {
9
10     function Binding(handler, element) {
11       this.handler = handler;
12       this.element = element;
13       $(this.element).data(this.handler, this);
14     }
15
16     return Binding;
17
18   })();
19
20   EduModule = (function(_super) {
21
22     __extends(EduModule, _super);
23
24     function EduModule(element) {
25       var _this = this;
26       EduModule.__super__.constructor.call(this, 'edumodule', element);
27       $("[name=teacher-toggle]").change(function(ev) {
28         if ($(ev.target).is(":checked")) {
29           return $(".teacher", _this.element).addClass("show");
30         } else {
31           return $(".teacher", _this.element).removeClass("show");
32         }
33       });
34     }
35
36     return EduModule;
37
38   })(Binding);
39
40   Excercise = (function(_super) {
41
42     __extends(Excercise, _super);
43
44     function Excercise(element) {
45       var _this = this;
46       Excercise.__super__.constructor.call(this, 'excercise', element);
47       $(".check", this.element).click(function() {
48         return _this.check();
49       });
50       $('.solutions', this.element).click(function() {
51         return _this.show_solutions();
52       });
53     }
54
55     Excercise.prototype.piece_correct = function(qpiece) {
56       return $(qpiece).removeClass('incorrect').addClass('correct');
57     };
58
59     Excercise.prototype.piece_incorrect = function(qpiece) {
60       return $(qpiece).removeClass('correct').addClass('incorrect');
61     };
62
63     Excercise.prototype.check = function() {
64       var score, scores,
65         _this = this;
66       scores = [];
67       $(".question", this.element).each(function(i, question) {
68         return scores.push(_this.check_question(question));
69       });
70       score = [0, 0];
71       $.each(scores, function(i, s) {
72         score[0] += s[0];
73         return score[1] += s[1];
74       });
75       return this.show_score(score);
76     };
77
78     Excercise.prototype.get_value_list = function(elem, data_key, numbers) {
79       var vl;
80       vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim);
81       if (numbers) {
82         vl = vl.map(function(x) {
83           return parseInt(x);
84         });
85       }
86       return vl;
87     };
88
89     Excercise.prototype.get_value_optional_list = function(elem, data_key) {
90       var mandat, opt, v, vals, _i, _len;
91       vals = this.get_value_list(elem, data_key);
92       mandat = [];
93       opt = [];
94       for (_i = 0, _len = vals.length; _i < _len; _i++) {
95         v = vals[_i];
96         if (v.slice(-1) === "?") {
97           opt.push(v.slice(0, -1));
98         } else {
99           mandat.push(v);
100         }
101       }
102       return [mandat, opt];
103     };
104
105     Excercise.prototype.show_score = function(score) {
106       return $(".message", this.element).text("Wynik: " + score[0] + " / " + score[1]);
107     };
108
109     return Excercise;
110
111   })(Binding);
112
113   Wybor = (function(_super) {
114
115     __extends(Wybor, _super);
116
117     function Wybor(element) {
118       Wybor.__super__.constructor.call(this, element);
119     }
120
121     Wybor.prototype.check_question = function(question) {
122       var all, good, solution,
123         _this = this;
124       all = 0;
125       good = 0;
126       solution = this.get_value_list(question, 'solution');
127       $(".question-piece", question).each(function(i, qpiece) {
128         var is_checked, piece_name, piece_no, should_be_checked;
129         piece_no = $(qpiece).attr('data-no');
130         piece_name = $(qpiece).attr('data-name');
131         if (piece_name) {
132           should_be_checked = solution.indexOf(piece_name) >= 0;
133         } else {
134           should_be_checked = solution.indexOf(piece_no) >= 0;
135         }
136         is_checked = $("input", qpiece).is(":checked");
137         if (should_be_checked) all += 1;
138         if (is_checked) {
139           if (should_be_checked) {
140             good += 1;
141             return _this.piece_correct(qpiece);
142           } else {
143             return _this.piece_incorrect(qpiece);
144           }
145         } else {
146           return $(qpiece).removeClass("correct,incorrect");
147         }
148       });
149       return [good, all];
150     };
151
152     Wybor.prototype.show_solutions = function() {};
153
154     return Wybor;
155
156   })(Excercise);
157
158   Uporzadkuj = (function(_super) {
159
160     __extends(Uporzadkuj, _super);
161
162     function Uporzadkuj(element) {
163       Uporzadkuj.__super__.constructor.call(this, element);
164       $('ol, ul', this.element).sortable({
165         items: "> li"
166       });
167     }
168
169     Uporzadkuj.prototype.check_question = function(question) {
170       var all, correct, pkt, pkts, positions, sorted, _ref;
171       positions = this.get_value_list(question, 'original', true);
172       sorted = positions.sort();
173       pkts = $('.question-piece', question);
174       correct = 0;
175       all = 0;
176       for (pkt = 0, _ref = pkts.length; 0 <= _ref ? pkt < _ref : pkt > _ref; 0 <= _ref ? pkt++ : pkt--) {
177         all += 1;
178         if (pkts.eq(pkt).data('pos') === sorted[pkt]) {
179           correct += 1;
180           this.piece_correct(pkts.eq(pkt));
181         } else {
182           this.piece_incorrect(pkts.eq(pkt));
183         }
184       }
185       return [correct, all];
186     };
187
188     return Uporzadkuj;
189
190   })(Excercise);
191
192   Luki = (function(_super) {
193
194     __extends(Luki, _super);
195
196     function Luki(element) {
197       Luki.__super__.constructor.call(this, element);
198     }
199
200     Luki.prototype.check = function() {
201       var all, correct,
202         _this = this;
203       all = 0;
204       correct = 0;
205       $(".question-piece", this.element).each(function(i, qpiece) {
206         if ($(qpiece).data('solution') === $(qpiece).val()) {
207           _this.piece_correct(qpiece);
208           correct += 1;
209         } else {
210           _this.piece_incorrect(qpiece);
211         }
212         return all += 1;
213       });
214       return this.show_score([correct, all]);
215     };
216
217     return Luki;
218
219   })(Excercise);
220
221   Zastap = (function(_super) {
222
223     __extends(Zastap, _super);
224
225     function Zastap(element) {
226       var _this = this;
227       Zastap.__super__.constructor.call(this, element);
228       $(".paragraph", this.element).each(function(i, par) {
229         var spans;
230         _this.wrap_words($(par), $('<span class="zastap question-piece"/>'));
231         spans = $("> span", par).attr("contenteditable", "true");
232         return spans.click(function(ev) {
233           spans.filter(':not(:empty)').removeClass('editing');
234           return $(ev.target).addClass('editing');
235         });
236       });
237     }
238
239     Zastap.prototype.check = function() {
240       var all, correct,
241         _this = this;
242       all = 0;
243       correct = 0;
244       $(".question-piece", this.element).each(function(i, qpiece) {
245         var should_be_changed, txt;
246         txt = $(qpiece).data('original');
247         should_be_changed = false;
248         if (!(txt != null)) {
249           txt = $(qpiece).data('solution');
250           should_be_changed = true;
251         }
252         if (!(txt != null)) return;
253         if (should_be_changed) all += 1;
254         if (txt !== $(qpiece).text()) {
255           return _this.piece_incorrect(qpiece);
256         } else {
257           if (should_be_changed) {
258             _this.piece_correct(qpiece);
259             return correct += 1;
260           }
261         }
262       });
263       return this.show_score([correct, all]);
264     };
265
266     Zastap.prototype.wrap_words = function(element, wrapper) {
267       var chld, i, ignore, insertWrapped, j, len, space, wordb, _ref, _results;
268       ignore = /^[ \t.,:;()]+/;
269       insertWrapped = function(txt, elem) {
270         var nw;
271         nw = wrapper.clone();
272         return $(document.createTextNode(txt)).wrap(nw).parent().attr("data-original", txt).insertBefore(elem);
273       };
274       _results = [];
275       for (j = _ref = element.get(0).childNodes.length - 1; _ref <= 0 ? j <= 0 : j >= 0; _ref <= 0 ? j++ : j--) {
276         chld = element.get(0).childNodes[j];
277         if (chld.nodeType === document.TEXT_NODE) {
278           len = chld.textContent.length;
279           wordb = 0;
280           i = 0;
281           while (i < len) {
282             space = ignore.exec(chld.textContent.substr(i));
283             if (space != null) {
284               if (wordb < i) {
285                 insertWrapped(chld.textContent.substr(wordb, i - wordb), chld);
286               }
287               $(document.createTextNode(space[0])).insertBefore(chld);
288               i += space[0].length;
289               wordb = i;
290             } else {
291               i = i + 1;
292             }
293           }
294           if (wordb < len - 1) {
295             insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld);
296           }
297           _results.push($(chld).remove());
298         } else {
299           _results.push(void 0);
300         }
301       }
302       return _results;
303     };
304
305     return Zastap;
306
307   })(Excercise);
308
309   Przyporzadkuj = (function(_super) {
310
311     __extends(Przyporzadkuj, _super);
312
313     Przyporzadkuj.prototype.is_multiple = function() {
314       var qp, _i, _len, _ref;
315       _ref = $(".question-piece", this.element);
316       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
317         qp = _ref[_i];
318         if ($(qp).data('solution').split(/[ ,]+/).length > 1) return true;
319       }
320       return false;
321     };
322
323     function Przyporzadkuj(element) {
324       var _this = this;
325       Przyporzadkuj.__super__.constructor.call(this, element);
326       this.multiple = this.is_multiple();
327       $(".question", this.element).each(function(i, question) {
328         var draggable_opts, helper_opts;
329         draggable_opts = {
330           revert: 'invalid'
331         };
332         if (_this.multiple) {
333           helper_opts = {
334             helper: "clone"
335           };
336         } else {
337           helper_opts = {};
338         }
339         $(".draggable", question).draggable($.extend({}, draggable_opts, helper_opts));
340         $(".predicate .droppable", question).parent().droppable({
341           accept: function(draggable) {
342             var $draggable, $predicate, added, _i, _len, _ref;
343             $draggable = $(draggable);
344             if (!$draggable.is(".draggable")) {
345               console.log('not draggable?');
346               return false;
347             }
348             $predicate = $(this);
349             _ref = $predicate.find("li");
350             for (_i = 0, _len = _ref.length; _i < _len; _i++) {
351               added = _ref[_i];
352               if ($(added).text() === $draggable.text()) {
353                 console.log('already here:' + $draggable.text());
354                 return false;
355               }
356             }
357             return true;
358           },
359           drop: function(ev, ui) {
360             var added;
361             added = ui.draggable.clone();
362             added.attr('style', '');
363             $(ev.target).find(".droppable").append(added);
364             added.draggable(draggable_opts);
365             if (!_this.multiple || ui.draggable.closest(".predicate").length > 0) {
366               return ui.draggable.remove();
367             }
368           }
369         });
370         $(".predicate .droppable", question).sortable({
371           items: "> li"
372         });
373         return $(".subject", question).droppable({
374           accept: ".draggable",
375           drop: function(ev, ui) {
376             var added;
377             if ($(ui.draggable).closest(".subject").length > 0) return;
378             added = ui.draggable.clone();
379             added.attr('style', '');
380             if (!_this.multiple) {
381               $(ev.target).append(added);
382               added.draggable($.extend({}, draggable_opts, helper_opts));
383             }
384             return ui.draggable.remove();
385           }
386         });
387       });
388     }
389
390     Przyporzadkuj.prototype.check_question = function(question) {
391       var all, all_multiple, count, mandatory, optional, pn, pred, qp, v, _i, _j, _len, _len2, _ref, _ref2;
392       count = 0;
393       all = 0;
394       all_multiple = 0;
395       _ref = $(".predicate .question-piece", question);
396       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
397         qp = _ref[_i];
398         pred = $(qp).closest("[data-predicate]");
399         v = this.get_value_optional_list(qp, 'solution');
400         mandatory = v[0];
401         optional = v[1];
402         all_multiple += mandatory.length + optional.length;
403         pn = pred.data('predicate');
404         if (mandatory.indexOf(pn) >= 0 || optional.indexOf(pn) >= 0) {
405           count += 1;
406           this.piece_correct(qp);
407         } else {
408           this.piece_incorrect(qp);
409         }
410         all += 1;
411       }
412       if (this.multiple) {
413         _ref2 = $(".subject .question-piece", question);
414         for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) {
415           qp = _ref2[_j];
416           v = this.get_value_optional_list(qp, 'solution');
417           mandatory = v[0];
418           optional = v[1];
419           all_multiple += mandatory.length + optional.length;
420         }
421         return [count, all_multiple];
422       } else {
423         return [count, all];
424       }
425     };
426
427     return Przyporzadkuj;
428
429   })(Excercise);
430
431   PrawdaFalsz = (function(_super) {
432
433     __extends(PrawdaFalsz, _super);
434
435     function PrawdaFalsz(element) {
436       var qp, _i, _len, _ref;
437       PrawdaFalsz.__super__.constructor.call(this, element);
438       _ref = $(".question-piece", this.element);
439       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
440         qp = _ref[_i];
441         $(".true", qp).click(function(ev) {
442           ev.preventDefault();
443           $(this).closest(".question-piece").data("value", "true");
444           return $(this).addClass('chosen').siblings('a').removeClass('chosen');
445         });
446         $(".false", qp).click(function(ev) {
447           ev.preventDefault();
448           $(this).closest(".question-piece").data("value", "false");
449           return $(this).addClass('chosen').siblings('a').removeClass('chosen');
450         });
451       }
452     }
453
454     PrawdaFalsz.prototype.check_question = function() {
455       var all, good, qp, _i, _len, _ref;
456       all = 0;
457       good = 0;
458       _ref = $(".question-piece", this.element);
459       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
460         qp = _ref[_i];
461         if ($(qp).data("solution").toString() === $(qp).data("value")) {
462           good += 1;
463           this.piece_correct(qp);
464         } else {
465           this.piece_incorrect(qp);
466         }
467         all += 1;
468       }
469       return [good, all];
470     };
471
472     return PrawdaFalsz;
473
474   })(Excercise);
475
476   excercise = function(ele) {
477     var cls, es;
478     es = {
479       wybor: Wybor,
480       uporzadkuj: Uporzadkuj,
481       luki: Luki,
482       zastap: Zastap,
483       przyporzadkuj: Przyporzadkuj,
484       prawdafalsz: PrawdaFalsz
485     };
486     cls = es[$(ele).attr('data-type')];
487     return new cls(ele);
488   };
489
490   window.edumed = {
491     'EduModule': EduModule
492   };
493
494   $(document).ready(function() {
495     new EduModule($("#book-text"));
496     return $(".excercise").each(function(i, el) {
497       return excercise(this);
498     });
499   });
500
501 }).call(this);