Commit b69f9925 by Usman Khalid

Studio editor can edit multiple prompts in student training step.

TNL-708
parent 8d5a842e
...@@ -33,6 +33,11 @@ ...@@ -33,6 +33,11 @@
<ol id="openassessment_training_example_criterion_template" class="is--hidden"> <ol id="openassessment_training_example_criterion_template" class="is--hidden">
{% include "openassessmentblock/edit/oa_training_example_criterion.html" %} {% include "openassessmentblock/edit/oa_training_example_criterion.html" %}
</ol> </ol>
<ol id="openassessment_training_example_part_template" class="is--hidden">
<li class="openassessment_training_example_essay_part">
<textarea maxlength="100000"></textarea>
</li>
</ol>
</div> </div>
</li> </li>
......
...@@ -28,7 +28,13 @@ ...@@ -28,7 +28,13 @@
<div class="openassessment_training_example_essay_wrapper"> <div class="openassessment_training_example_essay_wrapper">
<h2>{% trans "Response" %}</h2> <h2>{% trans "Response" %}</h2>
<textarea class="openassessment_training_example_essay" maxlength="100000">{{ example.answer }}</textarea> <ol class="openassessment_training_example_essay">
{% for part in example.answer.parts %}
<li class="openassessment_training_example_essay_part">
<textarea maxlength="100000">{{ part.text }}</textarea>
</li>
{% endfor %}
</ol>
</div> </div>
</div> </div>
</li> </li>
......
...@@ -88,7 +88,7 @@ EDITOR_UPDATE_SCHEMA = Schema({ ...@@ -88,7 +88,7 @@ EDITOR_UPDATE_SCHEMA = Schema({
'must_be_graded_by': All(int, Range(min=0)), 'must_be_graded_by': All(int, Range(min=0)),
'examples': [ 'examples': [
Schema({ Schema({
Required('answer'): utf8_validator, Required('answer'): [utf8_validator],
Required('options_selected'): [ Required('options_selected'): [
Schema({ Schema({
Required('criterion'): utf8_validator, Required('criterion'): utf8_validator,
......
...@@ -112,9 +112,34 @@ OpenAssessment.Prompt.prototype = { ...@@ -112,9 +112,34 @@ OpenAssessment.Prompt.prototype = {
return OpenAssessment.Fields.stringField(sel, text); return OpenAssessment.Fields.stringField(sel, text);
}, },
addHandler: function (){},
addEventListeners: function() {}, addEventListeners: function() {},
removeHandler: function() {},
/**
Hook into the event handler for addition of a prompt.
*/
addHandler: function (){
this.notifier.notificationFired(
"promptAdd",
{
"index": this.element.index()
}
);
},
/**
Hook into the event handler for removal of a prompt.
*/
removeHandler: function (){
this.notifier.notificationFired(
"promptRemove",
{
"index": this.element.index()
}
);
},
updateHandler: function() {}, updateHandler: function() {},
/** /**
...@@ -588,7 +613,7 @@ OpenAssessment.RubricCriterion.prototype = { ...@@ -588,7 +613,7 @@ OpenAssessment.RubricCriterion.prototype = {
OpenAssessment.TrainingExample = function(element){ OpenAssessment.TrainingExample = function(element){
this.element = element; this.element = element;
this.criteria = $(".openassessment_training_example_criterion_option", this.element); this.criteria = $(".openassessment_training_example_criterion_option", this.element);
this.answer = $('.openassessment_training_example_essay', this.element).first(); this.answer = $('.openassessment_training_example_essay_part textarea', this.element)
}; };
OpenAssessment.TrainingExample.prototype = { OpenAssessment.TrainingExample.prototype = {
...@@ -609,7 +634,9 @@ OpenAssessment.TrainingExample.prototype = { ...@@ -609,7 +634,9 @@ OpenAssessment.TrainingExample.prototype = {
).get(); ).get();
return { return {
answer: this.answer.prop('value'), answer: this.answer.map(function() {
return $(this).prop('value');
}).get(),
options_selected: optionsSelected options_selected: optionsSelected
}; };
}, },
......
...@@ -25,9 +25,14 @@ OpenAssessment.StudioView = function(runtime, element, server) { ...@@ -25,9 +25,14 @@ OpenAssessment.StudioView = function(runtime, element, server) {
// Initialize the validation alert // Initialize the validation alert
this.alert = new OpenAssessment.ValidationAlert().install(); this.alert = new OpenAssessment.ValidationAlert().install();
var studentTrainingListener = new OpenAssessment.StudentTrainingListener();
// Initialize the prompt tab view // Initialize the prompt tab view
this.promptsView = new OpenAssessment.EditPromptsView( this.promptsView = new OpenAssessment.EditPromptsView(
$("#oa_prompts_editor_wrapper", this.element).get(0) $("#oa_prompts_editor_wrapper", this.element).get(0),
new OpenAssessment.Notifier([
studentTrainingListener
])
); );
// Initialize the settings tab view // Initialize the settings tab view
...@@ -57,7 +62,7 @@ OpenAssessment.StudioView = function(runtime, element, server) { ...@@ -57,7 +62,7 @@ OpenAssessment.StudioView = function(runtime, element, server) {
this.rubricView = new OpenAssessment.EditRubricView( this.rubricView = new OpenAssessment.EditRubricView(
$("#oa_rubric_editor_wrapper", this.element).get(0), $("#oa_rubric_editor_wrapper", this.element).get(0),
new OpenAssessment.Notifier([ new OpenAssessment.Notifier([
new OpenAssessment.StudentTrainingListener() studentTrainingListener
]) ])
); );
......
...@@ -421,7 +421,7 @@ OpenAssessment.EditStudentTrainingView.prototype = { ...@@ -421,7 +421,7 @@ OpenAssessment.EditStudentTrainingView.prototype = {
{ {
examples: [ examples: [
{ {
answer: "I love pokemon", answer: ("I love pokemon 1", "I love pokemon 2"),
options_selected: [ options_selected: [
{ {
criterion: "brevity", criterion: "brevity",
......
/** /**
Dynamically update student training examples based on Dynamically update student training examples based on
changes to the rubric. changes to the prompts or the rubric.
**/ **/
OpenAssessment.StudentTrainingListener = function() { OpenAssessment.StudentTrainingListener = function() {
this.element = $('#oa_student_training_editor'); this.element = $('#oa_student_training_editor');
...@@ -8,6 +8,28 @@ OpenAssessment.StudentTrainingListener = function() { ...@@ -8,6 +8,28 @@ OpenAssessment.StudentTrainingListener = function() {
}; };
OpenAssessment.StudentTrainingListener.prototype = { OpenAssessment.StudentTrainingListener.prototype = {
/**
Add a answer part in the training examples when a prompt is added.
*/
promptAdd: function(data) {
var view = this.element;
var essay_part = $("#openassessment_training_example_part_template")
.children().first()
.clone()
.removeAttr('id')
.toggleClass('is--hidden', false)
.appendTo(".openassessment_training_example_essay", view);
},
/**
Remove the answer part in the training examples when a prompt is removed.
*/
promptRemove: function(data) {
var view = this.element;
$(".openassessment_training_example_essay li:nth-child(" + (data.index + 1) + ")", view).remove();
},
/** /**
Event handler for updating training examples when a criterion option has Event handler for updating training examples when a criterion option has
been updated. been updated.
......
...@@ -8,7 +8,7 @@ Returns: ...@@ -8,7 +8,7 @@ Returns:
OpenAssessment.EditPromptsView OpenAssessment.EditPromptsView
**/ **/
OpenAssessment.EditPromptsView = function(element) { OpenAssessment.EditPromptsView = function(element, notifier) {
this.element = element; this.element = element;
this.promptsContainer = new OpenAssessment.Container( this.promptsContainer = new OpenAssessment.Container(
...@@ -17,7 +17,8 @@ OpenAssessment.EditPromptsView = function(element) { ...@@ -17,7 +17,8 @@ OpenAssessment.EditPromptsView = function(element) {
templateElement: $("#openassessment_prompt_template", this.element).get(0), templateElement: $("#openassessment_prompt_template", this.element).get(0),
addButtonElement: $("#openassessment_prompts_add_prompt", this.element).get(0), addButtonElement: $("#openassessment_prompts_add_prompt", this.element).get(0),
removeButtonClass: "openassessment_prompt_remove_button", removeButtonClass: "openassessment_prompt_remove_button",
containerItemClass: "openassessment_prompt" containerItemClass: "openassessment_prompt",
notifier: notifier
} }
); );
this.promptsContainer.addEventListeners(); this.promptsContainer.addEventListeners();
......
...@@ -14,7 +14,7 @@ from xblock.fields import List, Scope ...@@ -14,7 +14,7 @@ from xblock.fields import List, Scope
from xblock.fragment import Fragment from xblock.fragment import Fragment
from openassessment.xblock.defaults import DEFAULT_EDITOR_ASSESSMENTS_ORDER, DEFAULT_RUBRIC_FEEDBACK_TEXT from openassessment.xblock.defaults import DEFAULT_EDITOR_ASSESSMENTS_ORDER, DEFAULT_RUBRIC_FEEDBACK_TEXT
from openassessment.xblock.validation import validator from openassessment.xblock.validation import validator
from openassessment.xblock.data_conversion import create_rubric_dict, make_django_template_key from openassessment.xblock.data_conversion import create_rubric_dict, make_django_template_key, update_assessments_format
from openassessment.xblock.schema import EDITOR_UPDATE_SCHEMA from openassessment.xblock.schema import EDITOR_UPDATE_SCHEMA
from openassessment.xblock.resolve_dates import resolve_dates from openassessment.xblock.resolve_dates import resolve_dates
from openassessment.xblock.xml import serialize_examples_to_xml_str, parse_examples_from_xml_str from openassessment.xblock.xml import serialize_examples_to_xml_str, parse_examples_from_xml_str
...@@ -191,6 +191,10 @@ class StudioMixin(object): ...@@ -191,6 +191,10 @@ class StudioMixin(object):
)} )}
# This is where we default to EASE for problems which are edited in the GUI # This is where we default to EASE for problems which are edited in the GUI
assessment['algorithm_id'] = 'ease' assessment['algorithm_id'] = 'ease'
if assessment['name'] == 'student-training':
for example in assessment['examples']:
example['answer'] = {'parts': [{'text': text} for text in example['answer']]}
xblock_validator = validator(self, self._) xblock_validator = validator(self, self._)
success, msg = xblock_validator( success, msg = xblock_validator(
...@@ -269,13 +273,20 @@ class StudioMixin(object): ...@@ -269,13 +273,20 @@ class StudioMixin(object):
# could be accomplished within the template, we are opting to remove logic from the template. # could be accomplished within the template, we are opting to remove logic from the template.
student_training_module = self.get_assessment_module('student-training') student_training_module = self.get_assessment_module('student-training')
student_training_template = {'answer': ""} student_training_template = {
'answer': {
'parts': [
{'text': ''} for prompt in self.prompts
]
}
}
criteria_list = copy.deepcopy(self.rubric_criteria_with_labels) criteria_list = copy.deepcopy(self.rubric_criteria_with_labels)
for criterion in criteria_list: for criterion in criteria_list:
criterion['option_selected'] = "" criterion['option_selected'] = ""
student_training_template['criteria'] = criteria_list student_training_template['criteria'] = criteria_list
if student_training_module: if student_training_module:
student_training_module = update_assessments_format([student_training_module])[0]
example_list = [] example_list = []
# Adds each example to a modified version of the student training module dictionary. # Adds each example to a modified version of the student training module dictionary.
for example in student_training_module['examples']: for example in student_training_module['examples']:
......
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