Fix for Uporzadkuj.
[edumed.git] / catalogue / static / catalogue / js / edumed.js
1 // Generated by CoffeeScript 1.4.0
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(function(a, b) {
313         return a - b;
314       });
315       pkts = $('.question-piece', question);
316       correct = 0;
317       bad = 0;
318       all = 0;
319       for (pkt = _i = 0, _ref = pkts.length; 0 <= _ref ? _i < _ref : _i > _ref; pkt = 0 <= _ref ? ++_i : --_i) {
320         all += 1;
321         if (pkts.eq(pkt).data('pos') === sorted[pkt]) {
322           correct += 1;
323           this.piece_correct(pkts.eq(pkt));
324         } else {
325           bad += 1;
326           this.piece_incorrect(pkts.eq(pkt));
327         }
328       }
329       return [correct, bad, all];
330     };
331
332     Uporzadkuj.prototype.solve_question = function(question) {
333       var p, parent, pkts, _i, _len, _results;
334       pkts = $('.question-piece', question);
335       pkts.sort(function(a, b) {
336         return $(a).data('pos') - $(b).data('pos');
337       });
338       parent = pkts.eq(0).parent();
339       _results = [];
340       for (_i = 0, _len = pkts.length; _i < _len; _i++) {
341         p = pkts[_i];
342         _results.push(parent.append(p));
343       }
344       return _results;
345     };
346
347     return Uporzadkuj;
348
349   })(Exercise);
350
351   Luki = (function(_super) {
352
353     __extends(Luki, _super);
354
355     function Luki(element) {
356       Luki.__super__.constructor.call(this, element);
357       this.dragging(false, false);
358     }
359
360     Luki.prototype.check = function() {
361       var all, bad, correct,
362         _this = this;
363       all = $(".placeholder", this.element).length;
364       correct = 0;
365       bad = 0;
366       $(".placeholder + .question-piece", this.element).each(function(i, qpiece) {
367         var $placeholder;
368         $placeholder = $(qpiece).prev(".placeholder");
369         if ($placeholder.data('solution') === $(qpiece).data('no')) {
370           _this.piece_correct(qpiece);
371           return correct += 1;
372         } else {
373           bad += 1;
374           return _this.piece_incorrect(qpiece);
375         }
376       });
377       return this.show_score([correct, bad, all]);
378     };
379
380     Luki.prototype.solve_question = function(question) {
381       var _this = this;
382       return $(".placeholder", question).each(function(i, placeholder) {
383         var $qp;
384         $qp = $(".question-piece[data-no=" + $(placeholder).data('solution') + "]", question);
385         return _this.draggable_move($qp, $(placeholder), false);
386       });
387     };
388
389     return Luki;
390
391   })(Exercise);
392
393   Zastap = (function(_super) {
394
395     __extends(Zastap, _super);
396
397     function Zastap(element) {
398       var _this = this;
399       Zastap.__super__.constructor.call(this, element);
400       $(".paragraph", this.element).each(function(i, par) {
401         return _this.wrap_words($(par), $('<span class="placeholder zastap"/>'));
402       });
403       this.dragging(false, false);
404     }
405
406     Zastap.prototype.check = function() {
407       var all, bad, correct,
408         _this = this;
409       all = 0;
410       correct = 0;
411       bad = 0;
412       $(".paragraph", this.element).each(function(i, par) {
413         return $(".placeholder", par).each(function(j, qpiece) {
414           var $dragged, $qp;
415           $qp = $(qpiece);
416           $dragged = $qp.next(".draggable");
417           if ($qp.data("solution")) {
418             if ($dragged && $qp.data("solution") === $dragged.data("no")) {
419               _this.piece_correct($dragged);
420               correct += 1;
421             }
422             return all += 1;
423           }
424         });
425       });
426       return this.show_score([correct, bad, all]);
427     };
428
429     Zastap.prototype.show_solutions = function() {
430       var _this = this;
431       this.reset();
432       return $(".paragraph", this.element).each(function(i, par) {
433         return $(".placeholder[data-solution]", par).each(function(j, qpiece) {
434           var $dr, $qp;
435           $qp = $(qpiece);
436           $dr = $(".draggable[data-no=" + $qp.data('solution') + "]", _this.element);
437           return _this.draggable_move($dr, $qp, false);
438         });
439       });
440     };
441
442     Zastap.prototype.wrap_words = function(element, wrapper) {
443       var chld, i, ignore, insertWrapped, j, len, space, wordb, _i, _ref, _results;
444       ignore = /^[ \t.,:;()]+/;
445       insertWrapped = function(txt, elem) {
446         var nw;
447         nw = wrapper.clone();
448         return $(document.createTextNode(txt)).wrap(nw).parent().attr("data-original", txt).insertBefore(elem);
449       };
450       _results = [];
451       for (j = _i = _ref = element.get(0).childNodes.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; j = _ref <= 0 ? ++_i : --_i) {
452         chld = element.get(0).childNodes[j];
453         if (chld.nodeType === document.TEXT_NODE) {
454           len = chld.textContent.length;
455           wordb = 0;
456           i = 0;
457           while (i < len) {
458             space = ignore.exec(chld.textContent.substr(i));
459             if (space != null) {
460               if (wordb < i) {
461                 insertWrapped(chld.textContent.substr(wordb, i - wordb), chld);
462               }
463               $(document.createTextNode(space[0])).insertBefore(chld);
464               i += space[0].length;
465               wordb = i;
466             } else {
467               i = i + 1;
468             }
469           }
470           if (wordb < len - 1) {
471             insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld);
472           }
473           _results.push($(chld).remove());
474         } else {
475           _results.push(void 0);
476         }
477       }
478       return _results;
479     };
480
481     return Zastap;
482
483   })(Exercise);
484
485   Przyporzadkuj = (function(_super) {
486
487     __extends(Przyporzadkuj, _super);
488
489     Przyporzadkuj.prototype.is_multiple = function() {
490       var qp, _i, _len, _ref;
491       _ref = $(".question-piece", this.element);
492       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
493         qp = _ref[_i];
494         if ($(qp).attr('data-solution').split(/[ ,]+/).length > 1) {
495           return true;
496         }
497       }
498       return false;
499     };
500
501     function Przyporzadkuj(element) {
502       Przyporzadkuj.__super__.constructor.call(this, element);
503       this.multiple = this.is_multiple();
504       this.dragging(this.multiple, true);
505     }
506
507     Przyporzadkuj.prototype.draggable_equal = function(d1, d2) {
508       return d1.data("no") === d2.data("no");
509     };
510
511     Przyporzadkuj.prototype.check_question = function(question) {
512       var all, bad_count, count, mandatory, minimum, optional, pn, pred, qp, self, v, _i, _j, _len, _len1, _ref, _ref1;
513       minimum = $(question).data("minimum");
514       count = 0;
515       bad_count = 0;
516       all = 0;
517       if (!minimum) {
518         self = this;
519         $(".subject .question-piece", question).each(function(i, el) {
520           var mandatory, v;
521           v = self.get_value_optional_list(el, 'solution');
522           mandatory = v[0];
523           return all += mandatory.length;
524         });
525       }
526       _ref = $(".predicate [data-predicate]", question);
527       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
528         pred = _ref[_i];
529         pn = $(pred).attr('data-predicate');
530         _ref1 = $(".question-piece", pred);
531         for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
532           qp = _ref1[_j];
533           v = this.get_value_optional_list(qp, 'solution');
534           mandatory = v[0];
535           optional = v[1];
536           if (mandatory.indexOf(pn) >= 0 || (minimum && optional.indexOf(pn) >= 0)) {
537             count += 1;
538             this.piece_correct(qp);
539           } else {
540             bad_count += 1;
541             this.piece_incorrect(qp);
542           }
543         }
544       }
545       return [count, bad_count, all];
546     };
547
548     Przyporzadkuj.prototype.solve_question = function(question) {
549       var $ph, $pr, draggables, m, mandatory, minimum, optional, qp, v, _i, _len, _ref, _results;
550       minimum = $(question).data("min");
551       _ref = $(".subject .question-piece", question);
552       _results = [];
553       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
554         qp = _ref[_i];
555         v = this.get_value_optional_list(qp, 'solution');
556         mandatory = v[0];
557         optional = v[1];
558         if (minimum) {
559           draggables = mandatory.count(optional).slice(0, minimum);
560         } else {
561           draggables = mandatory;
562         }
563         _results.push((function() {
564           var _j, _len1, _results1;
565           _results1 = [];
566           for (_j = 0, _len1 = draggables.length; _j < _len1; _j++) {
567             m = draggables[_j];
568             $pr = $(".predicate [data-predicate=" + m + "]", question);
569             $ph = $pr.find(".placeholder:visible");
570             _results1.push(this.draggable_move($(qp), $ph.eq(0), this.multiple));
571           }
572           return _results1;
573         }).call(this));
574       }
575       return _results;
576     };
577
578     return Przyporzadkuj;
579
580   })(Exercise);
581
582   PrawdaFalsz = (function(_super) {
583
584     __extends(PrawdaFalsz, _super);
585
586     function PrawdaFalsz(element) {
587       var qp, _i, _len, _ref,
588         _this = this;
589       PrawdaFalsz.__super__.constructor.call(this, element);
590       _ref = $(".question-piece", this.element);
591       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
592         qp = _ref[_i];
593         $(".true", qp).click(function(ev) {
594           ev.preventDefault();
595           _this.retry();
596           $(ev.target).closest(".question-piece").data("value", "true");
597           return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
598         });
599         $(".false", qp).click(function(ev) {
600           ev.preventDefault();
601           _this.retry();
602           $(ev.target).closest(".question-piece").data("value", "false");
603           return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen');
604         });
605       }
606     }
607
608     PrawdaFalsz.prototype.check_question = function() {
609       var all, bad, good, qp, _i, _len, _ref;
610       all = 0;
611       good = 0;
612       bad = 0;
613       _ref = $(".question-piece", this.element);
614       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
615         qp = _ref[_i];
616         if ($(qp).data("solution").toString() === $(qp).data("value")) {
617           good += 1;
618           this.piece_correct(qp);
619         } else {
620           bad += 1;
621           this.piece_incorrect(qp);
622         }
623         all += 1;
624       }
625       return [good, bad, all];
626     };
627
628     PrawdaFalsz.prototype.show_solutions = function() {
629       var qp, _i, _len, _ref, _results;
630       this.reset();
631       _ref = $(".question-piece", this.element);
632       _results = [];
633       for (_i = 0, _len = _ref.length; _i < _len; _i++) {
634         qp = _ref[_i];
635         if ($(qp).data('solution') === true) {
636           _results.push($(".true", qp).click());
637         } else {
638           _results.push($(".false", qp).click());
639         }
640       }
641       return _results;
642     };
643
644     return PrawdaFalsz;
645
646   })(Exercise);
647
648   exercise = function(ele) {
649     var cls, es;
650     es = {
651       wybor: Wybor,
652       uporzadkuj: Uporzadkuj,
653       luki: Luki,
654       zastap: Zastap,
655       przyporzadkuj: Przyporzadkuj,
656       prawdafalsz: PrawdaFalsz
657     };
658     cls = es[$(ele).attr('data-type')];
659     return new cls(ele);
660   };
661
662   window.edumed = {
663     'EduModule': EduModule
664   };
665
666   $(document).ready(function() {
667     new EduModule($("#book-text"));
668     return $(".exercise").each(function(i, el) {
669       return exercise(this);
670     });
671   });
672
673 }).call(this);