5 constructor: (@handler, @element) ->
6 $(@element).data(@handler, this)
9 class EduModule extends Binding
10 constructor: (element) ->
11 super 'edumodule', element
13 # $("[name=teacher-toggle]").change (ev) =>
14 # if $(ev.target).is(":checked")
15 # $(".teacher", @element).addClass "show"
17 # $(".teacher", @element).removeClass "show"
20 class Exercise extends Binding
21 constructor: (element) ->
22 super 'exercise', element
23 # just save the html to reset the exercise
24 $(@element).data("exercise-html", $(@element).html())
26 $(".check", @element).click (ev) =>
28 $(".retry", @element).show()
29 $(".check", @element).hide()
30 $(".retry", @element).click (ev) =>
32 $('.solutions', @element).click =>
34 $(".comment", @element).show()
35 $('.reset', @element).click =>
39 $(".correct, .incorrect", @element).removeClass("correct incorrect")
40 $(".check", @element).show()
41 $(".retry", @element).hide()
44 $(@element).html($(@element).data('exercise-html'))
47 piece_correct: (qpiece) ->
48 $(qpiece).removeClass('incorrect').addClass('correct')
50 piece_incorrect: (qpiece) ->
51 $(qpiece).removeClass('correct').addClass('incorrect')
55 $(".question", @element).each (i, question) =>
56 scores.push(@check_question question)
59 $.each scores, (i, s) ->
67 $(".question", @element).each (i, question) =>
68 @solve_question question
72 $('.question', @element).each (i, question) =>
73 answers.push(@get_answer question)
76 # Parses a list of values, separated by space or comma.
77 # The list is read from data attribute of elem using data_key
78 # Returns a list with elements
79 # eg.: things_i_need: "house bike tv playstation"
80 # yields ["house", "bike", "tv", "playstation"]
81 # If optional numbers argument is true, returns list of numbers
83 get_value_list: (elem, data_key, numbers) ->
84 vl = $(elem).attr("data-" + data_key).split(/[ ,]+/).map($.trim) #.map((x) -> parseInt(x))
86 vl = vl.map((x) -> parseInt(x))
89 # Parses a list of values, separated by space or comma.
90 # The list is read from data attribute of elem using data_key
91 # Returns a 2-element list with mandatory and optional
92 # items. optional items are marked with a question mark on the end
93 # eg.: things_i_need: "house bike tv? playstation?"
94 # yields [[ "house", "bike"], ["tv", "playstation"]]
95 get_value_optional_list: (elem, data_key) ->
96 vals = @get_value_list(elem, data_key)
100 if v.slice(-1) == "?"
101 opt.push v.slice(0, -1)
106 show_score: (score) ->
107 $msg = $(".message", @element)
108 $msg.text("Wynik: #{score[0]} / #{score[2]}")
109 if score[0] >= score[2] and score[1] == 0
110 $msg.addClass("maxscore")
112 $msg.removeClass("maxscore")
115 draggable_equal: ($draggable1, $draggable2) ->
118 draggable_accept: ($draggable, $droppable) ->
119 dropped = $droppable.closest("ul, ol").find(".draggable")
121 if @draggable_equal $draggable, $(d)
125 draggable_move: ($draggable, $placeholder, ismultiple) ->
126 $added = $draggable.clone()
127 $added.data("original", $draggable.get(0))
129 $draggable.addClass('disabled').draggable('disable')
131 $placeholder.after($added)
132 if not $placeholder.hasClass('multiple')
134 if $added.is(".add-li")
137 $added.append('<span class="remove">x</span><div class="clr"></div>')
138 $('.remove', $added).click (ev) =>
141 $($added.data('original')).removeClass('disabled').draggable('enable')
143 if $added.is(".add-li")
144 $added = $added.closest('li')
145 $added.prev(".placeholder:not(.multiple)").show()
149 ## XXX co z issortable?
150 dragging: (ismultiple, issortable) ->
151 $(".question", @element).each (i, question) =>
157 $(".draggable", question).draggable(draggable_opts)
159 $(".placeholder", question).droppable
160 accept: (draggable) ->
161 $draggable = $(draggable)
164 if not $draggable.is(".draggable")
168 is_accepted= self.draggable_accept $draggable, $(this)
171 $(this).addClass 'accepting'
173 $(this).removeClass 'accepting'
177 $(ev.target).removeClass 'accepting dragover'
179 @draggable_move $(ui.draggable), $(ev.target), ismultiple
181 # $added = $(ui.draggable).clone()
182 # $added.data("original", ui.draggable)
184 # $(ui.draggable).addClass('disabled').draggable('disable')
186 # $(ev.target).after(added)
187 # if not $(ev.target).hasClass('multiple')
188 # $(ev.target).hide()
189 # $added.append('<span class="remove">x</span>')
190 # $('.remove', added).click (ev) =>
191 # $added.prev(".placeholder:not(.multiple)").show()
193 # $added.data('original').removeClass('disabled').draggable('enable')
197 $(ev.target).addClass 'dragover'
201 $(ev.target).removeClass 'dragover'
205 class Wybor extends Exercise
206 constructor: (element) ->
208 $(".question-piece input", element).change(@retry);
211 check_question: (question) ->
215 solution = @get_value_list(question, 'solution')
216 $(".question-piece", question).each (i, qpiece) =>
217 piece_no = $(qpiece).attr 'data-no'
218 piece_name = $(qpiece).attr 'data-name'
220 should_be_checked = solution.indexOf(piece_name) >= 0
222 should_be_checked = solution.indexOf(piece_no) >= 0
223 is_checked = $("input", qpiece).is(":checked")
231 @piece_correct qpiece
234 @piece_incorrect qpiece
236 $(qpiece).removeClass("correct,incorrect")
238 return [good, bad, all]
240 solve_question: (question) ->
241 solution = @get_value_list(question, 'solution')
242 $(".question-piece", question).each (i, qpiece) =>
243 piece_no = $(qpiece).attr 'data-no'
244 piece_name = $(qpiece).attr 'data-name'
246 should_be_checked = solution.indexOf(piece_name) >= 0
248 should_be_checked = solution.indexOf(piece_no) >= 0
249 console.log("check " + $("input[type=checkbox]", qpiece).attr("id") + " -> " + should_be_checked)
250 $("input[type=checkbox],input[type=radio]", qpiece).prop 'checked', should_be_checked
252 get_answer: (question) ->
254 $('.question-piece', question).each (i, qpiece) =>
256 if $("input[type=checkbox],input[type=radio]", qpiece).is(':checked')
257 answer.push($qpiece.attr('data-name'))
261 class Uporzadkuj extends Exercise
262 constructor: (element) ->
264 $('ol, ul', @element).sortable({ items: "> li", start: @retry })
266 check_question: (question) ->
267 positions = @get_value_list(question, 'original', true)
268 sorted = positions.sort()
269 pkts = $('.question-piece', question)
275 for pkt in [0...pkts.length]
277 if pkts.eq(pkt).data('pos') == sorted[pkt]
279 @piece_correct pkts.eq(pkt)
282 @piece_incorrect pkts.eq(pkt)
283 return [correct, bad, all]
285 solve_question: (question) ->
286 positions = @get_value_list(question, 'original', true)
287 sorted = positions.sort()
288 pkts = $('.question-piece', question)
296 parent = pkts.eq(0).parent()
300 get_answer: (question) ->
302 $(".question-piece", @element).each (i, qpiece) =>
303 answer.push($(qpiece).attr('data-pos'))
307 # XXX propozycje="1/0"
308 class Luki extends Exercise
309 constructor: (element) ->
311 @dragging false, false
314 all = $(".placeholder", @element).length
317 $(".placeholder + .question-piece", @element).each (i, qpiece) =>
318 $placeholder = $(qpiece).prev(".placeholder")
319 if $placeholder.data('solution') == $(qpiece).data('no')
320 @piece_correct qpiece
324 @piece_incorrect qpiece
326 @show_score [correct, bad, all]
328 solve_question: (question) ->
329 $(".placeholder", question).each (i, placeholder) =>
330 $qp = $(".question-piece[data-no=" + $(placeholder).data('solution') + "]", question)
331 @draggable_move $qp, $(placeholder), false
334 class Zastap extends Exercise
335 constructor: (element) ->
337 $(".paragraph", @element).each (i, par) =>
338 @wrap_words $(par), $('<span class="placeholder zastap"/>')
339 @dragging false, false
346 $(".paragraph", @element).each (i, par) =>
347 $(".placeholder", par).each (j, qpiece) =>
349 $dragged = $qp.next(".draggable")
350 if $qp.data("solution")
351 if $dragged and $qp.data("solution") == $dragged.data("no")
352 @piece_correct $dragged
354 # else -- we dont mark enything here, so not to hint user about solution. He sees he hasn't used all the draggables
358 @show_score [correct, bad, all]
362 $(".paragraph", @element).each (i, par) =>
363 $(".placeholder[data-solution]", par).each (j, qpiece) =>
365 $dr = $(".draggable[data-no=" + $qp.data('solution') + "]", @element)
366 @draggable_move $dr, $qp, false
369 wrap_words: (element, wrapper) ->
370 # This function wraps each word of element in wrapper, but does not descend into child-tags of element.
371 # It doesn't wrap things between words (defined by ignore RE below). Warning - ignore must begin with ^
372 ignore = /^[ \t.,:;()]+/
374 insertWrapped = (txt, elem) ->
376 $(document.createTextNode(txt))
377 .wrap(nw).parent().attr("data-original", txt).insertBefore(elem)
379 for j in [element.get(0).childNodes.length-1..0]
380 chld = element.get(0).childNodes[j]
381 if chld.nodeType == document.TEXT_NODE
382 len = chld.textContent.length
386 space = ignore.exec(chld.textContent.substr(i))
389 insertWrapped(chld.textContent.substr(wordb, i-wordb), chld)
391 $(document.createTextNode(space[0])).insertBefore(chld)
397 insertWrapped(chld.textContent.substr(wordb, len - 1 - wordb), chld)
401 class Przyporzadkuj extends Exercise
403 for qp in $(".question-piece", @element)
404 if $(qp).attr('data-solution').split(/[ ,]+/).length > 1
408 constructor: (element) ->
411 @multiple = @is_multiple()
413 @dragging @multiple, true
415 draggable_equal: (d1, d2) ->
416 return d1.data("no") == d2.data("no")
419 check_question: (question) ->
420 # subjects placed in predicates
421 minimum = $(question).data("minimum")
427 $(".subject .question-piece", question).each (i, el) ->
428 v = self.get_value_optional_list el, 'solution'
430 all += mandatory.length
432 for pred in $(".predicate [data-predicate]", question)
433 pn = $(pred).attr('data-predicate')
437 for qp in $(".question-piece", pred)
438 v = @get_value_optional_list qp, 'solution'
442 if mandatory.indexOf(pn) >= 0 or (minimum and optional.indexOf(pn) >= 0)
449 return [count, bad_count, all]
451 solve_question: (question) ->
452 minimum = $(question).data("min")
454 for qp in $(".subject .question-piece", question)
455 v = @get_value_optional_list qp, 'solution'
460 draggables = mandatory.count(optional)[0...minimum]
462 draggables = mandatory
464 $pr = $(".predicate [data-predicate=" + m + "]", question)
465 $ph = $pr.find ".placeholder:visible"
466 @draggable_move $(qp), $ph.eq(0), @multiple
468 get_answer: (question) ->
470 $(".predicate [data-predicate]", question).each (i, subjects) =>
471 predicate = $(subjects).attr('data-predicate')
472 answer[predicate] = []
473 $('.question-piece', subjects).each (i, qpiece) =>
475 answer[predicate].push($qpiece.attr('data-id'))
479 class PrawdaFalsz extends Exercise
480 constructor: (element) ->
483 for qp in $(".question-piece", @element)
484 $(".true", qp).click (ev) =>
487 $(ev.target).closest(".question-piece").data("value", "true")
488 $(ev.target).addClass('chosen').siblings('a').removeClass('chosen')
489 $(".false", qp).click (ev) =>
492 $(ev.target).closest(".question-piece").data("value", "false")
493 $(ev.target).addClass('chosen').siblings('a').removeClass('chosen')
500 for qp in $(".question-piece", @element)
501 if $(qp).data("solution").toString() == $(qp).data("value")
510 return [good, bad, all]
514 for qp in $(".question-piece", @element)
515 if $(qp).data('solution') == true
516 $(".true", qp).click()
518 $(".false", qp).click()
520 get_answer: (question) ->
522 $(".question-piece", @element).each (i, qpiece) =>
523 answer.push($(qpiece).data('value') || '-')
531 uporzadkuj: Uporzadkuj
534 przyporzadkuj: Przyporzadkuj
535 prawdafalsz: PrawdaFalsz
538 cls = es[$(ele).attr('data-type')]
543 'EduModule': EduModule
548 $(document).ready () ->
549 new EduModule($("#book-text"))
551 $(".exercise").each (i, el) ->