Commit 0df6c286 by Will Daly

Merge pull request #338 from edx/will/refactor-rubric-javascript

JS rubric refactor
parents d24adc15 36414f2c
...@@ -47,7 +47,76 @@ ...@@ -47,7 +47,76 @@
{ {
"template": "openassessmentblock/self/oa_self_assessment.html", "template": "openassessmentblock/self/oa_self_assessment.html",
"context": { "context": {
"rubric_criteria": [], "rubric_criteria": [
{
"name": "Criterion 1",
"prompt": "Prompt 1",
"order_num": 0,
"feedback": "optional",
"options": [
{
"order_num": 0,
"points": 0,
"name": "Poor"
},
{
"order_num": 1,
"points": 1,
"name": "Fair"
},
{
"order_num": 2,
"points": 2,
"name": "Good"
}
]
},
{
"name": "Criterion 2",
"prompt": "Prompt 2",
"order_num": 1,
"options": [
{
"order_num": 0,
"points": 0,
"name": "Poor"
},
{
"order_num": 1,
"points": 1,
"name": "Fair"
},
{
"order_num": 2,
"points": 2,
"name": "Good"
}
]
},
{
"name": "Criterion 3",
"prompt": "Prompt 3",
"order_num": 2,
"feedback": "optional",
"options": [
{
"order_num": 0,
"points": 0,
"name": "Poor"
},
{
"order_num": 1,
"points": 1,
"name": "Fair"
},
{
"order_num": 2,
"points": 2,
"name": "Good"
}
]
}
],
"self_submission": {} "self_submission": {}
}, },
"output": "oa_self_assessment.html" "output": "oa_self_assessment.html"
...@@ -198,4 +267,4 @@ ...@@ -198,4 +267,4 @@
"context": {}, "context": {},
"output": "oa_edit.html" "output": "oa_edit.html"
} }
] ]
\ No newline at end of file
...@@ -15,12 +15,12 @@ describe("OpenAssessment.BaseView", function() { ...@@ -15,12 +15,12 @@ describe("OpenAssessment.BaseView", function() {
grade: readFixtures("oa_grade_complete.html") grade: readFixtures("oa_grade_complete.html")
}; };
this.selfAssess = function(optionsSelected) { // Remember which fragments were requested
return $.Deferred(function(defer) { defer.resolve(); }).promise(); this.fragmentsLoaded = [];
};
this.render = function(component) { this.render = function(component) {
var server = this; var server = this;
this.fragmentsLoaded.push(component);
return $.Deferred(function(defer) { return $.Deferred(function(defer) {
defer.resolveWith(this, [server.fragments[component]]); defer.resolveWith(this, [server.fragments[component]]);
}).promise(); }).promise();
...@@ -66,24 +66,12 @@ describe("OpenAssessment.BaseView", function() { ...@@ -66,24 +66,12 @@ describe("OpenAssessment.BaseView", function() {
view = new OpenAssessment.BaseView(runtime, el, server); view = new OpenAssessment.BaseView(runtime, el, server);
}); });
it("Sends a self assessment to the server", function() { it("Loads each step", function() {
loadSubviews(function() {
spyOn(server, 'selfAssess').andCallThrough();
view.selfAssess();
expect(server.selfAssess).toHaveBeenCalled();
});
});
it("Displays error messages from self assessment to the user", function() {
var testError = 'Test failure contacting server message';
loadSubviews(function() { loadSubviews(function() {
/* stub our selfAssess to fail */ expect(server.fragmentsLoaded).toContain("submission");
spyOn(server, 'selfAssess').andCallFake(function(optionsSelected) { expect(server.fragmentsLoaded).toContain("self_assessment");
return $.Deferred(function(defer) { defer.rejectWith(server, [testError]); }).promise(); expect(server.fragmentsLoaded).toContain("peer_assessment");
}); expect(server.fragmentsLoaded).toContain("grade");
view.selfAssess();
expect(server.selfAssess).toHaveBeenCalled();
expect(view.getStepActionsErrorMessage()).toContain(testError);
}); });
}); });
......
...@@ -62,13 +62,13 @@ describe("OpenAssessment.PeerView", function() { ...@@ -62,13 +62,13 @@ describe("OpenAssessment.PeerView", function() {
optionsSelected['Criterion 1'] = 'Poor'; optionsSelected['Criterion 1'] = 'Poor';
optionsSelected['Criterion 2'] = 'Fair'; optionsSelected['Criterion 2'] = 'Fair';
optionsSelected['Criterion 3'] = 'Good'; optionsSelected['Criterion 3'] = 'Good';
view.optionsSelected(optionsSelected); view.rubric.optionsSelected(optionsSelected);
// Provide per-criterion feedback // Provide per-criterion feedback
var criterionFeedback = {}; var criterionFeedback = {};
criterionFeedback['Criterion 1'] = "You did a fair job"; criterionFeedback['Criterion 1'] = "You did a fair job";
criterionFeedback['Criterion 3'] = "You did a good job"; criterionFeedback['Criterion 3'] = "You did a good job";
view.criterionFeedback(criterionFeedback); view.rubric.criterionFeedback(criterionFeedback);
// Provide overall feedback // Provide overall feedback
var overallFeedback = "Good job!"; var overallFeedback = "Good job!";
......
...@@ -26,12 +26,12 @@ describe("OpenAssessment.SelfView", function() { ...@@ -26,12 +26,12 @@ describe("OpenAssessment.SelfView", function() {
this.showLoadError = function(msg) {}; this.showLoadError = function(msg) {};
this.toggleActionError = function(msg, step) {}; this.toggleActionError = function(msg, step) {};
this.setUpCollapseExpand = function(sel) {}; this.setUpCollapseExpand = function(sel) {};
this.loadAssessmentModules = function() {};
this.scrollToTop = function() {};
}; };
// Stub runtime
var runtime = {};
// Stubs // Stubs
var baseView = null;
var server = null; var server = null;
// View under test // View under test
...@@ -45,12 +45,22 @@ describe("OpenAssessment.SelfView", function() { ...@@ -45,12 +45,22 @@ describe("OpenAssessment.SelfView", function() {
// Create a new stub server // Create a new stub server
server = new StubServer(); server = new StubServer();
// Create the stub base view
baseView = new StubBaseView();
// Create the object under test // Create the object under test
var el = $("#openassessment").get(0); var el = $("#openassessment").get(0);
view = new OpenAssessment.BaseView(runtime, el, server); view = new OpenAssessment.SelfView(el, server, baseView);
view.installHandlers();
});
it("Sends a self assessment to the server", function() {
spyOn(server, 'selfAssess').andCallThrough();
view.selfAssess();
expect(server.selfAssess).toHaveBeenCalled();
}); });
it("re-enables the self assess button on error", function() { it("Re-enables the self assess button on error", function() {
// Simulate a server error // Simulate a server error
spyOn(server, 'selfAssess').andCallFake(function() { spyOn(server, 'selfAssess').andCallFake(function() {
expect(view.selfSubmitEnabled()).toBe(false); expect(view.selfSubmitEnabled()).toBe(false);
...@@ -59,6 +69,7 @@ describe("OpenAssessment.SelfView", function() { ...@@ -59,6 +69,7 @@ describe("OpenAssessment.SelfView", function() {
}).promise(); }).promise();
}); });
view.selfAssess(); view.selfAssess();
// Expect the submit button to have been re-enabled // Expect the submit button to have been re-enabled
expect(view.selfSubmitEnabled()).toBe(true); expect(view.selfSubmitEnabled()).toBe(true);
}); });
......
...@@ -15,8 +15,10 @@ OpenAssessment.BaseView = function(runtime, element, server) { ...@@ -15,8 +15,10 @@ OpenAssessment.BaseView = function(runtime, element, server) {
this.server = server; this.server = server;
this.responseView = new OpenAssessment.ResponseView(this.element, this.server, this); this.responseView = new OpenAssessment.ResponseView(this.element, this.server, this);
this.selfView = new OpenAssessment.SelfView(this.element, this.server, this);
this.peerView = new OpenAssessment.PeerView(this.element, this.server, this); this.peerView = new OpenAssessment.PeerView(this.element, this.server, this);
this.gradeView = new OpenAssessment.GradeView(this.element, this.server, this); this.gradeView = new OpenAssessment.GradeView(this.element, this.server, this);
// Staff only information about student progress. // Staff only information about student progress.
this.staffInfoView = new OpenAssessment.StaffInfoView(this.element, this.server, this); this.staffInfoView = new OpenAssessment.StaffInfoView(this.element, this.server, this);
}; };
...@@ -74,106 +76,11 @@ OpenAssessment.BaseView.prototype = { ...@@ -74,106 +76,11 @@ OpenAssessment.BaseView.prototype = {
**/ **/
loadAssessmentModules: function() { loadAssessmentModules: function() {
this.peerView.load(); this.peerView.load();
this.renderSelfAssessmentStep(); this.selfView.load();
this.gradeView.load(); this.gradeView.load();
}, },
/** /**
Render the self-assessment step.
**/
renderSelfAssessmentStep: function() {
var view = this;
this.server.render('self_assessment').done(
function(html) {
// Load the HTML
$('#openassessment__self-assessment', view.element).replaceWith(html);
var sel = $('#openassessment__self-assessment', view.element);
// Install a click handler for collapse/expand
view.setUpCollapseExpand(sel);
// Install a change handler for rubric options to enable/disable the submit button
$("#self-assessment--001__assessment", view.element).change(
function() {
var numChecked = $('input[type=radio]:checked', this).length;
var numAvailable = $('.field--radio.assessment__rubric__question', this).length;
$("#self-assessment--001__assessment__submit", view.element).toggleClass(
'is--disabled', numChecked != numAvailable
);
}
);
// Install a click handler for the submit button
sel.find('#self-assessment--001__assessment__submit').click(
function(eventObject) {
// Override default form submission
eventObject.preventDefault();
// Handle the click
view.selfAssess();
}
);
}
).fail(function(errMsg) {
view.showLoadError('self-assessment');
});
},
/**
Enable/disable the self assess button.
Check that whether the self assess button is enabled.
Args:
enabled (bool): If specified, set the state of the button.
Returns:
bool: Whether the button is enabled.
Examples:
>> view.selfSubmitEnabled(true); // enable the button
>> view.selfSubmitEnabled(); // check whether the button is enabled
>> true
**/
selfSubmitEnabled: function(enabled) {
var button = $('#self-assessment--001__assessment__submit', this.element);
if (typeof enabled === 'undefined') {
return !button.hasClass('is--disabled');
} else {
button.toggleClass('is--disabled', !enabled);
}
},
/**
Send a self-assessment to the server and update the view.
**/
selfAssess: function() {
// Retrieve self-assessment info from the DOM
var optionsSelected = {};
$("#self-assessment--001__assessment input[type=radio]:checked", this.element).each(
function(index, sel) {
optionsSelected[sel.name] = sel.value;
}
);
// Send the assessment to the server
var view = this;
view.toggleActionError('self', null);
view.selfSubmitEnabled(false);
this.server.selfAssess(optionsSelected).done(
function() {
view.loadAssessmentModules();
view.scrollToTop();
}
).fail(function(errMsg) {
view.toggleActionError('self', errMsg);
view.selfSubmitEnabled(true);
});
},
/**
Report an error to the user. Report an error to the user.
Args: Args:
...@@ -220,20 +127,6 @@ OpenAssessment.BaseView.prototype = { ...@@ -220,20 +127,6 @@ OpenAssessment.BaseView.prototype = {
$(container).toggleClass('has--error', true); $(container).toggleClass('has--error', true);
$(container + ' .step__status__value i').removeClass().addClass('ico icon-warning-sign'); $(container + ' .step__status__value i').removeClass().addClass('ico icon-warning-sign');
$(container + ' .step__status__value .copy').html(gettext('Unable to Load')); $(container + ' .step__status__value .copy').html(gettext('Unable to Load'));
},
/**
* Get the contents of the Step Actions error message box, for unit test validation.
*
* Step Actions are the UX-level parts of the student interaction flow -
* Submission, Peer Assessment, and Self Assessment. Since steps are mutually
* exclusive, only one error box should be rendered on screen at a time.
*
* Returns:
* One HTML string
*/
getStepActionsErrorMessage: function() {
return $('.step__actions .message__content').html();
} }
}; };
......
...@@ -13,6 +13,7 @@ OpenAssessment.PeerView = function(element, server, baseView) { ...@@ -13,6 +13,7 @@ OpenAssessment.PeerView = function(element, server, baseView) {
this.element = element; this.element = element;
this.server = server; this.server = server;
this.baseView = baseView; this.baseView = baseView;
this.rubric = null;
}; };
...@@ -27,7 +28,7 @@ OpenAssessment.PeerView.prototype = { ...@@ -27,7 +28,7 @@ OpenAssessment.PeerView.prototype = {
function(html) { function(html) {
// Load the HTML and install event handlers // Load the HTML and install event handlers
$('#openassessment__peer-assessment', view.element).replaceWith(html); $('#openassessment__peer-assessment', view.element).replaceWith(html);
view.installHandlers(); view.installHandlers(false);
} }
).fail(function(errMsg) { ).fail(function(errMsg) {
view.showLoadError('peer-assessment'); view.showLoadError('peer-assessment');
...@@ -46,7 +47,7 @@ OpenAssessment.PeerView.prototype = { ...@@ -46,7 +47,7 @@ OpenAssessment.PeerView.prototype = {
function(html) { function(html) {
// Load the HTML and install event handlers // Load the HTML and install event handlers
$('#openassessment__peer-assessment', view.element).replaceWith(html); $('#openassessment__peer-assessment', view.element).replaceWith(html);
view.installHandlersForContinuedAssessment(); view.installHandlers(true);
} }
).fail(function(errMsg) { ).fail(function(errMsg) {
view.showLoadError('peer-assessment'); view.showLoadError('peer-assessment');
...@@ -55,22 +56,30 @@ OpenAssessment.PeerView.prototype = { ...@@ -55,22 +56,30 @@ OpenAssessment.PeerView.prototype = {
/** /**
Install event handlers for the view. Install event handlers for the view.
Args:
isContinuedAssessment (boolean): If true, we are in "continued grading" mode,
meaning that the user is continuing to grade even though she has met
the requirements.
**/ **/
installHandlers: function() { installHandlers: function(isContinuedAssessment) {
var sel = $('#openassessment__peer-assessment', this.element); var sel = $('#openassessment__peer-assessment', this.element);
var view = this; var view = this;
// Install a click handler for collapse/expand // Install a click handler for collapse/expand
this.baseView.setUpCollapseExpand(sel, $.proxy(view.loadContinuedAssessment, view)); this.baseView.setUpCollapseExpand(sel, $.proxy(view.loadContinuedAssessment, view));
// Initialize the rubric
var rubricSelector = $("#peer-assessment--001__assessment", this.element);
if (rubricSelector.size() > 0) {
var rubricElement = rubricSelector.get(0);
this.rubric = new OpenAssessment.Rubric(rubricElement);
}
// Install a change handler for rubric options to enable/disable the submit button // Install a change handler for rubric options to enable/disable the submit button
sel.find("#peer-assessment--001__assessment").change( if (this.rubric !== null) {
function() { this.rubric.canSubmitCallback($.proxy(view.peerSubmitEnabled, view));
var numChecked = $('input[type=radio]:checked', this).length; }
var numAvailable = $('.field--radio.assessment__rubric__question', this).length;
view.peerSubmitEnabled(numChecked == numAvailable);
}
);
// Install a click handler for assessment // Install a click handler for assessment
sel.find('#peer-assessment--001__assessment__submit').click( sel.find('#peer-assessment--001__assessment__submit').click(
...@@ -79,38 +88,8 @@ OpenAssessment.PeerView.prototype = { ...@@ -79,38 +88,8 @@ OpenAssessment.PeerView.prototype = {
eventObject.preventDefault(); eventObject.preventDefault();
// Handle the click // Handle the click
view.peerAssess(); if (!isContinuedAssessment) { view.peerAssess(); }
} else { view.continuedPeerAssess(); }
);
},
/**
Install event handlers for the continued grading version of the view.
**/
installHandlersForContinuedAssessment: function() {
var sel = $('#openassessment__peer-assessment', this.element);
var view = this;
// Install a click handler for collapse/expand
this.baseView.setUpCollapseExpand(sel);
// Install a click handler for assessment
sel.find('#peer-assessment--001__assessment__submit').click(
function(eventObject) {
// Override default form submission
eventObject.preventDefault();
// Handle the click
view.continuedPeerAssess();
}
);
// Install a change handler for rubric options to enable/disable the submit button
sel.find("#peer-assessment--001__assessment").change(
function() {
var numChecked = $('input[type=radio]:checked', this).length;
var numAvailable = $('.field--radio.assessment__rubric__question', this).length;
view.peerSubmitEnabled(numChecked == numAvailable);
} }
); );
}, },
...@@ -168,106 +147,6 @@ OpenAssessment.PeerView.prototype = { ...@@ -168,106 +147,6 @@ OpenAssessment.PeerView.prototype = {
}, },
/** /**
Get or set overall feedback on the submission.
Args:
overallFeedback (string or undefined): The overall feedback text (optional).
Returns:
string or undefined
Example usage:
>>> view.overallFeedback('Good job!'); // Set the feedback text
>>> view.overallFeedback(); // Retrieve the feedback text
'Good job!'
**/
overallFeedback: function(overallFeedback) {
var selector = '#assessment__rubric__question--feedback__value';
if (typeof overallFeedback === 'undefined') {
return $(selector, this.element).val();
}
else {
$(selector, this.element).val(overallFeedback);
}
},
/**
Get or set per-criterion feedback.
Args:
criterionFeedback (object literal or undefined):
Map of criterion names to feedback strings.
Returns:
object literal or undefined
Example usage:
>>> view.criterionFeedback({'ideas': 'Good ideas'}); // Set per-criterion feedback
>>> view.criterionFeedback(); // Retrieve criterion feedback
{'ideas': 'Good ideas'}
**/
criterionFeedback: function(criterionFeedback) {
var selector = '#peer-assessment--001__assessment textarea.answer__value';
var feedback = {};
$(selector, this.element).each(
function(index, sel) {
if (typeof criterionFeedback !== 'undefined') {
$(sel).val(criterionFeedback[sel.name]);
feedback[sel.name] = criterionFeedback[sel.name];
}
else {
feedback[sel.name] = $(sel).val();
}
}
);
return feedback;
},
/**
Get or set the options selected in the rubric.
Args:
optionsSelected (object literal or undefined):
Map of criterion names to option values.
Returns:
object literal or undefined
Example usage:
>>> view.optionsSelected({'ideas': 'Good'}); // Set the criterion option
>>> view.optionsSelected(); // Retrieve the options selected
{'ideas': 'Good'}
**/
optionsSelected: function(optionsSelected) {
var selector = "#peer-assessment--001__assessment input[type=radio]";
if (typeof optionsSelected === 'undefined') {
var options = {};
$(selector + ":checked", this.element).each(
function(index, sel) {
options[sel.name] = sel.value;
}
);
return options;
}
else {
// Uncheck all the options
$(selector, this.element).prop('checked', false);
// Check the selected options
$(selector, this.element).each(function(index, sel) {
if (optionsSelected.hasOwnProperty(sel.name)) {
if (sel.value == optionsSelected[sel.name]) {
$(sel).prop('checked', true);
}
}
});
}
},
/**
Common peer assessment request building, used for all types of peer assessments. Common peer assessment request building, used for all types of peer assessments.
Args: Args:
...@@ -283,8 +162,8 @@ OpenAssessment.PeerView.prototype = { ...@@ -283,8 +162,8 @@ OpenAssessment.PeerView.prototype = {
// Pull the assessment info from the DOM and send it to the server // Pull the assessment info from the DOM and send it to the server
this.server.peerAssess( this.server.peerAssess(
this.optionsSelected(), this.rubric.optionsSelected(),
this.criterionFeedback(), this.rubric.criterionFeedback(),
this.overallFeedback() this.overallFeedback()
).done( ).done(
successFunction successFunction
...@@ -293,4 +172,29 @@ OpenAssessment.PeerView.prototype = { ...@@ -293,4 +172,29 @@ OpenAssessment.PeerView.prototype = {
view.peerSubmitEnabled(true); view.peerSubmitEnabled(true);
}); });
}, },
/**
Get or set overall feedback on the submission.
Args:
overallFeedback (string or undefined): The overall feedback text (optional).
Returns:
string or undefined
Example usage:
>>> view.overallFeedback('Good job!'); // Set the feedback text
>>> view.overallFeedback(); // Retrieve the feedback text
'Good job!'
**/
overallFeedback: function(overallFeedback) {
var selector = '#assessment__rubric__question--feedback__value';
if (typeof overallFeedback === 'undefined') {
return $(selector, this.element).val();
}
else {
$(selector, this.element).val(overallFeedback);
}
}
}; };
/**
Interface for reading and modifying a rubric.
Args:
element (DOM element): The DOM element representing the rubric.
Returns:
OpenAssessment.Rubric
**/
OpenAssessment.Rubric = function(element) {
this.element = element;
};
OpenAssessment.Rubric.prototype = {
/**
Get or set per-criterion feedback.
Args:
criterionFeedback (object literal or undefined):
Map of criterion names to feedback strings.
Returns:
object literal or undefined
Example usage:
>>> view.criterionFeedback({'ideas': 'Good ideas'}); // Set per-criterion feedback
>>> view.criterionFeedback(); // Retrieve criterion feedback
{'ideas': 'Good ideas'}
**/
criterionFeedback: function(criterionFeedback) {
var selector = 'textarea.answer__value';
var feedback = {};
$(selector, this.element).each(
function(index, sel) {
if (typeof criterionFeedback !== 'undefined') {
$(sel).val(criterionFeedback[sel.name]);
feedback[sel.name] = criterionFeedback[sel.name];
}
else {
feedback[sel.name] = $(sel).val();
}
}
);
return feedback;
},
/**
Get or set the options selected in the rubric.
Args:
optionsSelected (object literal or undefined):
Map of criterion names to option values.
Returns:
object literal or undefined
Example usage:
>>> view.optionsSelected({'ideas': 'Good'}); // Set the criterion option
>>> view.optionsSelected(); // Retrieve the options selected
{'ideas': 'Good'}
**/
optionsSelected: function(optionsSelected) {
var selector = "input[type=radio]";
if (typeof optionsSelected === 'undefined') {
var options = {};
$(selector + ":checked", this.element).each(
function(index, sel) {
options[sel.name] = sel.value;
}
);
return options;
}
else {
// Uncheck all the options
$(selector, this.element).prop('checked', false);
// Check the selected options
$(selector, this.element).each(function(index, sel) {
if (optionsSelected.hasOwnProperty(sel.name)) {
if (sel.value == optionsSelected[sel.name]) {
$(sel).prop('checked', true);
}
}
});
}
},
/**
Install a callback handler to be notified when
the the user has selected options for all criteria and can submit the assessment.
Args:
callback (function): Callback function that accepts one argument, a boolean indicating
whether the user is allowed to submit the rubric.
**/
canSubmitCallback: function(callback) {
$(this.element).change(
function() {
var numChecked = $('input[type=radio]:checked', this).length;
var numAvailable = $('.field--radio.assessment__rubric__question', this).length;
var canSubmit = numChecked == numAvailable;
callback(canSubmit);
}
);
}
};
/**
Interface for self assessment view.
Args:
element (DOM element): The DOM element representing the XBlock.
server (OpenAssessment.Server): The interface to the XBlock server.
baseView (OpenAssessment.BaseView): Container view.
Returns:
OpenAssessment.SelfView
**/
OpenAssessment.SelfView = function(element, server, baseView) {
this.element = element;
this.server = server;
this.baseView = baseView;
this.rubric = null;
};
OpenAssessment.SelfView.prototype = {
/**
Load the self assessment view.
**/
load: function() {
var view = this;
this.server.render('self_assessment').done(
function(html) {
// Load the HTML and install event handlers
$('#openassessment__self-assessment', view.element).replaceWith(html);
view.installHandlers();
}
).fail(function(errMsg) {
view.showLoadError('self-assessment');
});
},
/**
Install event handlers for the view.
**/
installHandlers: function() {
var view = this;
var sel = $('#openassessment__self-assessment', view.element);
// Install a click handler for collapse/expand
this.baseView.setUpCollapseExpand(sel);
// Initialize the rubric
var rubricSelector = $("#self-assessment--001__assessment", this.element);
if (rubricSelector.size() > 0) {
var rubricElement = rubricSelector.get(0);
this.rubric = new OpenAssessment.Rubric(rubricElement);
}
// Install a change handler for rubric options to enable/disable the submit button
if (this.rubric !== null) {
this.rubric.canSubmitCallback($.proxy(this.selfSubmitEnabled, this));
}
// Install a click handler for the submit button
sel.find('#self-assessment--001__assessment__submit').click(
function(eventObject) {
// Override default form submission
eventObject.preventDefault();
// Handle the click
view.selfAssess();
}
);
},
/**
Enable/disable the self assess button.
Check that whether the self assess button is enabled.
Args:
enabled (bool): If specified, set the state of the button.
Returns:
bool: Whether the button is enabled.
Examples:
>> view.selfSubmitEnabled(true); // enable the button
>> view.selfSubmitEnabled(); // check whether the button is enabled
>> true
**/
selfSubmitEnabled: function(enabled) {
var button = $('#self-assessment--001__assessment__submit', this.element);
if (typeof enabled === 'undefined') {
return !button.hasClass('is--disabled');
} else {
button.toggleClass('is--disabled', !enabled);
}
},
/**
Send a self-assessment to the server and update the view.
**/
selfAssess: function() {
// Send the assessment to the server
var view = this;
var baseView = this.baseView;
baseView.toggleActionError('self', null);
view.selfSubmitEnabled(false);
var options = this.rubric.optionsSelected();
this.server.selfAssess(options).done(
function() {
baseView.loadAssessmentModules();
baseView.scrollToTop();
}
).fail(function(errMsg) {
baseView.toggleActionError('self', errMsg);
view.selfSubmitEnabled(true);
});
}
};
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