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