From fc8acb61a33974ca022349fac8f682bb355392dc Mon Sep 17 00:00:00 2001 From: Felix Sun Date: Fri, 28 Jun 2013 12:02:52 -0400 Subject: [PATCH] Changed voting dialog to only display one tab per answer. No tests for this, yet. Conflicts: common/lib/xmodule/xmodule/crowdsource_hinter.py common/templates/hinter_display.html --- .../lib/xmodule/xmodule/crowdsource_hinter.py | 41 +++++++++---------- .../js/src/crowdsource_hinter/display.coffee | 13 ++++-- common/templates/hinter_display.html | 22 ++++++---- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/common/lib/xmodule/xmodule/crowdsource_hinter.py b/common/lib/xmodule/xmodule/crowdsource_hinter.py index 7c7f94a26b..734708ec04 100644 --- a/common/lib/xmodule/xmodule/crowdsource_hinter.py +++ b/common/lib/xmodule/xmodule/crowdsource_hinter.py @@ -188,8 +188,8 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule): Args: `data` -- not actually used. (It is assumed that the answer is correct.) Output keys: - - 'index_to_hints' maps previous answer indices to hints that the user saw earlier. - - 'index_to_answer' maps previous answer indices to the actual answer submitted. + - 'answer_to_hints': a nested dictionary. + answer_to_hints[answer][hint_pk] returns the text of the hint. """ # The student got it right. # Did he submit at least one wrong answer? @@ -199,27 +199,24 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule): # Make a hint-voting interface for each wrong answer. The student will only # be allowed to make one vote / submission, but he can choose which wrong answer # he wants to look at. - # index_to_hints[previous answer #] = [(hint text, hint pk), + ] - index_to_hints = {} - # index_to_answer[previous answer #] = answer text - index_to_answer = {} + answer_to_hints = {} #answer_to_hints[answer text][hint pk] -> hint text # Go through each previous answer, and populate index_to_hints and index_to_answer. for i in xrange(len(self.previous_answers)): answer, hints_offered = self.previous_answers[i] - index_to_hints[i] = [] - index_to_answer[i] = answer + if answer not in answer_to_hints: + answer_to_hints[answer] = {} if answer in self.hints: # Go through each hint, and add to index_to_hints for hint_id in hints_offered: - if hint_id is not None: + if (hint_id is not None) and (hint_id not in answer_to_hints[answer]): try: - index_to_hints[i].append((self.hints[answer][str(hint_id)][0], hint_id)) + answer_to_hints[answer][hint_id] = self.hints[answer][str(hint_id)][0] except KeyError: # Sometimes, the hint that a user saw will have been deleted by the instructor. continue - return {'index_to_hints': index_to_hints, 'index_to_answer': index_to_answer} + return {'answer_to_hints': answer_to_hints} def tally_vote(self, data): """ @@ -229,27 +226,29 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule): `data` -- expected to have the following keys: 'answer': ans_no (index in previous_answers) 'hint': hint_pk + 'pk_list': We will return a list of how many votes each hint has so far. + It's up to the browser to specify which hints to return vote counts for. + Every pk listed here will have a hint count returned. Returns key 'hint_and_votes', a list of (hint_text, #votes) pairs. """ if self.user_voted: - return {} - ans_no = int(data['answer']) - hint_no = str(data['hint']) - answer = self.previous_answers[ans_no][0] + return json.dumps({'contents': 'Sorry, but you have already voted!'}) + ans = data['answer'] + hint_pk = str(data['hint']) + pk_list = json.loads(data['pk_list']) # We use temp_dict because we need to do a direct write for the database to update. temp_dict = self.hints - temp_dict[answer][hint_no][1] += 1 + temp_dict[ans][hint_pk][1] += 1 self.hints = temp_dict # Don't let the user vote again! self.user_voted = True # Return a list of how many votes each hint got. hint_and_votes = [] - for hint_no in self.previous_answers[ans_no][1]: - if hint_no is None: - continue - hint_and_votes.append(temp_dict[answer][str(hint_no)]) + for vote_pk in pk_list: + hint_and_votes.append(temp_dict[ans][vote_pk]) + hint_and_votes.sort(key=lambda pair: pair[1], reverse=True) # Reset self.previous_answers. self.previous_answers = [] return {'hint_and_votes': hint_and_votes} @@ -266,7 +265,7 @@ class CrowdsourceHinterModule(CrowdsourceHinterFields, XModule): """ # Do html escaping. Perhaps in the future do profanity filtering, etc. as well. hint = escape(data['hint']) - answer = self.previous_answers[int(data['answer'])][0] + answer = data['answer'] # Only allow a student to vote or submit a hint once. if self.user_voted: return {'message': 'Sorry, but you have already voted!'} diff --git a/common/lib/xmodule/xmodule/js/src/crowdsource_hinter/display.coffee b/common/lib/xmodule/xmodule/js/src/crowdsource_hinter/display.coffee index 72522f5b03..3df970a618 100644 --- a/common/lib/xmodule/xmodule/js/src/crowdsource_hinter/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/crowdsource_hinter/display.coffee @@ -28,6 +28,10 @@ class @Hinter $: (selector) -> $(selector, @el) + jq_escape: (string) => + # Escape a string for jquery selector use. + return string.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~]/g, '\\$&') + bind: => window.update_schematics() @$('input.vote').click @vote @@ -44,14 +48,17 @@ class @Hinter vote: (eventObj) => target = @$(eventObj.currentTarget) - post_json = {'answer': target.data('answer'), 'hint': target.data('hintno')} + parent_div_selector = '#previous-answer-' + @jq_escape(target.attr('data-answer')) + all_pks = @$(parent_div_selector).attr('data-all-pks') + console.debug(all_pks) + post_json = {'answer': target.attr('data-answer'), 'hint': target.data('hintno'), 'pk_list': all_pks} $.postWithPrefix "#{@url}/vote", post_json, (response) => @render(response.contents) submit_hint: (eventObj) => target = @$(eventObj.currentTarget) - textarea_id = '#custom-hint-' + target.data('answer') - post_json = {'answer': target.data('answer'), 'hint': @$(textarea_id).val()} + textarea_id = '#custom-hint-' + @jq_escape(target.attr('data-answer')) + post_json = {'answer': target.attr('data-answer'), 'hint': @$(textarea_id).val()} $.postWithPrefix "#{@url}/submit_hint",post_json, (response) => @render(response.contents) diff --git a/common/templates/hinter_display.html b/common/templates/hinter_display.html index 6f5d6f37fb..d349a17fc5 100644 --- a/common/templates/hinter_display.html +++ b/common/templates/hinter_display.html @@ -25,21 +25,25 @@
- % for index, answer in index_to_answer.items(): -
+ % for answer, pk_dict in answer_to_hints.items(): + <% + import json + all_pks = json.dumps(pk_dict.keys()) + %> +
- % if index in index_to_hints and len(index_to_hints[index]) > 0: + % if len(pk_dict) > 0:

Which hint would be most effective to show a student who also got ${answer}?

- % for hint_text, hint_pk in index_to_hints[index]: + % for hint_pk, hint_text in pk_dict.items():

- + ${hint_text}

% endfor @@ -50,12 +54,12 @@

What hint would you give a student who made the same mistake you did? Please don't give away the answer.

-

- +
% endfor