From 8ae014fa8f6e9e9555f28dc9e09ce0c81e58bc85 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Aleksander=20=C5=81ukasz?= Date: Wed, 30 Oct 2013 12:27:57 +0100 Subject: [PATCH] Introducing edumed.coffee from redakcja repository Source: http://git.nowoczesnapolska.org.pl/?p=redakcja.git;a=blob;f=redakcja/static/edumed/js/edumed.coffee;h=fb8ea87246c0c14b6dce9749c1ee32e0e5a81303;hb=refs/heads/edumed --- edumed/settings.d/50-static.py | 6 + wtem/static/wtem/edumed.coffee | 519 +++++++++++++++++++++++++ wtem/static/wtem/edumed.js | 673 +++++++++++++++++++++++++++++++++ wtem/templates/wtem/main.html | 5 + 4 files changed, 1203 insertions(+) create mode 100644 wtem/static/wtem/edumed.coffee create mode 100644 wtem/static/wtem/edumed.js diff --git a/edumed/settings.d/50-static.py b/edumed/settings.d/50-static.py index 43dbb7c..35aabe2 100644 --- a/edumed/settings.d/50-static.py +++ b/edumed/settings.d/50-static.py @@ -48,6 +48,12 @@ PIPELINE_JS = { ), 'output_filename': 'compressed/base.js', }, + 'wtem': { + 'source_filenames': ( + 'wtem/edumed.js', + ), + 'output_filename': 'compressed/wtem.js' + }, } PIPELINE_COMPILERS = ( diff --git a/wtem/static/wtem/edumed.coffee b/wtem/static/wtem/edumed.coffee new file mode 100644 index 0000000..fb8ea87 --- /dev/null +++ b/wtem/static/wtem/edumed.coffee @@ -0,0 +1,519 @@ + +$ = jQuery + +class Binding + constructor: (@handler, @element) -> + $(@element).data(@handler, this) + + +class EduModule extends Binding + constructor: (element) -> + super 'edumodule', element + + # $("[name=teacher-toggle]").change (ev) => + # if $(ev.target).is(":checked") + # $(".teacher", @element).addClass "show" + # else + # $(".teacher", @element).removeClass "show" + + +class Exercise extends Binding + constructor: (element) -> + super 'exercise', element + # just save the html to reset the exercise + $(@element).data("exercise-html", $(@element).html()) + + $(".check", @element).click (ev) => + @check() + $(".retry", @element).show() + $(".check", @element).hide() + $(".retry", @element).click (ev) => + @retry() + $('.solutions', @element).click => + @show_solutions() + $(".comment", @element).show() + $('.reset', @element).click => + @reset() + + retry: -> + $(".correct, .incorrect", @element).removeClass("correct incorrect") + $(".check", @element).show() + $(".retry", @element).hide() + + reset: -> + $(@element).html($(@element).data('exercise-html')) + exercise @element + + piece_correct: (qpiece) -> + $(qpiece).removeClass('incorrect').addClass('correct') + + piece_incorrect: (qpiece) -> + $(qpiece).removeClass('correct').addClass('incorrect') + + check: -> + scores = [] + $(".question", @element).each (i, question) => + scores.push(@check_question question) + + score = [0, 0, 0] + $.each scores, (i, s) -> + score[0] += s[0] + score[1] += s[1] + score[2] += s[2] + @show_score(score) + + show_solutions: -> + @reset() + $(".question", @element).each (i, question) => + @solve_question question + + # Parses a list of values, separated by space or comma. + # The list is read from data attribute of elem using data_key + # Returns a list with elements + # eg.: things_i_need: "house bike tv playstation" + # yields ["house", "bike", "tv", "playstation"] + # If optional numbers argument is true, returns list of numbers + # instead of strings + get_value_list: (elem, data_key, numbers) -> + vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim) #.map((x) -> parseInt(x)) + if numbers + vl = vl.map((x) -> parseInt(x)) + return vl + + # Parses a list of values, separated by space or comma. + # The list is read from data attribute of elem using data_key + # Returns a 2-element list with mandatory and optional + # items. optional items are marked with a question mark on the end + # eg.: things_i_need: "house bike tv? playstation?" + # yields [[ "house", "bike"], ["tv", "playstation"]] + get_value_optional_list: (elem, data_key) -> + vals = @get_value_list(elem, data_key) + mandat = [] + opt = [] + for v in vals + if v.slice(-1) == "?" + opt.push v.slice(0, -1) + else + mandat.push v + return [mandat, opt] + + show_score: (score) -> + $msg = $(".message", @element) + $msg.text("Wynik: #{score[0]} / #{score[2]}") + if score[0] >= score[2] and score[1] == 0 + $msg.addClass("maxscore") + else + $msg.removeClass("maxscore") + + + draggable_equal: ($draggable1, $draggable2) -> + return false + + draggable_accept: ($draggable, $droppable) -> + dropped = $droppable.closest("ul, ol").find(".draggable") + for d in dropped + if @draggable_equal $draggable, $(d) + return false + return true + + draggable_move: ($draggable, $placeholder, ismultiple) -> + $added = $draggable.clone() + $added.data("original", $draggable.get(0)) + if not ismultiple + $draggable.addClass('disabled').draggable('disable') + + $placeholder.after($added) + if not $placeholder.hasClass('multiple') + $placeholder.hide() + if $added.is(".add-li") + $added.wrap("
  • ") + + $added.append('x
    ') + $('.remove', $added).click (ev) => + @retry() + if not ismultiple + $($added.data('original')).removeClass('disabled').draggable('enable') + + if $added.is(".add-li") + $added = $added.closest('li') + $added.prev(".placeholder:not(.multiple)").show() + $added.remove() + + +## XXX co z issortable? + dragging: (ismultiple, issortable) -> + $(".question", @element).each (i, question) => + draggable_opts = + revert: 'invalid' + helper: 'clone' + start: @retry + + $(".draggable", question).draggable(draggable_opts) + self = this + $(".placeholder", question).droppable + accept: (draggable) -> + $draggable = $(draggable) + is_accepted = true + + if not $draggable.is(".draggable") + is_accepted = false + + if is_accepted + is_accepted= self.draggable_accept $draggable, $(this) + + if is_accepted + $(this).addClass 'accepting' + else + $(this).removeClass 'accepting' + return is_accepted + + drop: (ev, ui) => + $(ev.target).removeClass 'accepting dragover' + + @draggable_move $(ui.draggable), $(ev.target), ismultiple + + # $added = $(ui.draggable).clone() + # $added.data("original", ui.draggable) + # if not ismultiple + # $(ui.draggable).addClass('disabled').draggable('disable') + + # $(ev.target).after(added) + # if not $(ev.target).hasClass('multiple') + # $(ev.target).hide() + # $added.append('x') + # $('.remove', added).click (ev) => + # $added.prev(".placeholder:not(.multiple)").show() + # if not ismultiple + # $added.data('original').removeClass('disabled').draggable('enable') + # $(added).remove() + + over: (ev, ui) -> + $(ev.target).addClass 'dragover' + + + out: (ev, ui) -> + $(ev.target).removeClass 'dragover' + + + +class Wybor extends Exercise + constructor: (element) -> + super element + $(".question-piece input", element).change(@retry); + + + check_question: (question) -> + all = 0 + good = 0 + bad = 0 + solution = @get_value_list(question, 'solution') + $(".question-piece", question).each (i, qpiece) => + piece_no = $(qpiece).attr 'data-no' + piece_name = $(qpiece).attr 'data-name' + if piece_name + should_be_checked = solution.indexOf(piece_name) >= 0 + else + should_be_checked = solution.indexOf(piece_no) >= 0 + is_checked = $("input", qpiece).is(":checked") + + if should_be_checked + all += 1 + + if is_checked + if should_be_checked + good += 1 + @piece_correct qpiece + else + bad += 1 + @piece_incorrect qpiece + else + $(qpiece).removeClass("correct,incorrect") + + return [good, bad, all] + + solve_question: (question) -> + solution = @get_value_list(question, 'solution') + $(".question-piece", question).each (i, qpiece) => + piece_no = $(qpiece).attr 'data-no' + piece_name = $(qpiece).attr 'data-name' + if piece_name + should_be_checked = solution.indexOf(piece_name) >= 0 + else + should_be_checked = solution.indexOf(piece_no) >= 0 + console.log("check " + $("input[type=checkbox]", qpiece).attr("id") + " -> " + should_be_checked) + $("input[type=checkbox],input[type=radio]", qpiece).prop 'checked', should_be_checked + + + +class Uporzadkuj extends Exercise + constructor: (element) -> + super element + $('ol, ul', @element).sortable({ items: "> li", start: @retry }) + + check_question: (question) -> + positions = @get_value_list(question, 'original', true) + sorted = positions.sort() + pkts = $('.question-piece', question) + + correct = 0 + bad = 0 + all = 0 + + for pkt in [0...pkts.length] + all += 1 + if pkts.eq(pkt).data('pos') == sorted[pkt] + correct += 1 + @piece_correct pkts.eq(pkt) + else + bad += 1 + @piece_incorrect pkts.eq(pkt) + return [correct, bad, all] + + solve_question: (question) -> + positions = @get_value_list(question, 'original', true) + sorted = positions.sort() + pkts = $('.question-piece', question) + pkts.sort (a, b) -> + q = $(a).data('pos') + w = $(b).data('pos') + return 1 if q < w + return -1 if q > w + return 0 + + parent = pkts.eq(0).parent() + for p in pkts + parent.prepend(p) + + +# XXX propozycje="1/0" +class Luki extends Exercise + constructor: (element) -> + super element + @dragging false, false + + check: -> + all = $(".placeholder", @element).length + correct = 0 + bad = 0 + $(".placeholder + .question-piece", @element).each (i, qpiece) => + $placeholder = $(qpiece).prev(".placeholder") + if $placeholder.data('solution') == $(qpiece).data('no') + @piece_correct qpiece + correct += 1 + else + bad += 1 + @piece_incorrect qpiece + + @show_score [correct, bad, all] + + solve_question: (question) -> + $(".placeholder", question).each (i, placeholder) => + $qp = $(".question-piece[data-no=" + $(placeholder).data('solution') + "]", question) + @draggable_move $qp, $(placeholder), false + + +class Zastap extends Exercise + constructor: (element) -> + super element + $(".paragraph", @element).each (i, par) => + @wrap_words $(par), $('') + @dragging false, false + + check: -> + all = 0 + correct = 0 + bad = 0 + + $(".paragraph", @element).each (i, par) => + $(".placeholder", par).each (j, qpiece) => + $qp = $(qpiece) + $dragged = $qp.next(".draggable") + if $qp.data("solution") + if $dragged and $qp.data("solution") == $dragged.data("no") + @piece_correct $dragged + correct += 1 +# else -- we dont mark enything here, so not to hint user about solution. He sees he hasn't used all the draggables + + all += 1 + + @show_score [correct, bad, all] + + show_solutions: -> + @reset() + $(".paragraph", @element).each (i, par) => + $(".placeholder[data-solution]", par).each (j, qpiece) => + $qp = $(qpiece) + $dr = $(".draggable[data-no=" + $qp.data('solution') + "]", @element) + @draggable_move $dr, $qp, false + + + wrap_words: (element, wrapper) -> + # This function wraps each word of element in wrapper, but does not descend into child-tags of element. + # It doesn't wrap things between words (defined by ignore RE below). Warning - ignore must begin with ^ + ignore = /^[ \t.,:;()]+/ + + insertWrapped = (txt, elem) -> + nw = wrapper.clone() + $(document.createTextNode(txt)) + .wrap(nw).parent().attr("data-original", txt).insertBefore(elem) + + for j in [element.get(0).childNodes.length-1..0] + chld = element.get(0).childNodes[j] + if chld.nodeType == document.TEXT_NODE + len = chld.textContent.length + wordb = 0 + i = 0 + while i < len + space = ignore.exec(chld.textContent.substr(i)) + if space? + if wordb < i + insertWrapped(chld.textContent.substr(wordb, i-wordb), chld) + + $(document.createTextNode(space[0])).insertBefore(chld) + i += space[0].length + wordb = i + else + i = i + 1 + if wordb < len - 1 + insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld) + $(chld).remove() + + +class Przyporzadkuj extends Exercise + is_multiple: -> + for qp in $(".question-piece", @element) + if $(qp).attr('data-solution').split(/[ ,]+/).length > 1 + return true + return false + + constructor: (element) -> + super element + + @multiple = @is_multiple() + + @dragging @multiple, true + + draggable_equal: (d1, d2) -> + return d1.data("no") == d2.data("no") + + + check_question: (question) -> + # subjects placed in predicates + minimum = $(question).data("minimum") + count = 0 + bad_count = 0 + all = 0 + if not minimum + self = this + $(".subject .question-piece", question).each (i, el) -> + v = self.get_value_optional_list el, 'solution' + mandatory = v[0] + all += mandatory.length + + for pred in $(".predicate [data-predicate]", question) + pn = $(pred).attr('data-predicate') + #if minimum? + # all += minimum + + for qp in $(".question-piece", pred) + v = @get_value_optional_list qp, 'solution' + mandatory = v[0] + optional = v[1] + + if mandatory.indexOf(pn) >= 0 or (minimum and optional.indexOf(pn) >= 0) + count += 1 + @piece_correct qp + else + bad_count += 1 + @piece_incorrect qp + + return [count, bad_count, all] + + solve_question: (question) -> + minimum = $(question).data("min") + + for qp in $(".subject .question-piece", question) + v = @get_value_optional_list qp, 'solution' + mandatory = v[0] + optional = v[1] + + if minimum + draggables = mandatory.count(optional)[0...minimum] + else + draggables = mandatory + for m in draggables + $pr = $(".predicate [data-predicate=" + m + "]", question) + $ph = $pr.find ".placeholder:visible" + @draggable_move $(qp), $ph.eq(0), @multiple + + + +class PrawdaFalsz extends Exercise + constructor: (element) -> + super element + + for qp in $(".question-piece", @element) + $(".true", qp).click (ev) => + ev.preventDefault() + @retry() + $(ev.target).closest(".question-piece").data("value", "true") + $(ev.target).addClass('chosen').siblings('a').removeClass('chosen') + $(".false", qp).click (ev) => + ev.preventDefault() + @retry() + $(ev.target).closest(".question-piece").data("value", "false") + $(ev.target).addClass('chosen').siblings('a').removeClass('chosen') + + + check_question: -> + all = 0 + good = 0 + bad = 0 + for qp in $(".question-piece", @element) + if $(qp).data("solution").toString() == $(qp).data("value") + good += 1 + @piece_correct qp + else + bad += 1 + @piece_incorrect qp + + all += 1 + + return [good, bad, all] + + show_solutions: -> + @reset() + for qp in $(".question-piece", @element) + if $(qp).data('solution') == true + $(".true", qp).click() + else + $(".false", qp).click() + + +########## + +exercise = (ele) -> + es = + wybor: Wybor + uporzadkuj: Uporzadkuj + luki: Luki + zastap: Zastap + przyporzadkuj: Przyporzadkuj + prawdafalsz: PrawdaFalsz + + + cls = es[$(ele).attr('data-type')] + new cls(ele) + + +window.edumed = + 'EduModule': EduModule + + + + +$(document).ready () -> + new EduModule($("#book-text")) + + $(".exercise").each (i, el) -> + exercise(this) diff --git a/wtem/static/wtem/edumed.js b/wtem/static/wtem/edumed.js new file mode 100644 index 0000000..f828dec --- /dev/null +++ b/wtem/static/wtem/edumed.js @@ -0,0 +1,673 @@ +// Generated by CoffeeScript 1.6.3 +(function() { + var $, Binding, EduModule, Exercise, Luki, PrawdaFalsz, Przyporzadkuj, Uporzadkuj, Wybor, Zastap, exercise, + __hasProp = {}.hasOwnProperty, + __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; }; + + $ = jQuery; + + Binding = (function() { + function Binding(handler, element) { + this.handler = handler; + this.element = element; + $(this.element).data(this.handler, this); + } + + return Binding; + + })(); + + EduModule = (function(_super) { + __extends(EduModule, _super); + + function EduModule(element) { + EduModule.__super__.constructor.call(this, 'edumodule', element); + } + + return EduModule; + + })(Binding); + + Exercise = (function(_super) { + __extends(Exercise, _super); + + function Exercise(element) { + var _this = this; + Exercise.__super__.constructor.call(this, 'exercise', element); + $(this.element).data("exercise-html", $(this.element).html()); + $(".check", this.element).click(function(ev) { + _this.check(); + $(".retry", _this.element).show(); + return $(".check", _this.element).hide(); + }); + $(".retry", this.element).click(function(ev) { + return _this.retry(); + }); + $('.solutions', this.element).click(function() { + _this.show_solutions(); + return $(".comment", _this.element).show(); + }); + $('.reset', this.element).click(function() { + return _this.reset(); + }); + } + + Exercise.prototype.retry = function() { + $(".correct, .incorrect", this.element).removeClass("correct incorrect"); + $(".check", this.element).show(); + return $(".retry", this.element).hide(); + }; + + Exercise.prototype.reset = function() { + $(this.element).html($(this.element).data('exercise-html')); + return exercise(this.element); + }; + + Exercise.prototype.piece_correct = function(qpiece) { + return $(qpiece).removeClass('incorrect').addClass('correct'); + }; + + Exercise.prototype.piece_incorrect = function(qpiece) { + return $(qpiece).removeClass('correct').addClass('incorrect'); + }; + + Exercise.prototype.check = function() { + var score, scores, + _this = this; + scores = []; + $(".question", this.element).each(function(i, question) { + return scores.push(_this.check_question(question)); + }); + score = [0, 0, 0]; + $.each(scores, function(i, s) { + score[0] += s[0]; + score[1] += s[1]; + return score[2] += s[2]; + }); + return this.show_score(score); + }; + + Exercise.prototype.show_solutions = function() { + var _this = this; + this.reset(); + return $(".question", this.element).each(function(i, question) { + return _this.solve_question(question); + }); + }; + + Exercise.prototype.get_value_list = function(elem, data_key, numbers) { + var vl; + vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim); + if (numbers) { + vl = vl.map(function(x) { + return parseInt(x); + }); + } + return vl; + }; + + Exercise.prototype.get_value_optional_list = function(elem, data_key) { + var mandat, opt, v, vals, _i, _len; + vals = this.get_value_list(elem, data_key); + mandat = []; + opt = []; + for (_i = 0, _len = vals.length; _i < _len; _i++) { + v = vals[_i]; + if (v.slice(-1) === "?") { + opt.push(v.slice(0, -1)); + } else { + mandat.push(v); + } + } + return [mandat, opt]; + }; + + Exercise.prototype.show_score = function(score) { + var $msg; + $msg = $(".message", this.element); + $msg.text("Wynik: " + score[0] + " / " + score[2]); + if (score[0] >= score[2] && score[1] === 0) { + return $msg.addClass("maxscore"); + } else { + return $msg.removeClass("maxscore"); + } + }; + + Exercise.prototype.draggable_equal = function($draggable1, $draggable2) { + return false; + }; + + Exercise.prototype.draggable_accept = function($draggable, $droppable) { + var d, dropped, _i, _len; + dropped = $droppable.closest("ul, ol").find(".draggable"); + for (_i = 0, _len = dropped.length; _i < _len; _i++) { + d = dropped[_i]; + if (this.draggable_equal($draggable, $(d))) { + return false; + } + } + return true; + }; + + Exercise.prototype.draggable_move = function($draggable, $placeholder, ismultiple) { + var $added, + _this = this; + $added = $draggable.clone(); + $added.data("original", $draggable.get(0)); + if (!ismultiple) { + $draggable.addClass('disabled').draggable('disable'); + } + $placeholder.after($added); + if (!$placeholder.hasClass('multiple')) { + $placeholder.hide(); + } + if ($added.is(".add-li")) { + $added.wrap("
  • "); + } + $added.append('x
    '); + return $('.remove', $added).click(function(ev) { + _this.retry(); + if (!ismultiple) { + $($added.data('original')).removeClass('disabled').draggable('enable'); + } + if ($added.is(".add-li")) { + $added = $added.closest('li'); + } + $added.prev(".placeholder:not(.multiple)").show(); + return $added.remove(); + }); + }; + + Exercise.prototype.dragging = function(ismultiple, issortable) { + var _this = this; + return $(".question", this.element).each(function(i, question) { + var draggable_opts, self; + draggable_opts = { + revert: 'invalid', + helper: 'clone', + start: _this.retry + }; + $(".draggable", question).draggable(draggable_opts); + self = _this; + return $(".placeholder", question).droppable({ + accept: function(draggable) { + var $draggable, is_accepted; + $draggable = $(draggable); + is_accepted = true; + if (!$draggable.is(".draggable")) { + is_accepted = false; + } + if (is_accepted) { + is_accepted = self.draggable_accept($draggable, $(this)); + } + if (is_accepted) { + $(this).addClass('accepting'); + } else { + $(this).removeClass('accepting'); + } + return is_accepted; + }, + drop: function(ev, ui) { + $(ev.target).removeClass('accepting dragover'); + return _this.draggable_move($(ui.draggable), $(ev.target), ismultiple); + }, + over: function(ev, ui) { + return $(ev.target).addClass('dragover'); + }, + out: function(ev, ui) { + return $(ev.target).removeClass('dragover'); + } + }); + }); + }; + + return Exercise; + + })(Binding); + + Wybor = (function(_super) { + __extends(Wybor, _super); + + function Wybor(element) { + Wybor.__super__.constructor.call(this, element); + $(".question-piece input", element).change(this.retry); + } + + Wybor.prototype.check_question = function(question) { + var all, bad, good, solution, + _this = this; + all = 0; + good = 0; + bad = 0; + solution = this.get_value_list(question, 'solution'); + $(".question-piece", question).each(function(i, qpiece) { + var is_checked, piece_name, piece_no, should_be_checked; + piece_no = $(qpiece).attr('data-no'); + piece_name = $(qpiece).attr('data-name'); + if (piece_name) { + should_be_checked = solution.indexOf(piece_name) >= 0; + } else { + should_be_checked = solution.indexOf(piece_no) >= 0; + } + is_checked = $("input", qpiece).is(":checked"); + if (should_be_checked) { + all += 1; + } + if (is_checked) { + if (should_be_checked) { + good += 1; + return _this.piece_correct(qpiece); + } else { + bad += 1; + return _this.piece_incorrect(qpiece); + } + } else { + return $(qpiece).removeClass("correct,incorrect"); + } + }); + return [good, bad, all]; + }; + + Wybor.prototype.solve_question = function(question) { + var solution, + _this = this; + solution = this.get_value_list(question, 'solution'); + return $(".question-piece", question).each(function(i, qpiece) { + var piece_name, piece_no, should_be_checked; + piece_no = $(qpiece).attr('data-no'); + piece_name = $(qpiece).attr('data-name'); + if (piece_name) { + should_be_checked = solution.indexOf(piece_name) >= 0; + } else { + should_be_checked = solution.indexOf(piece_no) >= 0; + } + console.log("check " + $("input[type=checkbox]", qpiece).attr("id") + " -> " + should_be_checked); + return $("input[type=checkbox],input[type=radio]", qpiece).prop('checked', should_be_checked); + }); + }; + + return Wybor; + + })(Exercise); + + Uporzadkuj = (function(_super) { + __extends(Uporzadkuj, _super); + + function Uporzadkuj(element) { + Uporzadkuj.__super__.constructor.call(this, element); + $('ol, ul', this.element).sortable({ + items: "> li", + start: this.retry + }); + } + + Uporzadkuj.prototype.check_question = function(question) { + var all, bad, correct, pkt, pkts, positions, sorted, _i, _ref; + positions = this.get_value_list(question, 'original', true); + sorted = positions.sort(); + pkts = $('.question-piece', question); + correct = 0; + bad = 0; + all = 0; + for (pkt = _i = 0, _ref = pkts.length; 0 <= _ref ? _i < _ref : _i > _ref; pkt = 0 <= _ref ? ++_i : --_i) { + all += 1; + if (pkts.eq(pkt).data('pos') === sorted[pkt]) { + correct += 1; + this.piece_correct(pkts.eq(pkt)); + } else { + bad += 1; + this.piece_incorrect(pkts.eq(pkt)); + } + } + return [correct, bad, all]; + }; + + Uporzadkuj.prototype.solve_question = function(question) { + var p, parent, pkts, positions, sorted, _i, _len, _results; + positions = this.get_value_list(question, 'original', true); + sorted = positions.sort(); + pkts = $('.question-piece', question); + pkts.sort(function(a, b) { + var q, w; + q = $(a).data('pos'); + w = $(b).data('pos'); + if (q < w) { + return 1; + } + if (q > w) { + return -1; + } + return 0; + }); + parent = pkts.eq(0).parent(); + _results = []; + for (_i = 0, _len = pkts.length; _i < _len; _i++) { + p = pkts[_i]; + _results.push(parent.prepend(p)); + } + return _results; + }; + + return Uporzadkuj; + + })(Exercise); + + Luki = (function(_super) { + __extends(Luki, _super); + + function Luki(element) { + Luki.__super__.constructor.call(this, element); + this.dragging(false, false); + } + + Luki.prototype.check = function() { + var all, bad, correct, + _this = this; + all = $(".placeholder", this.element).length; + correct = 0; + bad = 0; + $(".placeholder + .question-piece", this.element).each(function(i, qpiece) { + var $placeholder; + $placeholder = $(qpiece).prev(".placeholder"); + if ($placeholder.data('solution') === $(qpiece).data('no')) { + _this.piece_correct(qpiece); + return correct += 1; + } else { + bad += 1; + return _this.piece_incorrect(qpiece); + } + }); + return this.show_score([correct, bad, all]); + }; + + Luki.prototype.solve_question = function(question) { + var _this = this; + return $(".placeholder", question).each(function(i, placeholder) { + var $qp; + $qp = $(".question-piece[data-no=" + $(placeholder).data('solution') + "]", question); + return _this.draggable_move($qp, $(placeholder), false); + }); + }; + + return Luki; + + })(Exercise); + + Zastap = (function(_super) { + __extends(Zastap, _super); + + function Zastap(element) { + var _this = this; + Zastap.__super__.constructor.call(this, element); + $(".paragraph", this.element).each(function(i, par) { + return _this.wrap_words($(par), $('')); + }); + this.dragging(false, false); + } + + Zastap.prototype.check = function() { + var all, bad, correct, + _this = this; + all = 0; + correct = 0; + bad = 0; + $(".paragraph", this.element).each(function(i, par) { + return $(".placeholder", par).each(function(j, qpiece) { + var $dragged, $qp; + $qp = $(qpiece); + $dragged = $qp.next(".draggable"); + if ($qp.data("solution")) { + if ($dragged && $qp.data("solution") === $dragged.data("no")) { + _this.piece_correct($dragged); + correct += 1; + } + return all += 1; + } + }); + }); + return this.show_score([correct, bad, all]); + }; + + Zastap.prototype.show_solutions = function() { + var _this = this; + this.reset(); + return $(".paragraph", this.element).each(function(i, par) { + return $(".placeholder[data-solution]", par).each(function(j, qpiece) { + var $dr, $qp; + $qp = $(qpiece); + $dr = $(".draggable[data-no=" + $qp.data('solution') + "]", _this.element); + return _this.draggable_move($dr, $qp, false); + }); + }); + }; + + Zastap.prototype.wrap_words = function(element, wrapper) { + var chld, i, ignore, insertWrapped, j, len, space, wordb, _i, _ref, _results; + ignore = /^[ \t.,:;()]+/; + insertWrapped = function(txt, elem) { + var nw; + nw = wrapper.clone(); + return $(document.createTextNode(txt)).wrap(nw).parent().attr("data-original", txt).insertBefore(elem); + }; + _results = []; + for (j = _i = _ref = element.get(0).childNodes.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; j = _ref <= 0 ? ++_i : --_i) { + chld = element.get(0).childNodes[j]; + if (chld.nodeType === document.TEXT_NODE) { + len = chld.textContent.length; + wordb = 0; + i = 0; + while (i < len) { + space = ignore.exec(chld.textContent.substr(i)); + if (space != null) { + if (wordb < i) { + insertWrapped(chld.textContent.substr(wordb, i - wordb), chld); + } + $(document.createTextNode(space[0])).insertBefore(chld); + i += space[0].length; + wordb = i; + } else { + i = i + 1; + } + } + if (wordb < len - 1) { + insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld); + } + _results.push($(chld).remove()); + } else { + _results.push(void 0); + } + } + return _results; + }; + + return Zastap; + + })(Exercise); + + Przyporzadkuj = (function(_super) { + __extends(Przyporzadkuj, _super); + + Przyporzadkuj.prototype.is_multiple = function() { + var qp, _i, _len, _ref; + _ref = $(".question-piece", this.element); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + qp = _ref[_i]; + if ($(qp).attr('data-solution').split(/[ ,]+/).length > 1) { + return true; + } + } + return false; + }; + + function Przyporzadkuj(element) { + Przyporzadkuj.__super__.constructor.call(this, element); + this.multiple = this.is_multiple(); + this.dragging(this.multiple, true); + } + + Przyporzadkuj.prototype.draggable_equal = function(d1, d2) { + return d1.data("no") === d2.data("no"); + }; + + Przyporzadkuj.prototype.check_question = function(question) { + var all, bad_count, count, mandatory, minimum, optional, pn, pred, qp, self, v, _i, _j, _len, _len1, _ref, _ref1; + minimum = $(question).data("minimum"); + count = 0; + bad_count = 0; + all = 0; + if (!minimum) { + self = this; + $(".subject .question-piece", question).each(function(i, el) { + var mandatory, v; + v = self.get_value_optional_list(el, 'solution'); + mandatory = v[0]; + return all += mandatory.length; + }); + } + _ref = $(".predicate [data-predicate]", question); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + pred = _ref[_i]; + pn = $(pred).attr('data-predicate'); + _ref1 = $(".question-piece", pred); + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + qp = _ref1[_j]; + v = this.get_value_optional_list(qp, 'solution'); + mandatory = v[0]; + optional = v[1]; + if (mandatory.indexOf(pn) >= 0 || (minimum && optional.indexOf(pn) >= 0)) { + count += 1; + this.piece_correct(qp); + } else { + bad_count += 1; + this.piece_incorrect(qp); + } + } + } + return [count, bad_count, all]; + }; + + Przyporzadkuj.prototype.solve_question = function(question) { + var $ph, $pr, draggables, m, mandatory, minimum, optional, qp, v, _i, _len, _ref, _results; + minimum = $(question).data("min"); + _ref = $(".subject .question-piece", question); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + qp = _ref[_i]; + v = this.get_value_optional_list(qp, 'solution'); + mandatory = v[0]; + optional = v[1]; + if (minimum) { + draggables = mandatory.count(optional).slice(0, minimum); + } else { + draggables = mandatory; + } + _results.push((function() { + var _j, _len1, _results1; + _results1 = []; + for (_j = 0, _len1 = draggables.length; _j < _len1; _j++) { + m = draggables[_j]; + $pr = $(".predicate [data-predicate=" + m + "]", question); + $ph = $pr.find(".placeholder:visible"); + _results1.push(this.draggable_move($(qp), $ph.eq(0), this.multiple)); + } + return _results1; + }).call(this)); + } + return _results; + }; + + return Przyporzadkuj; + + })(Exercise); + + PrawdaFalsz = (function(_super) { + __extends(PrawdaFalsz, _super); + + function PrawdaFalsz(element) { + var qp, _i, _len, _ref, + _this = this; + PrawdaFalsz.__super__.constructor.call(this, element); + _ref = $(".question-piece", this.element); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + qp = _ref[_i]; + $(".true", qp).click(function(ev) { + ev.preventDefault(); + _this.retry(); + $(ev.target).closest(".question-piece").data("value", "true"); + return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen'); + }); + $(".false", qp).click(function(ev) { + ev.preventDefault(); + _this.retry(); + $(ev.target).closest(".question-piece").data("value", "false"); + return $(ev.target).addClass('chosen').siblings('a').removeClass('chosen'); + }); + } + } + + PrawdaFalsz.prototype.check_question = function() { + var all, bad, good, qp, _i, _len, _ref; + all = 0; + good = 0; + bad = 0; + _ref = $(".question-piece", this.element); + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + qp = _ref[_i]; + if ($(qp).data("solution").toString() === $(qp).data("value")) { + good += 1; + this.piece_correct(qp); + } else { + bad += 1; + this.piece_incorrect(qp); + } + all += 1; + } + return [good, bad, all]; + }; + + PrawdaFalsz.prototype.show_solutions = function() { + var qp, _i, _len, _ref, _results; + this.reset(); + _ref = $(".question-piece", this.element); + _results = []; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + qp = _ref[_i]; + if ($(qp).data('solution') === true) { + _results.push($(".true", qp).click()); + } else { + _results.push($(".false", qp).click()); + } + } + return _results; + }; + + return PrawdaFalsz; + + })(Exercise); + + exercise = function(ele) { + var cls, es; + es = { + wybor: Wybor, + uporzadkuj: Uporzadkuj, + luki: Luki, + zastap: Zastap, + przyporzadkuj: Przyporzadkuj, + prawdafalsz: PrawdaFalsz + }; + cls = es[$(ele).attr('data-type')]; + return new cls(ele); + }; + + window.edumed = { + 'EduModule': EduModule + }; + + $(document).ready(function() { + new EduModule($("#book-text")); + return $(".exercise").each(function(i, el) { + return exercise(this); + }); + }); + +}).call(this); diff --git a/wtem/templates/wtem/main.html b/wtem/templates/wtem/main.html index 22f919d..bee75ec 100644 --- a/wtem/templates/wtem/main.html +++ b/wtem/templates/wtem/main.html @@ -1 +1,6 @@ {% extends 'base_super.html' %} +{% load compressed %} + +{% block extra_script %} + {% compressed_js 'wtem' %} +{% endblock %} -- 2.20.1