Commit e3c213dd by Victor Shnayder

Refactor html and js.

Next:
  - more clear states (logic in python, view in js)
  - style
parent b66a559b
sa_wrapper_name='section.sa-wrapper' class @SelfAssessment
constructor: (element) ->
@el = $(element).find('section.self-assessment')
@id = @el.data('id')
@ajax_url = @el.data('ajax-url')
$(document).on('click', "#{sa_wrapper_name} input#show", ( -> # Where to put the rubric once we load it
post_url=$("#{sa_wrapper_name} input#ajax_url").attr('url') @rubric_wrapper = @$('.rubric-wrapper')
final_url="#{post_url}/sa_show" @check_button = @$('.submit-button')
answer=$("#{sa_wrapper_name} textarea#answer").val() @answer_area = @$('textarea.answer')
$.post final_url, {'student_answer' : answer }, (response) -> @errors_area = @$('.error')
if response.success @state = 'prompt' # switches to 'eval' after answer is submitted
$("#{sa_wrapper_name} input#show").remove() @bind()
$("#{sa_wrapper_name} textarea#answer").remove()
$("#{sa_wrapper_name} p#rubric").append("Your answer: #{answer}") # locally scoped jquery.
$("#{sa_wrapper_name} p#rubric").append(response.rubric) $: (selector) ->
else $(selector, @el)
$("#{sa_wrapper_name} input#show").remove()
$("#{sa_wrapper_name} p#rubric").append(response.message) bind: ->
)); @check_button.click @show_rubric
$(document).on('click', "#{sa_wrapper_name} input#save", ( -> find_eval_elements: ->
assessment=$("#{sa_wrapper_name} #assessment").find(':selected').text() # find the elements we'll need from the newly loaded rubric data
post_url=$("#{sa_wrapper_name} input#ajax_url").attr('url') @assessment = @$('select.assessment')
final_url="#{post_url}/sa_save" @hint = @$('textarea.hint')
hint=$("#{sa_wrapper_name} textarea#hint").val() @save_message = @$('.save_message')
$.post final_url, {'assessment':assessment, 'hint':hint}, (response) ->
if response.success show_rubric: (event) =>
$("#{sa_wrapper_name} p#save_message").append(response.message) event.preventDefault()
$("#{sa_wrapper_name} input#save").remove() if @state == 'prompt'
)); data = {'student_answer' : @answer_area.val()}
$.postWithPrefix "#{@ajax_url}/show", data, (response) =>
if response.success
@rubric_wrapper.html(response.rubric)
@state = 'eval'
@find_eval_elements()
else
@errors_area.html(response.message)
else
data = {'assessment' : @assessment.find(':selected').text(), 'hint' : @hint.val()}
$.postWithPrefix "#{@ajax_url}/save", data, (response) =>
if response.success
@rubric_wrapper.html(response.message)
else
@errors_area.html('There was an error saving your response.')
...@@ -22,25 +22,22 @@ from .editing_module import EditingDescriptor ...@@ -22,25 +22,22 @@ from .editing_module import EditingDescriptor
from .html_checker import check_html from .html_checker import check_html
from .stringify import stringify_children from .stringify import stringify_children
from .x_module import XModule from .x_module import XModule
from .xml_module import XmlDescriptor, name_to_pathname from .xml_module import XmlDescriptor
from xmodule.modulestore import Location from xmodule.modulestore import Location
from xmodule.contentstore.content import XASSET_SRCREF_PREFIX, StaticContent
log = logging.getLogger("mitx.courseware") log = logging.getLogger("mitx.courseware")
#Set the default number of max attempts. Should be 1 for production # Set the default number of max attempts. Should be 1 for production
#Set higher for debugging/testing # Set higher for debugging/testing
# attempts specified in xml definition overrides this. # attempts specified in xml definition overrides this.
MAX_ATTEMPTS = 1 MAX_ATTEMPTS = 1
#Set maximum available number of points. Should be set to 1 for now due to correctness handling, # Set maximum available number of points. Should be set to 1 for now due to correctness handling,
# which only allows for correct/incorrect. # which only allows for correct/incorrect.
MAX_SCORE=1 MAX_SCORE = 1
class SelfAssessmentModule(XModule): class SelfAssessmentModule(XModule):
js = {'coffee': [resource_string(__name__, 'js/src/selfassessment/display.coffee')] js = {'coffee': [resource_string(__name__, 'js/src/selfassessment/display.coffee')]}
}
js_module_name = "SelfAssessment" js_module_name = "SelfAssessment"
def get_html(self): def get_html(self):
...@@ -85,17 +82,21 @@ class SelfAssessmentModule(XModule): ...@@ -85,17 +82,21 @@ class SelfAssessmentModule(XModule):
log.debug('Instance state of self-assessment module {0}: {1}'.format(location.url(), instance_state)) log.debug('Instance state of self-assessment module {0}: {1}'.format(location.url(), instance_state))
# Pull out state, or initialize variables # Pull out state, or initialize variables
# lists of student answers, correctness responses ('incorrect'/'correct'), and suggested hints
# lists of student answers, correctness responses
# ('incorrect'/'correct'), and suggested hints
self.student_answers = instance_state.get('student_answers', []) self.student_answers = instance_state.get('student_answers', [])
self.correctness = instance_state.get('correctness', []) self.correctness = instance_state.get('correctness', [])
self.hints = instance_state.get('hints', []) self.hints = instance_state.get('hints', [])
# Used to keep track of a submitted answer for which we don't have a self-assessment and hint yet: # Used to keep track of a submitted answer for which we don't have a
# this means that the answers, correctness, hints always stay in sync, and have the same number of elements. # self-assessment and hint yet: this means that the answers,
# correctness, hints always stay in sync, and have the same number of
# elements.
self.temp_answer = instance_state.get('temp_answer', '') self.temp_answer = instance_state.get('temp_answer', '')
# Used for progress / grading. Currently get credit just for completion (doesn't matter if you self-assessed # Used for progress / grading. Currently get credit just for
# correct/incorrect). # completion (doesn't matter if you self-assessed correct/incorrect).
self.score = instance_state.get('score', 0) self.score = instance_state.get('score', 0)
self.top_score = instance_state.get('top_score', MAX_SCORE) self.top_score = instance_state.get('top_score', MAX_SCORE)
...@@ -116,21 +117,15 @@ class SelfAssessmentModule(XModule): ...@@ -116,21 +117,15 @@ class SelfAssessmentModule(XModule):
#Determine if student has answered the question before. This is used to display #Determine if student has answered the question before. This is used to display
#a "previous answer" message to the student if they have. #a "previous answer" message to the student if they have.
previous_answer='' previous_answer = self.student_answers[-1] if self.student_answers else ''
if len(self.student_answers)>0:
previous_answer=self.student_answers[len(self.student_answers)-1]
#set context variables and render template #set context variables and render template
self.context = { context = {
'prompt' : self.prompt, 'prompt' : self.prompt,
'rubric' : self.rubric,
'hint_prompt' : self.hint_prompt,
'previous_answer_given' : len(self.student_answers)>0,
'previous_answer' : previous_answer, 'previous_answer' : previous_answer,
'ajax_url' : system.ajax_url, 'ajax_url' : system.ajax_url,
'section_name' : 'sa-wrapper',
} }
self.html = self.system.render_template('self_assessment_prompt.html', self.context) self.html = self.system.render_template('self_assessment_prompt.html', context)
def get_score(self): def get_score(self):
return {'score': self.score} return {'score': self.score}
...@@ -153,7 +148,7 @@ class SelfAssessmentModule(XModule): ...@@ -153,7 +148,7 @@ class SelfAssessmentModule(XModule):
def handle_ajax(self, dispatch, get): def handle_ajax(self, dispatch, get):
''' """
This is called by courseware.module_render, to handle an AJAX call. This is called by courseware.module_render, to handle an AJAX call.
"get" is request.POST. "get" is request.POST.
...@@ -161,11 +156,11 @@ class SelfAssessmentModule(XModule): ...@@ -161,11 +156,11 @@ class SelfAssessmentModule(XModule):
{ 'progress_changed' : True/False, { 'progress_changed' : True/False,
'progress' : 'none'/'in_progress'/'done', 'progress' : 'none'/'in_progress'/'done',
<other request-specific values here > } <other request-specific values here > }
''' """
handlers = { handlers = {
'sa_show': self.show_rubric, 'show': self.show_rubric,
'sa_save': self.save_problem, 'save': self.save_problem,
} }
if dispatch not in handlers: if dispatch not in handlers:
...@@ -182,21 +177,24 @@ class SelfAssessmentModule(XModule): ...@@ -182,21 +177,24 @@ class SelfAssessmentModule(XModule):
def show_rubric(self, get): def show_rubric(self, get):
""" """
After the prompt is submitted, show the rubric After the answer is submitted, show the rubric.
""" """
#Check to see if attempts are less than max # Check to see if attempts are less than max
if(self.attempts < self.max_attempts): if(self.attempts < self.max_attempts):
# Dump to temp_answer to keep answer in sync with correctness and hint # Dump to temp_answer to keep answer in sync with correctness and hint
self.temp_answer = get['student_answer'] self.temp_answer = get['student_answer']
#Return success and return rubric html to ajax call # Return success and return rubric html to ajax call
rubric_context = {'rubric' : self.rubric,
'hint_prompt' : self.hint_prompt,}
return { return {
'success': True, 'success': True,
'rubric': self.system.render_template('self_assessment_rubric.html', self.context) 'rubric': self.system.render_template('self_assessment_rubric.html', rubric_context)
} }
else: else:
#If too many attempts, prevent student from saving answer and seeing rubric. # If too many attempts, prevent student from saving answer and seeing rubric.
return{ return {
'success': False, 'success': False,
'message': 'Too many attempts.' 'message': 'Too many attempts.'
} }
...@@ -221,7 +219,7 @@ class SelfAssessmentModule(XModule): ...@@ -221,7 +219,7 @@ class SelfAssessmentModule(XModule):
#Create and store event info dict #Create and store event info dict
#Currently points are assigned for completion, so set to 1 instead of depending on correctness. #Currently points are assigned for completion, so set to 1 instead of depending on correctness.
points=1 points = 1
event_info = dict() event_info = dict()
event_info['state'] = { event_info['state'] = {
'student_answers': self.student_answers, 'student_answers': self.student_answers,
...@@ -315,4 +313,4 @@ class SelfAssessmentDescriptor(XmlDescriptor, EditingDescriptor): ...@@ -315,4 +313,4 @@ class SelfAssessmentDescriptor(XmlDescriptor, EditingDescriptor):
for child in ['rubric', 'prompt', 'submitmessage', 'hintprompt']: for child in ['rubric', 'prompt', 'submitmessage', 'hintprompt']:
add_child(child) add_child(child)
return elt return elt
\ No newline at end of file
<section class="${ section_name }"> <section id="self_assessment_${id}" class="self-assessment" data-ajax-url="${ajax_url}" data-id="${id}">
${ prompt } <div class="error"></div>
% if previous_answer_given: <div class="prompt">
<br/>Previous answer: ${ previous_answer }<br/> ${prompt}
% endif </div>
<textarea name="answer" id="answer" cols="50" rows="5"/>
<br/> <div>
<input type="button" value="Check" id ="show" name="show"/> <textarea name="answer" class="answer" cols="80" rows="20">${previous_answer|h}</textarea>
<p id="rubric"> </div>
</p>
<input type="hidden" id="ajax_url" name="ajax_url" url="${ ajax_url }"> <div class="rubric-wrapper"></div>
<input type="button" value="Submit" class="submit-button" name="show"/>
</section> </section>
<br/><br/>
\ No newline at end of file
<section class="${section_name}"> <div class="assessment">
<br/><br/><b>Rubric</b> <div class="rubric">
${ rubric } <h3>Self-assess your answer with this rubric:</h3>
Please assess your performance given the above rubric: <br/> ${rubric}
<select name="assessment" id="assessment"> </div>
<select name="assessment" class="assessment">
<option value="incorrect">Incorrect</option> <option value="incorrect">Incorrect</option>
<option value="correct">Correct</option> <option value="correct">Correct</option>
</select> </select>
<br/>
${ hint_prompt } <div class="hint-prompt">
<textarea name="hint" id="hint" cols="50" rows="5"/> ${hint_prompt}
<br/> </div>
<input type="button" value="Save" id="save" name="save"/> <textarea name="hint" class="hint" cols="50" rows="5"/>
<p id="save_message"></p>
<input type="hidden" id="ajax_url" name="ajax_url" url="${ ajax_url}"> <div class="save_message"></div>
</section> </div>
<br/><br/>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment