maxscore style; fix exercise: Luki
[edumed.git] / catalogue / static / catalogue / js / edumed.js
1 // Generated by CoffeeScript 1.3.3
2 (function() {
3   var $, Binding, EduModule, Exercise, Luki, PrawdaFalsz, Przyporzadkuj, Uporzadkuj, Wybor, Zastap, exercise,
4     __hasProp = {}.hasOwnProperty,
5     __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; };
6
7   $ = jQuery;
8
9   Binding = (function() {
10
11     function Binding(handler, element) {
12       this.handler = handler;
13       this.element = element;
14       $(this.element).data(this.handler, this);
15     }
16
17     return Binding;
18
19   })();
20
21   EduModule = (function(_super) {
22
23     __extends(EduModule, _super);
24
25     function EduModule(element) {
26       EduModule.__super__.constructor.call(this, 'edumodule', element);
27     }
28
29     return EduModule;
30
31   })(Binding);
32
33   Exercise = (function(_super) {
34
35     __extends(Exercise, _super);
36
37     function Exercise(element) {
38       var _this = this;
39       Exercise.__super__.constructor.call(this, 'exercise', element);
40       $(this.element).data("exercise-html", $(this.element).html());
41       $(".check", this.element).click(function(ev) {
42         _this.check();
43         $(".retry", _this.element).show();
44         return $(".check", _this.element).hide();
45       });
46       $(".retry", this.element).click(function(ev) {
47         return _this.retry();
48       });
49       $('.solutions', this.element).click(function() {
50         _this.show_solutions();
51         return $(".comment", _this.element).show();
52       });
53       $('.reset', this.element).click(function() {
54         return _this.reset();
55       });
56     }
57
58     Exercise.prototype.retry = function() {
59       $(".correct, .incorrect", this.element).removeClass("correct incorrect");
60       $(".check", this.element).show();
61       return $(".retry", this.element).hide();
62     };
63
64     Exercise.prototype.reset = function() {
65       $(this.element).html($(this.element).data('exercise-html'));
66       return exercise(this.element);
67     };
68
69     Exercise.prototype.piece_correct = function(qpiece) {
70       return $(qpiece).removeClass('incorrect').addClass('correct');
71     };
72
73     Exercise.prototype.piece_incorrect = function(qpiece) {
74       return $(qpiece).removeClass('correct').addClass('incorrect');
75     };
76
77     Exercise.prototype.check = function() {
78       var score, scores,
79         _this = this;
80       scores = [];
81       $(".question", this.element).each(function(i, question) {
82         return scores.push(_this.check_question(question));
83       });
84       score = [0, 0];
85       $.each(scores, function(i, s) {
86         score[0] += s[0];
87         return score[1] += s[1];
88       });
89       return this.show_score(score);
90     };
91
92     Exercise.prototype.show_solutions = function() {
93       var _this = this;
94       this.reset();
95       return $(".question", this.element).each(function(i, question) {
96         return _this.solve_question(question);
97       });
98     };
99
100     Exercise.prototype.get_value_list = function(elem, data_key, numbers) {
101       var vl;
102       vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim);
103       if (numbers) {
104         vl = vl.map(function(x) {
105           return parseInt(x);
106         });
107       }
108       return vl;
109     };
110
111     Exercise.prototype.get_value_optional_list = function(elem, data_key) {
112       var mandat, opt, v, vals, _i, _len;
113       vals = this.get_value_list(elem, data_key);
114       mandat = [];
115       opt = [];
116       for (_i = 0, _len = vals.length; _i < _len; _i++) {
117         v = vals[_i];
118         if (v.slice(-1) === "?") {
119           opt.push(v.slice(0, -1));
120         } else {
121           mandat.push(v);
122         }
123       }
124       return [mandat, opt];
125     };
126
127     Exercise.prototype.show_score = function(score) {
128       var $msg;
129       $msg = $(".message", this.element);
130       $msg.text("Wynik: " + score[0] + " / " + score[1]);
131       if (score[0] === score[1]) {
132         return $msg.addClass("maxscore");
133       } else {
134         return $msg.removeClass("maxscore");
135       }
136     };
137
138     Exercise.prototype.draggable_equal = function($draggable1, $draggable2) {
139       return false;
140     };
141
142     Exercise.prototype.draggable_accept = function($draggable, $droppable) {
143       var d, dropped, _i, _len;
144       dropped = $droppable.closest("ul, ol").find(".draggable");
145       for (_i = 0, _len = dropped.length; _i < _len; _i++) {
146         d = dropped[_i];
147         if (this.draggable_equal($draggable, $(d))) {
148           return false;
149         }
150       }
151       return true;
152     };
153
154     Exercise.prototype.draggable_move = function($draggable, $placeholder, ismultiple) {
155       var $added,
156         _this = this;
157       $added = $draggable.clone();
158       $added.data("original", $draggable.get(0));
159       if (!ismultiple) {
160         $draggable.addClass('disabled').draggable('disable');
161       }
162       $placeholder.after($added);
163       if (!$placeholder.hasClass('multiple')) {
164         $placeholder.hide();
165       }
166       if ($added.is(".add-li")) {
167         $added.wrap("<li/>");
168       }
169       $added.append('<span class="remove">x</span><div class="clr"></div>');
170       return $('.remove', $added).click(function(ev) {
171         _this.retry();
172         if (!ismultiple) {
173           $($added.data('original')).removeClass('disabled').draggable('enable');
174         }
175         if ($added.is(".add-li")) {
176           $added = $added.closest('li');
177         }
178         $added.prev(".placeholder:not(.multiple)").show();
179         return $added.remove();
180       });
181     };
182
183     Exercise.prototype.dragging = function(ismultiple, issortable) {
184       var _this = this;
185       return $(".question", this.element).each(function(i, question) {
186         var draggable_opts, self;
187         draggable_opts = {
188           revert: 'invalid',
189           helper: 'clone',
190           start: _this.retry
191         };
192         $(".draggable", question).draggable(draggable_opts);
193         self = _this;
194         return $(".placeholder", question).droppable({
195           accept: function(draggable) {
196             var $draggable, is_accepted;
197             $draggable = $(draggable);
198             is_accepted = true;
199             if (!$draggable.is(".draggable")) {
200               is_accepted = false;
201             }
202             if (is_accepted) {
203               is_accepted = self.draggable_accept($draggable, $(this));
204             }
205             if (is_accepted) {
206               $(this).addClass('accepting');
207             } else {
208               $(this).removeClass('accepting');
209             }
210             return is_accepted;
211           },
212           drop: function(ev, ui) {
213             $(ev.target).removeClass('accepting dragover');
214             return _this.draggable_move($(ui.draggable), $(ev.target), ismultiple);
215           },
216           over: function(ev, ui) {
217             return $(ev.target).addClass('dragover');
218           },
219           out: function(ev, ui) {
220             return $(ev.target).removeClass('dragover');
221           }
222         });
223       });
224     };
225
226     return Exercise;
227
228   })(Binding);
229
230   Wybor = (function(_super) {
231
232     __extends(Wybor, _super);
233
234     function Wybor(element) {
235       Wybor.__super__.constructor.call(this, element);
236       $(".question-piece input", element).change(this.retry);
237     }
238
239     Wybor.prototype.check_question = function(question) {
240       var all, good, solution,
241         _this = this;
242       all = 0;
243       good = 0;
244       solution = this.get_value_list(question, 'solution');
245       $(".question-piece", question).each(function(i, qpiece) {
246         var is_checked, piece_name, piece_no, should_be_checked;
247         piece_no = $(qpiece).attr('data-no');
248         piece_name = $(qpiece).attr('data-name');
249         if (piece_name) {
250           should_be_checked = solution.indexOf(piece_name) >= 0;
251         } else {
252           should_be_checked = solution.indexOf(piece_no) >= 0;
253         }
254         is_checked = $("input", qpiece).is(":checked");
255         if (should_be_checked) {
256           all += 1;
257         }
258         if (is_checked) {
259           if (should_be_checked) {
260             good += 1;
261             return _this.piece_correct(qpiece);
262           } else {
263             return _this.piece_incorrect(qpiece);
264           }
265         } else {
266           return $(qpiece).removeClass("correct,incorrect");
267         }
268       });
269       return [good, all];
270     };
271
272     Wybor.prototype.solve_question = function(question) {
273       var solution,
274         _this = this;
275       solution = this.get_value_list(question, 'solution');
276       return $(".question-piece", question).each(function(i, qpiece) {
277         var piece_name, piece_no, should_be_checked;
278         piece_no = $(qpiece).attr('data-no');
279         piece_name = $(qpiece).attr('data-name');
280         if (piece_name) {
281           should_be_checked = solution.indexOf(piece_name) >= 0;
282         } else {
283           should_be_checked = solution.indexOf(piece_no) >= 0;
284         }
285         console.log("check " + $("input[type=checkbox]", qpiece).attr("id") + " -> " + should_be_checked);
286         return $("input[type=checkbox],input[type=radio]", qpiece).prop('checked', should_be_checked);
287       });
288     };
289
290     return Wybor;
291
292   })(Exercise);
293
294   Uporzadkuj = (function(_super) {
295
296     __extends(Uporzadkuj, _super);
297
298     function Uporzadkuj(element) {
299       Uporzadkuj.__super__.constructor.call(this, element);
300       $('ol, ul', this.element).sortable({
301         items: "> li",
302         start: this.retry
303       });
304     }
305
306     Uporzadkuj.prototype.check_question = function(question) {
307       var all, correct, pkt, pkts, positions, sorted, _i, _ref;
308       positions = this.get_value_list(question, 'original', true);
309       sorted = positions.sort();
310       pkts = $('.question-piece', question);
311       correct = 0;
312       all = 0;
313       for (pkt = _i = 0, _ref = pkts.length; 0 <= _ref ? _i < _ref : _i > _ref; pkt = 0 <= _ref ? ++_i : --_i) {
314         all += 1;
315         if (pkts.eq(pkt).data('pos') === sorted[pkt]) {
316           correct += 1;
317           this.piece_correct(pkts.eq(pkt));
318         } else {
319           this.piece_incorrect(pkts.eq(pkt));
320         }
321       }
322       return [correct, all];
323     };
324
325     Uporzadkuj.prototype.solve_question = function(question) {
326       var p, parent, pkts, positions, sorted, _i, _len, _results;
327       positions = this.get_value_list(question, 'original', true);
328       sorted = positions.sort();
329       pkts = $('.question-piece', question);
330       pkts.sort(function(a, b) {
331         var q, w;
332         q = $(a).data('pos');
333         w = $(b).data('pos');
334         if (q < w) {
335           return 1;
336         }
337         if (q > w) {
338           return -1;
339         }
340         return 0;
341       });
342       parent = pkts.eq(0).parent();
343       _results = [];
344       for (_i = 0, _len = pkts.length; _i < _len; _i++) {
345         p = pkts[_i];
346         _results.push(parent.prepend(p));
347       }
348       return _results;
349     };
350
351     return Uporzadkuj;
352
353   })(Exercise);
354
355   Luki = (function(_super) {
356
357     __extends(Luki, _super);
358
359     function Luki(element) {
360       Luki.__super__.constructor.call(this, element);
361       this.dragging(false, false);
362     }
363
364     Luki.prototype.check = function() {
365       var all, correct,
366         _this = this;
367       all = $(".placeholder", this.element).length;
368       correct = 0;
369       $(".placeholder + .question-piece", this.element).each(function(i, qpiece) {
370         var $placeholder;
371         $placeholder = $(qpiece).prev(".placeholder");
372         if ($placeholder.data('solution') === $(qpiece).data('no')) {
373           _this.piece_correct(qpiece);
374           return correct += 1;
375         } else {
376           return _this.piece_incorrect(qpiece);
377         }
378       });
379       return this.show_score([correct, all]);
380     };
381
382     Luki.prototype.solve_question = function(question) {
383       var _this = this;
384       return $(".placeholder", question).each(function(i, placeholder) {
385         var $qp;
386         $qp = $(".question-piece[data-no=" + $(placeholder).data('solution') + "]", question);
387         return _this.draggable_move($qp, $(placeholder), false);
388       });
389     };
390
391     return Luki;
392
393   })(Exercise);
394
395   Zastap = (function(_super) {
396
397     __extends(Zastap, _super);
398
399     function Zastap(element) {
400       var _this = this;
401       Zastap.__super__.constructor.call(this, element);
402       $(".paragraph", this.element).each(function(i, par) {
403         return _this.wrap_words($(par), $('<span class="placeholder zastap"/>'));
404       });
405       this.dragging(false, false);
406     }
407
408     Zastap.prototype.check = function() {
409       var all, correct,
410         _this = this;
411       all = 0;
412       correct = 0;
413       $(".paragraph", this.element).each(function(i, par) {
414         return $(".placeholder", par).each(function(j, qpiece) {
415           var $dragged, $qp;
416           $qp = $(qpiece);
417           $dragged = $qp.next(".draggable");
418           if ($qp.data("solution")) {
419             if ($dragged && $qp.data("solution") === $dragged.data("no")) {
420               _this.piece_correct($dragged);
421               correct += 1;
422             }
423             return all += 1;
424           }
425         });
426       });
427       return this.show_score([correct, all]);
428     };
429
430     Zastap.prototype.show_solutions = function() {
431       var _this = this;
432       this.reset();
433       return $(".paragraph", this.element).each(function(i, par) {
434         return $(".placeholder[data-solution]", par).each(function(j, qpiece) {
435           var $dr, $qp;
436           $qp = $(qpiece);
437           $dr = $(".draggable[data-no=" + $qp.data('solution') + "]", _this.element);
438           return _this.draggable_move($dr, $qp, false);
439         });
440       });
441     };
442
443     Zastap.prototype.wrap_words = function(element, wrapper) {
444       var chld, i, ignore, insertWrapped, j, len, space, wordb, _i, _ref, _results;
445       ignore = /^[ \t.,:;()]+/;
446       insertWrapped = function(txt, elem) {
447         var nw;
448         nw = wrapper.clone();
449         return $(document.createTextNode(txt)).wrap(nw).parent().attr("data-original", txt).insertBefore(elem);
450       };
451       _results = [];
452       for (j = _i = _ref = element.get(0).childNodes.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; j = _ref <= 0 ? ++_i : --_i) {
453         chld = element.get(0).childNodes[j];
454         if (chld.nodeType === document.TEXT_NODE) {
455           len = chld.textContent.length;
456           wordb = 0;
457           i = 0;
458           while (i < len) {
459             space = ignore.exec(chld.textContent.substr(i));
460             if (space != null) {
461               if (wordb < i) {
462                 insertWrapped(chld.textContent.substr(wordb, i - wordb), chld);
463               }
464               $(document.createTextNode(space[0])).insertBefore(chld);
465               i += space[0].length;
466               wordb = i;
467             } else {
468               i = i + 1;
469             }
470           }
471           if (wordb < len - 1) {
472             insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld);
473           }
474           _results.push($(chld).remove());
475         } else {
476           _results.push(void 0);
477         }
478       }
479       return _results;
480     };
481
482     return Zastap;
483
484   })(Exercise);
485
486   Przyporzadkuj = (function(_super) {
487
488     __extends(Przyporzadkuj, _super);
489
490     Przyporzadkuj.prototype.is_multiple = function() {
491       var qp, _i, _len, _ref;
492       _ref = $(".question-piece", this.element);
493       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
494         qp = _ref[_i];
495         if ($(qp).attr('data-solution').split(/[ ,]+/).length > 1) {
496           return true;
497         }
498       }
499       return false;
500     };
501
502     function Przyporzadkuj(element) {
503       Przyporzadkuj.__super__.constructor.call(this, element);
504       this.multiple = this.is_multiple();
505       this.dragging(this.multiple, true);
506     }
507
508     Przyporzadkuj.prototype.draggable_equal = function(d1, d2) {
509       return d1.data("no") === d2.data("no");
510     };
511
512     Przyporzadkuj.prototype.check_question = function(question) {
513       var all, count, mandatory, minimum, optional, pn, pred, qp, v, _i, _j, _len, _len1, _ref, _ref1;
514       minimum = $(question).data("minimum");
515       count = 0;
516       all = 0;
517       if (!minimum) {
518         all = $(".subject .question-piece", question).length;
519       }
520       _ref = $(".predicate [data-predicate]", question);
521       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
522         pred = _ref[_i];
523         pn = $(pred).attr('data-predicate');
524         if (minimum != null) {
525           all += minimum;
526         }
527         _ref1 = $(".question-piece", pred);
528         for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
529           qp = _ref1[_j];
530           v = this.get_value_optional_list(qp, 'solution');
531           mandatory = v[0];
532           optional = v[1];
533           if (mandatory.indexOf(pn) >= 0 || (minimum && optional.indexOf(pn) >= 0)) {
534             count += 1;
535             this.piece_correct(qp);
536           } else {
537             this.piece_incorrect(qp);
538           }
539         }
540       }
541       return [count, all];
542     };
543
544     Przyporzadkuj.prototype.solve_question = function(question) {
545       var $ph, $pr, draggables, m, mandatory, minimum, optional, qp, v, _i, _len, _ref, _results;
546       minimum = $(question).data("min");
547       _ref = $(".subject .question-piece", question);
548       _results = [];
549       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
550         qp = _ref[_i];
551         v = this.get_value_optional_list(qp, 'solution');
552         mandatory = v[0];
553         optional = v[1];
554         if (minimum) {
555           draggables = mandatory.count(optional).slice(0, minimum);
556         } else {
557           draggables = mandatory;
558         }
559         _results.push((function() {
560           var _j, _len1, _results1;
561           _results1 = [];
562           for (_j = 0, _len1 = draggables.length; _j < _len1; _j++) {
563             m = draggables[_j];
564             $pr = $(".predicate [data-predicate=" + m + "]", question);
565             $ph = $pr.find(".placeholder:visible");
566             _results1.push(this.draggable_move($(qp), $ph.eq(0), this.multiple));
567           }
568           return _results1;
569         }).call(this));
570       }
571       return _results;
572     };
573
574     return Przyporzadkuj;
575
576   })(Exercise);
577
578   PrawdaFalsz = (function(_super) {
579
580     __extends(PrawdaFalsz, _super);
581
582     function PrawdaFalsz(element) {
583       var qp, _i, _len, _ref,
584         _this = this;
585       PrawdaFalsz.__super__.constructor.call(this, element);
586       _ref = $(".question-piece", this.element);
587       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
588         qp = _ref[_i];
589         $(".true", qp).click(function(ev) {
590           ev.preventDefault();
591           _this.retry();
592           $(ev.target).closest(".question-piece").data("value", "true");
593           return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
594         });
595         $(".false", qp).click(function(ev) {
596           ev.preventDefault();
597           _this.retry();
598           $(ev.target).closest(".question-piece").data("value", "false");
599           return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
600         });
601       }
602     }
603
604     PrawdaFalsz.prototype.check_question = function() {
605       var all, good, qp, _i, _len, _ref;
606       all = 0;
607       good = 0;
608       _ref = $(".question-piece", this.element);
609       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
610         qp = _ref[_i];
611         if ($(qp).data("solution").toString() === $(qp).data("value")) {
612           good += 1;
613           this.piece_correct(qp);
614         } else {
615           this.piece_incorrect(qp);
616         }
617         all += 1;
618       }
619       return [good, all];
620     };
621
622     PrawdaFalsz.prototype.show_solutions = function() {
623       var qp, _i, _len, _ref, _results;
624       this.reset();
625       _ref = $(".question-piece", this.element);
626       _results = [];
627       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
628         qp = _ref[_i];
629         if ($(qp).data('solution') === true) {
630           _results.push($(".true", qp).click());
631         } else {
632           _results.push($(".false", qp).click());
633         }
634       }
635       return _results;
636     };
637
638     return PrawdaFalsz;
639
640   })(Exercise);
641
642   exercise = function(ele) {
643     var cls, es;
644     es = {
645       wybor: Wybor,
646       uporzadkuj: Uporzadkuj,
647       luki: Luki,
648       zastap: Zastap,
649       przyporzadkuj: Przyporzadkuj,
650       prawdafalsz: PrawdaFalsz
651     };
652     cls = es[$(ele).attr('data-type')];
653     return new cls(ele);
654   };
655
656   window.edumed = {
657     'EduModule': EduModule
658   };
659
660   $(document).ready(function() {
661     new EduModule($("#book-text"));
662     return $(".exercise").each(function(i, el) {
663       return exercise(this);
664     });
665   });
666
667 }).call(this);