Commit aba4abd5 by Andy Armstrong

Miscellaneous small improvements

* Bump version numbers
* Introduce JSCS style validation
* Address style failures
parent 582a4a4f
{
"preset": "google",
// edX specific rules
"validateIndentation": 4,
"maximumLineLength": 120,
"disallowMultipleVarDecl": false,
"requireCamelCaseOrUpperCaseIdentifiers": {"ignoreProperties": true},
// Temporary overrides until we clean up further...
"validateQuoteMarks": null, // We should standardize on single quotes
"disallowKeywordsOnNewLine": [] // Other repos disallow lines starting with "else"
}
......@@ -14,7 +14,6 @@
"forin" : true, // Requires all for in loops to filter object's items.
"freeze" : true, // Prohibits overwriting prototypes of native objects such as Array, Date and so on.
"immed" : true, // Prohibits the use of immediate function invocations without wrapping them in parentheses.
// "indent" : 4, // Enforces specific tab width for your code. Has no effect when "white" option is not used.
"latedef" : "nofunc", // Prohibits the use of a variable before it was defined. Setting this option to "nofunc" will allow function declarations to be ignored.
"newcap" : true, // Requires you to capitalize names of constructor functions.
"noarg" : true, // Prohibits the use of arguments.caller and arguments.callee.
......@@ -27,11 +26,6 @@
"unused" : true, // Warns when you define and never use your variables.
"strict" : false, // Requires all functions to run in ECMAScript 5's strict mode.
"trailing" : true, // Makes it an error to leave a trailing whitespace in your code.
"maxlen" : 120, // Lets you set the maximum length of a line.
//"maxparams" : 4, // Lets you set the max number of formal parameters allowed per function.
//"maxdepth" : 4, // Lets you control how nested do you want your blocks to be.
//"maxstatements" : 4, // Lets you set the max number of statements allowed per function.
//"maxcomplexity" : 4, // Lets you control cyclomatic complexity throughout your code.
// == Relaxing Options ================================================
......
......@@ -21,7 +21,6 @@ install-python:
./scripts/install-python.sh
install-js:
npm config set loglevel warn
npm install
install-nltk-data:
......@@ -43,6 +42,7 @@ install-test:
pip install -q -r requirements/test.txt
install-sys-requirements: install-system install-node
npm config set loglevel warn
install-dev:
gem install sass
......@@ -52,9 +52,12 @@ install: install-wheels install-python install-js install-nltk-data install-test
quality:
jshint openassessment/xblock/static/js/src -c .jshintrc --verbose
./node_modules/jscs/bin/jscs openassessment/xblock/static/js/src --verbose
test: quality
./scripts/test.sh
test: quality test-python test-js
test-python:
./scripts/test-python.sh
render-templates:
./scripts/render-templates.sh
......@@ -65,6 +68,8 @@ test-js: render-templates
test-js-debug: render-templates
./scripts/js-debugger.sh
test-sandbox: test-acceptance test-a11y
test-acceptance:
./scripts/test-acceptance.sh tests
......
......@@ -2,7 +2,7 @@
Tests for the Openassessment Container Object.
**/
describe("OpenAssessment.Container", function () {
describe("OpenAssessment.Container", function() {
var counter = 0;
var StubContainerItem = function(element) {
......@@ -38,7 +38,7 @@ describe("OpenAssessment.Container", function () {
);
};
beforeEach(function () {
beforeEach(function() {
// Reset the counter before each test
counter = 0;
......
......@@ -174,7 +174,7 @@ describe("OpenAssessment edit assessment views", function() {
});
it("enables and disables", function() { testEnableAndDisable(view); });
it("loads a description", function () {
it("loads a description", function() {
// This assumes a particular structure of the DOM,
// which is set by the HTML fixture.
expect(view.description()).toEqual({
......@@ -192,7 +192,7 @@ describe("OpenAssessment edit assessment views", function() {
});
});
it("modifies a description", function () {
it("modifies a description", function() {
view.exampleContainer.add();
expect(view.description()).toEqual({
examples: [
......
......@@ -429,7 +429,7 @@ describe("OpenAssessment.StudentTrainingListenerWithTrainingExamples", function(
});
it("adds a criterion and an option, then adds a training example", function (){
it("adds a criterion and an option, then adds a training example", function(){
// Initial state, set by the fixture
assertExampleLabels(
listener.examplesOptionsLabels(),
......
......@@ -208,7 +208,7 @@ describe("OpenAssessment.EditRubricView", function() {
});
});
it("validates option points", function () {
it("validates option points", function() {
// Test that a particular value is marked as valid/invalid
var testValidateOptionPoints = function(value, isValid) {
var option = view.getOptionItem(0, 0);
......
......@@ -27,7 +27,6 @@ OpenAssessment.BaseView = function(runtime, element, server, data) {
this.staffAreaView = new OpenAssessment.StaffAreaView(this.element, this.server, this);
};
OpenAssessment.BaseView.prototype = {
/**
......@@ -39,7 +38,7 @@ OpenAssessment.BaseView.prototype = {
*/
scrollToTop: function() {
if ($.scrollTo instanceof Function) {
$(window).scrollTo($("#openassessment__steps", this.element), 800, {offset:-50});
$(window).scrollTo($("#openassessment__steps", this.element), 800, {offset: -50});
}
},
......@@ -49,8 +48,8 @@ OpenAssessment.BaseView.prototype = {
Args:
parentSel (JQuery selector): CSS selector for the container element.
**/
setUpCollapseExpand: function (parentSel) {
parentSel.on('click', '.ui-toggle-visibility__control', function (eventData) {
setUpCollapseExpand: function(parentSel) {
parentSel.on('click', '.ui-toggle-visibility__control', function(eventData) {
var sel = $(eventData.target).closest('.ui-toggle-visibility');
sel.toggleClass('is--collapsed');
}
......
......@@ -15,7 +15,6 @@ OpenAssessment.GradeView = function(element, server, baseView) {
this.baseView = baseView;
};
OpenAssessment.GradeView.prototype = {
/**
Load the grade view.
......
......@@ -15,7 +15,6 @@ OpenAssessment.LeaderboardView = function(element, server, baseView) {
this.baseView = baseView;
};
OpenAssessment.LeaderboardView.prototype = {
/**
Load the leaderboard view.
......@@ -32,5 +31,5 @@ OpenAssessment.LeaderboardView.prototype = {
).fail(function(errMsg) {
baseView.showLoadError('leaderboard', errMsg);
});
},
}
};
......@@ -31,5 +31,5 @@ OpenAssessment.MessageView.prototype = {
).fail(function(errMsg) {
baseView.showLoadError('message', errMsg);
});
}
}
};
......@@ -16,7 +16,6 @@ OpenAssessment.PeerView = function(element, server, baseView) {
this.rubric = null;
};
OpenAssessment.PeerView.prototype = {
/**
......@@ -184,7 +183,7 @@ OpenAssessment.PeerView.prototype = {
Common peer assessment request building, used for all types of peer assessments.
Args:
successFunction (function): The function called if the request is
successfunction(function): The function called if the request is
successful. This varies based on the type of request to submit
a peer assessment.
......
/**
Interface for response (submission) view.
Args:
element (DOM element): The DOM element representing the XBlock.
server (OpenAssessment.Server): The interface to the XBlock server.
fileUploader (OpenAssessment.FileUploader): File uploader instance.
baseView (OpenAssessment.BaseView): Container view.
data (Object): The data object passed from XBlock backend.
Returns:
OpenAssessment.ResponseView
**/
Interface for response (submission) view.
Args:
element (DOM element): The DOM element representing the XBlock.
server (OpenAssessment.Server): The interface to the XBlock server.
fileUploader (OpenAssessment.FileUploader): File uploader instance.
baseView (OpenAssessment.BaseView): Container view.
data (Object): The data object passed from XBlock backend.
Returns:
OpenAssessment.ResponseView
**/
OpenAssessment.ResponseView = function(element, server, fileUploader, baseView, data) {
this.element = element;
this.server = server;
......@@ -26,7 +26,6 @@ OpenAssessment.ResponseView = function(element, server, fileUploader, baseView,
this.fileUploaded = false;
};
OpenAssessment.ResponseView.prototype = {
// Milliseconds between checks for whether we should autosave.
......@@ -40,8 +39,8 @@ OpenAssessment.ResponseView.prototype = {
MAX_FILE_SIZE: 5242880,
/**
Load the response (submission) view.
**/
Load the response (submission) view.
**/
load: function() {
var view = this;
this.server.render('submission').done(
......@@ -58,8 +57,8 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Install event handlers for the view.
**/
Install event handlers for the view.
**/
installHandlers: function() {
var sel = $('#openassessment__response', this.element);
var view = this;
......@@ -104,13 +103,13 @@ OpenAssessment.ResponseView.prototype = {
function(eventObject) {
eventObject.preventDefault();
// extract typed-in response and replace newline with br
var preview_text = sel.find('.submission__answer__part__text__value').val();
var preview_container = sel.find('#preview_content');
preview_container.html(preview_text.replace(/\r\n|\r|\n/g,"<br />"));
var previewText = sel.find('.submission__answer__part__text__value').val();
var previewContainer = sel.find('#preview_content');
previewContainer.html(previewText.replace(/\r\n|\r|\n/g,"<br />"));
// Render in mathjax
sel.find('#submission__preview__item').show();
MathJax.Hub.Queue(['Typeset', MathJax.Hub, preview_container[0]]);
MathJax.Hub.Queue(['Typeset', MathJax.Hub, previewContainer[0]]);
}
);
......@@ -126,12 +125,12 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Enable or disable autosave polling.
Enable or disable autosave polling.
Args:
enabled (boolean): If true, start polling for whether we need to autosave.
Otherwise, stop polling.
**/
Args:
enabled (boolean): If true, start polling for whether we need to autosave.
Otherwise, stop polling.
**/
setAutoSaveEnabled: function(enabled) {
if (enabled) {
if (this.autoSaveTimerId === null) {
......@@ -149,20 +148,20 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Enable/disable the submit button.
Check that whether the submit button is enabled.
Enable/disable the submit button.
Check that whether the submit button is enabled.
Args:
enabled (bool): If specified, set the state of the button.
Args:
enabled (bool): If specified, set the state of the button.
Returns:
bool: Whether the button is enabled.
Returns:
bool: Whether the button is enabled.
Examples:
>> view.submitEnabled(true); // enable the button
>> view.submitEnabled(); // check whether the button is enabled
>> true
**/
Examples:
>> view.submitEnabled(true); // enable the button
>> view.submitEnabled(); // check whether the button is enabled
>> true
**/
submitEnabled: function(enabled) {
var sel = $('#step--response__submit', this.element);
if (typeof enabled === 'undefined') {
......@@ -173,23 +172,23 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Enable/disable the save button.
Check whether the save button is enabled.
Enable/disable the save button.
Check whether the save button is enabled.
Also enables/disables a beforeunload handler to warn
users about navigating away from the page with unsaved changes.
Also enables/disables a beforeunload handler to warn
users about navigating away from the page with unsaved changes.
Args:
enabled (bool): If specified, set the state of the button.
Args:
enabled (bool): If specified, set the state of the button.
Returns:
bool: Whether the button is enabled.
Returns:
bool: Whether the button is enabled.
Examples:
>> view.submitEnabled(true); // enable the button
>> view.submitEnabled(); // check whether the button is enabled
>> true
**/
Examples:
>> view.submitEnabled(true); // enable the button
>> view.submitEnabled(); // check whether the button is enabled
>> true
**/
saveEnabled: function(enabled) {
var sel = $('#submission__save', this.element);
if (typeof enabled === 'undefined') {
......@@ -200,10 +199,10 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Enable/disable the preview button.
Enable/disable the preview button.
Works exactly the same way as saveEnabled method.
**/
Works exactly the same way as saveEnabled method.
**/
previewEnabled: function(enabled) {
var sel = $('#submission__preview', this.element);
if (typeof enabled === 'undefined') {
......@@ -213,15 +212,15 @@ OpenAssessment.ResponseView.prototype = {
}
},
/**
Set the save status message.
Retrieve the save status message.
Set the save status message.
Retrieve the save status message.
Args:
msg (string): If specified, the message to display.
Args:
msg (string): If specified, the message to display.
Returns:
string: The current status message.
**/
Returns:
string: The current status message.
**/
saveStatus: function(msg) {
var sel = $('#response__save_status h3', this.element);
if (typeof msg === 'undefined') {
......@@ -235,19 +234,19 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Enable/disable the "navigate away" warning to alert the user of unsaved changes.
Enable/disable the "navigate away" warning to alert the user of unsaved changes.
Args:
enabled (bool): If specified, set whether the warning is enabled.
Args:
enabled (bool): If specified, set whether the warning is enabled.
Returns:
bool: Whether the warning is enabled.
Returns:
bool: Whether the warning is enabled.
Examples:
>> view.unsavedWarningEnabled(true); // enable the "unsaved" warning
>> view.unsavedWarningEnabled();
>> true
**/
Examples:
>> view.unsavedWarningEnabled(true); // enable the "unsaved" warning
>> view.unsavedWarningEnabled();
>> true
**/
unsavedWarningEnabled: function(enabled) {
if (typeof enabled === 'undefined') {
return (window.onbeforeunload !== null);
......@@ -256,8 +255,7 @@ OpenAssessment.ResponseView.prototype = {
if (enabled) {
window.onbeforeunload = function() {
// Keep this on one big line to avoid gettext bug: http://stackoverflow.com/a/24579117
/* jshint maxlen:300 */
return gettext("If you leave this page without saving or submitting your response, you'll lose any work you've done on the response.");
return gettext("If you leave this page without saving or submitting your response, you'll lose any work you've done on the response."); // jscs:ignore maximumLineLength
};
}
else {
......@@ -267,15 +265,15 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Set the response texts.
Retrieve the response texts.
Set the response texts.
Retrieve the response texts.
Args:
texts (array of strings): If specified, the texts to set for the response.
Args:
texts (array of strings): If specified, the texts to set for the response.
Returns:
array of strings: The current response texts.
**/
Returns:
array of strings: The current response texts.
**/
response: function(texts) {
var sel = $('.submission__answer__part__text__value', this.element);
if (typeof texts === 'undefined') {
......@@ -290,25 +288,25 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Check whether the response texts have changed since the last save.
Check whether the response texts have changed since the last save.
Returns: boolean
**/
Returns: boolean
**/
responseChanged: function() {
var savedResponse = this.savedResponse;
return this.response().some(function(element, index) {
return element !== savedResponse[index];
return element !== savedResponse[index];
});
},
/**
Automatically save the user's response if certain conditions are met.
Automatically save the user's response if certain conditions are met.
Usually, this would be called by a timer (see `setAutoSaveEnabled()`).
For testing purposes, it's useful to disable the timer
and call this function synchronously.
**/
Usually, this would be called by a timer (see `setAutoSaveEnabled()`).
For testing purposes, it's useful to disable the timer
and call this function synchronously.
**/
autoSave: function() {
var timeSinceLastChange = Date.now() - this.lastChangeTime;
......@@ -324,14 +322,14 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Enable/disable the submission and save buttons based on whether
the user has entered a response.
**/
Enable/disable the submission and save buttons based on whether
the user has entered a response.
**/
handleResponseChanged: function() {
// Enable the save/submit button only for non-blank responses
var isNotBlank = !this.response().every(function(element) {
return $.trim(element) === '';
});
return $.trim(element) === '';
});
this.submitEnabled(isNotBlank);
// Update the save button, save status, and "unsaved changes" warning
......@@ -348,8 +346,8 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Save a response without submitting it.
**/
Save a response without submitting it.
**/
save: function() {
// If there were errors on previous calls to save, forget
// about them for now. If an error occurs on *this* save,
......@@ -396,8 +394,8 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Send a response submission to the server and update the view.
**/
Send a response submission to the server and update the view.
**/
submit: function() {
// Immediately disable the submit button to prevent multiple submission
this.submitEnabled(false);
......@@ -409,7 +407,7 @@ OpenAssessment.ResponseView.prototype = {
// check if there is a file selected but not uploaded yet
if (view.files !== null && !view.fileUploaded) {
var msg = gettext('Do you want to upload your file before submitting?');
if(confirm(msg)) {
if (confirm(msg)) {
fileDefer = view.fileUpload();
} else {
view.submitEnabled(true);
......@@ -456,8 +454,8 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Transition the user to the next step in the workflow.
**/
Transition the user to the next step in the workflow.
**/
moveToNextStep: function() {
this.load();
this.baseView.loadAssessmentModules();
......@@ -468,17 +466,16 @@ OpenAssessment.ResponseView.prototype = {
},
/**
Make the user confirm before submitting a response.
Make the user confirm before submitting a response.
Returns:
JQuery deferred object, which is:
* resolved if the user confirms the submission
* rejected if the user cancels the submission
**/
Returns:
JQuery deferred object, which is:
* resolved if the user confirms the submission
* rejected if the user cancels the submission
**/
confirmSubmission: function() {
// Keep this on one big line to avoid gettext bug: http://stackoverflow.com/a/24579117
/* jshint maxlen:300 */
var msg = gettext("You're about to submit your response for this assignment. After you submit this response, you can't change it or submit a new response.");
var msg = gettext("You're about to submit your response for this assignment. After you submit this response, you can't change it or submit a new response."); // jscs:ignore maximumLineLength
// TODO -- UI for confirmation dialog instead of JS confirm
return $.Deferred(function(defer) {
if (confirm(msg)) { defer.resolve(); }
......@@ -492,11 +489,11 @@ OpenAssessment.ResponseView.prototype = {
larger than the maximum file size.
Args:
files (list): A collection of files used for upload. This function assumes
there is only one file being uploaded at any time. This file must
be less than 5 MB and an image, PDF or other allowed types.
uploadType (string): uploaded file type allowed, could be none, image,
file or custom.
files (list): A collection of files used for upload. This function assumes
there is only one file being uploaded at any time. This file must
be less than 5 MB and an image, PDF or other allowed types.
uploadType (string): uploaded file type allowed, could be none, image,
file or custom.
**/
prepareUpload: function(files, uploadType) {
......@@ -536,7 +533,6 @@ OpenAssessment.ResponseView.prototype = {
$("#file__upload").toggleClass("is--disabled", this.files === null);
},
/**
Manages file uploads for submission attachments. Retrieves a one-time
upload URL from the server, and uses it to upload images to a designated
......
......@@ -11,7 +11,6 @@ OpenAssessment.Rubric = function(element) {
this.element = element;
};
OpenAssessment.Rubric.prototype = {
/**
Get or set per-criterion feedback.
......
......@@ -16,7 +16,6 @@ OpenAssessment.SelfView = function(element, server, baseView) {
this.rubric = null;
};
OpenAssessment.SelfView.prototype = {
/**
......
......@@ -52,15 +52,15 @@
loadStudentInfo: function() {
var view = this;
var sel = $('#openassessment__staff-tools', this.element);
var student_username = sel.find('#openassessment__student_username').val();
this.server.studentInfo(student_username).done(
var studentUsername = sel.find('#openassessment__student_username').val();
this.server.studentInfo(studentUsername).done(
function(html) {
// Load the HTML and install event handlers
$('#openassessment__student-info', view.element).replaceWith(html);
// Install key handler for new staff grade Save button.
var selCancelSub = $('#openassessment__staff-info__cancel__submission', view.element);
selCancelSub.on('click', '#submit_cancel_submission', function (eventObject) {
selCancelSub.on('click', '#submit_cancel_submission', function(eventObject) {
eventObject.preventDefault();
view.cancelSubmission($(this).data('submission-uuid'));
}
......
......@@ -16,7 +16,6 @@ OpenAssessment.StudentTrainingView = function(element, server, baseView) {
this.rubric = null;
};
OpenAssessment.StudentTrainingView.prototype = {
/**
......
/**
Encapsulate interactions with OpenAssessment XBlock handlers.
**/
Encapsulate interactions with OpenAssessment XBlock handlers.
**/
// Since the server is included by both LMS and Studio views,
// skip loading it the second time.
if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
/**
Interface for server-side XBlock handlers.
Interface for server-side XBlock handlers.
Args:
runtime (Runtime): An XBlock runtime instance.
element (DOM element): The DOM element representing this XBlock.
Args:
runtime (Runtime): An XBlock runtime instance.
element (DOM element): The DOM element representing this XBlock.
Returns:
OpenAssessment.Server
**/
Returns:
OpenAssessment.Server
**/
OpenAssessment.Server = function(runtime, element) {
this.runtime = runtime;
this.element = element;
......@@ -26,35 +26,35 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
OpenAssessment.Server.prototype = {
/**
Construct the URL for the handler, specific to one instance of the XBlock on the page.
Construct the URL for the handler, specific to one instance of the XBlock on the page.
Args:
handler (string): The name of the XBlock handler.
Args:
handler (string): The name of the XBlock handler.
Returns:
URL (string)
**/
Returns:
URL (string)
**/
url: function(handler) {
return this.runtime.handlerUrl(this.element, handler);
},
/**
Render the XBlock.
Args:
component (string): The component to render.
Returns:
A JQuery promise, which resolves with the HTML of the rendered XBlock
and fails with an error message.
Example:
server.render('submission').done(
function(html) { console.log(html); }
).fail(
function(err) { console.log(err); }
)
**/
Render the XBlock.
Args:
component (string): The component to render.
Returns:
A JQuery promise, which resolves with the HTML of the rendered XBlock
and fails with an error message.
Example:
server.render('submission').done(
function(html) { console.log(html); }
).fail(
function(err) { console.log(err); }
)
**/
render: function(component) {
var view = this;
var url = this.url('render_' + component);
......@@ -72,11 +72,11 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
},
/**
Render Latex for all new DOM elements with class 'allow--latex'.
Render Latex for all new DOM elements with class 'allow--latex'.
Args:
element: The element to modify.
**/
Args:
element: The element to modify.
**/
renderLatex: function(element) {
element.filter(".allow--latex").each(function() {
MathJax.Hub.Queue(['Typeset', MathJax.Hub, this]);
......@@ -88,15 +88,15 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
continue grading peers.
Returns:
A JQuery promise, which resolves with the HTML of the rendered peer
assessment section or fails with an error message.
A JQuery promise, which resolves with the HTML of the rendered peer
assessment section or fails with an error message.
Example:
server.render_continued_peer().done(
function(html) { console.log(html); }
).fail(
function(err) { console.log(err); }
)
server.render_continued_peer().done(
function(html) { console.log(html); }
).fail(
function(err) { console.log(err); }
)
**/
renderContinuedPeer: function() {
var view = this;
......@@ -108,42 +108,42 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
dataType: "html",
data: {continue_grading: true}
}).done(function(data) {
defer.resolveWith(view, [data]);
}).fail(function() {
defer.rejectWith(view, [gettext('This section could not be loaded.')]);
});
defer.resolveWith(view, [data]);
}).fail(function() {
defer.rejectWith(view, [gettext('This section could not be loaded.')]);
});
}).promise();
},
/**
Load the Student Info section in Staff Info.
**/
studentInfo: function(student_username) {
studentInfo: function(studentUsername) {
var url = this.url('render_student_info');
return $.Deferred(function(defer) {
$.ajax({
url: url,
type: "POST",
dataType: "html",
data: {student_username: student_username}
data: {student_username: studentUsername}
}).done(function(data) {
defer.resolveWith(this, [data]);
}).fail(function() {
defer.rejectWith(this, [gettext('This section could not be loaded.')]);
});
defer.resolveWith(this, [data]);
}).fail(function() {
defer.rejectWith(this, [gettext('This section could not be loaded.')]);
});
}).promise();
},
/**
Send a submission to the XBlock.
Send a submission to the XBlock.
Args:
submission (string): The text of the student's submission.
Args:
submission (string): The text of the student's submission.
Returns:
A JQuery promise, which resolves with the student's ID and attempt number
if the call was successful and fails with an status code and error message otherwise.
**/
Returns:
A JQuery promise, which resolves with the student's ID and attempt number
if the call was successful and fails with an status code and error message otherwise.
**/
submit: function(submission) {
var url = this.url('submit');
return $.Deferred(function(defer) {
......@@ -171,15 +171,15 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
},
/**
Save a response without submitting it.
Save a response without submitting it.
Args:
submission (string): The text of the student's response.
Args:
submission (string): The text of the student's response.
Returns:
A JQuery promise, which resolves with no arguments on success and
fails with an error message.
**/
Returns:
A JQuery promise, which resolves with no arguments on success and
fails with an error message.
**/
save: function(submission) {
var url = this.url('save_submission');
return $.Deferred(function(defer) {
......@@ -216,14 +216,14 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
* console.log("Error: " + errMsg);
* });
*/
submitFeedbackOnAssessment: function(text, options) {
submitFeedbackOnAssessment: function(text, options) {
var url = this.url('submit_feedback');
var payload = JSON.stringify({
'feedback_text': text,
'feedback_options': options
});
return $.Deferred(function(defer) {
$.ajax({ type: "POST", url: url, data: payload, contentType: jsonContentType }).done(
$.ajax({type: "POST", url: url, data: payload, contentType: jsonContentType}).done(
function(data) {
if (data.success) { defer.resolve(); }
else { defer.rejectWith(this, [data.msg]); }
......@@ -235,28 +235,28 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
},
/**
Send a peer assessment to the XBlock.
Args:
optionsSelected (object literal): Keys are criteria names,
values are the option text the user selected for the criterion.
criterionFeedback (object literal): Written feedback on a particular criterion,
where keys are criteria names and values are the feedback strings.
overallFeedback (string): Written feedback on the submission as a whole.
Returns:
A JQuery promise, which resolves with no args if successful
and fails with an error message otherise.
Example:
var options = { clarity: "Very clear", precision: "Somewhat precise" };
var criterionFeedback = { clarity: "The essay was very clear." };
var overallFeedback = "Good job!";
server.peerAssess(options, criterionFeedback, overallFeedback).done(
function() { console.log("Success!"); }
).fail(
function(errorMsg) { console.log(errorMsg); }
);
**/
Send a peer assessment to the XBlock.
Args:
optionsSelected (object literal): Keys are criteria names,
values are the option text the user selected for the criterion.
criterionFeedback (object literal): Written feedback on a particular criterion,
where keys are criteria names and values are the feedback strings.
overallFeedback (string): Written feedback on the submission as a whole.
Returns:
A JQuery promise, which resolves with no args if successful
and fails with an error message otherise.
Example:
var options = { clarity: "Very clear", precision: "Somewhat precise" };
var criterionFeedback = { clarity: "The essay was very clear." };
var overallFeedback = "Good job!";
server.peerAssess(options, criterionFeedback, overallFeedback).done(
function() { console.log("Success!"); }
).fail(
function(errorMsg) { console.log(errorMsg); }
);
**/
peerAssess: function(optionsSelected, criterionFeedback, overallFeedback, uuid) {
var url = this.url('peer_assess');
var payload = JSON.stringify({
......@@ -266,7 +266,7 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
submission_uuid: uuid
});
return $.Deferred(function(defer) {
$.ajax({ type: "POST", url: url, data: payload, contentType: jsonContentType }).done(
$.ajax({type: "POST", url: url, data: payload, contentType: jsonContentType}).done(
function(data) {
if (data.success) {
defer.resolve();
......@@ -282,26 +282,26 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
},
/**
Send a self-assessment to the XBlock.
Args:
optionsSelected (object literal): Keys are criteria names,
values are the option text the user selected for the criterion.
var criterionFeedback = { clarity: "The essay was very clear." };
var overallFeedback = "Good job!";
Returns:
A JQuery promise, which resolves with no args if successful
and fails with an error message otherwise.
Example:
var options = { clarity: "Very clear", precision: "Somewhat precise" };
server.selfAssess(options).done(
function() { console.log("Success!"); }
).fail(
function(errorMsg) { console.log(errorMsg); }
);
**/
Send a self-assessment to the XBlock.
Args:
optionsSelected (object literal): Keys are criteria names,
values are the option text the user selected for the criterion.
var criterionFeedback = { clarity: "The essay was very clear." };
var overallFeedback = "Good job!";
Returns:
A JQuery promise, which resolves with no args if successful
and fails with an error message otherwise.
Example:
var options = { clarity: "Very clear", precision: "Somewhat precise" };
server.selfAssess(options).done(
function() { console.log("Success!"); }
).fail(
function(errorMsg) { console.log(errorMsg); }
);
**/
selfAssess: function(optionsSelected, criterionFeedback, overallFeedback) {
var url = this.url('self_assess');
var payload = JSON.stringify({
......@@ -310,7 +310,7 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
overall_feedback: overallFeedback
});
return $.Deferred(function(defer) {
$.ajax({ type: "POST", url: url, data: payload, contentType: jsonContentType }).done(
$.ajax({type: "POST", url: url, data: payload, contentType: jsonContentType}).done(
function(data) {
if (data.success) {
defer.resolve();
......@@ -326,32 +326,32 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
},
/**
Assess an instructor-provided training example.
Args:
optionsSelected (object literal): Keys are criteria names,
values are the option text the user selected for the criterion.
Returns:
A JQuery promise, which resolves with a list of corrections if
successful and fails with an error message otherwise.
Example:
var options = { clarity: "Very clear", precision: "Somewhat precise" };
server.trainingAssess(options).done(
function(corrections) { console.log("Success!"); }
alert(corrections);
).fail(
function(errorMsg) { console.log(errorMsg); }
);
**/
Assess an instructor-provided training example.
Args:
optionsSelected (object literal): Keys are criteria names,
values are the option text the user selected for the criterion.
Returns:
A JQuery promise, which resolves with a list of corrections if
successful and fails with an error message otherwise.
Example:
var options = { clarity: "Very clear", precision: "Somewhat precise" };
server.trainingAssess(options).done(
function(corrections) { console.log("Success!"); }
alert(corrections);
).fail(
function(errorMsg) { console.log(errorMsg); }
);
**/
trainingAssess: function(optionsSelected) {
var url = this.url('training_assess');
var payload = JSON.stringify({
options_selected: optionsSelected
});
return $.Deferred(function(defer) {
$.ajax({ type: "POST", url: url, data: payload, contentType: jsonContentType }).done(
$.ajax({type: "POST", url: url, data: payload, contentType: jsonContentType}).done(
function(data) {
if (data.success) {
defer.resolveWith(this, [data.corrections]);
......@@ -367,25 +367,25 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
},
/**
Schedules classifier training for Example Based Assessment for this
Location.
Returns:
A JQuery promise, which resolves with a message indicating the results
of the scheduling request.
Example:
server.scheduleTraining().done(
function(msg) { console.log("Success!"); }
alert(msg);
).fail(
function(errorMsg) { console.log(errorMsg); }
);
**/
Schedules classifier training for Example Based Assessment for this
Location.
Returns:
A JQuery promise, which resolves with a message indicating the results
of the scheduling request.
Example:
server.scheduleTraining().done(
function(msg) { console.log("Success!"); }
alert(msg);
).fail(
function(errorMsg) { console.log(errorMsg); }
);
**/
scheduleTraining: function() {
var url = this.url('schedule_training');
return $.Deferred(function(defer) {
$.ajax({ type: "POST", url: url, data: "\"\"", contentType: jsonContentType}).done(
$.ajax({type: "POST", url: url, data: "\"\"", contentType: jsonContentType}).done(
function(data) {
if (data.success) {
defer.resolveWith(this, [data.msg]);
......@@ -395,21 +395,21 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
}
}
).fail(function() {
defer.rejectWith(this, [gettext('This assessment could not be submitted.')]);
});
defer.rejectWith(this, [gettext('This assessment could not be submitted.')]);
});
});
},
/**
Reschedules grading tasks for example based assessments
Reschedules grading tasks for example based assessments
Returns:
JQuery Promise which will resolve with a message indicating success or failure of the scheduling
**/
Returns:
JQuery Promise which will resolve with a message indicating success or failure of the scheduling
**/
rescheduleUnfinishedTasks: function() {
var url = this.url('reschedule_unfinished_tasks');
return $.Deferred(function(defer) {
$.ajax({ type: "POST", url: url, data: "\"\"", contentType: jsonContentType}).done(
$.ajax({type: "POST", url: url, data: "\"\"", contentType: jsonContentType}).done(
function(data) {
if (data.success) {
defer.resolveWith(this, [data.msg]);
......@@ -419,34 +419,34 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
}
}
).fail(function() {
defer.rejectWith(this, [gettext('One or more rescheduling tasks failed.')]);
defer.rejectWith(this, [gettext('One or more rescheduling tasks failed.')]);
});
});
},
/**
Update the XBlock's XML definition on the server.
Kwargs:
title (string): The title of the problem.
prompt (string): The question prompt.
feedbackPrompt (string): The directions to the student for giving overall feedback on a submission.
feedback_default_text (string): The default feedback text used as the student's feedback response
submissionStart (ISO-formatted datetime string or null): The start date of the submission.
submissionDue (ISO-formatted datetime string or null): The date the submission is due.
criteria (list of object literals): The rubric criteria.
assessments (list of object literals): The assessments the student will be evaluated on.
fileUploadType (string): 'image' if image attachments are allowed, 'pdf-and-image' if pdf and
image attachments are allowed, 'custom' if file type is restricted by a white list.
fileTypeWhiteList (string): Comma separated file type white list
latexEnabled: TRUE if latex rendering is enabled.
leaderboardNum (int): The number of scores to show in the leaderboard.
Returns:
A JQuery promise, which resolves with no arguments
and fails with an error message.
**/
Update the XBlock's XML definition on the server.
Kwargs:
title (string): The title of the problem.
prompt (string): The question prompt.
feedbackPrompt (string): The directions to the student for giving overall feedback on a submission.
feedback_default_text (string): The default feedback text used as the student's feedback response
submissionStart (ISO-formatted datetime string or null): The start date of the submission.
submissionDue (ISO-formatted datetime string or null): The date the submission is due.
criteria (list of object literals): The rubric criteria.
assessments (list of object literals): The assessments the student will be evaluated on.
fileUploadType (string): 'image' if image attachments are allowed, 'pdf-and-image' if pdf and
image attachments are allowed, 'custom' if file type is restricted by a white list.
fileTypeWhiteList (string): Comma separated file type white list
latexEnabled: TRUE if latex rendering is enabled.
leaderboardNum (int): The number of scores to show in the leaderboard.
Returns:
A JQuery promise, which resolves with no arguments
and fails with an error message.
**/
updateEditorContext: function(kwargs) {
var url = this.url('update_editor_context');
var payload = JSON.stringify({
......@@ -477,20 +477,20 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
},
/**
Check whether the XBlock has been released.
Returns:
A JQuery promise, which resolves with a boolean indicating
whether the XBlock has been released. On failure, the promise
provides an error message.
Example:
server.checkReleased().done(
function(isReleased) {}
).fail(
function(errMsg) {}
)
**/
Check whether the XBlock has been released.
Returns:
A JQuery promise, which resolves with a boolean indicating
whether the XBlock has been released. On failure, the promise
provides an error message.
Example:
server.checkReleased().done(
function(isReleased) {}
).fail(
function(errMsg) {}
)
**/
checkReleased: function() {
var url = this.url('check_released');
var payload = "\"\"";
......@@ -511,12 +511,12 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
submission.
Args:
contentType (str): The Content Type for the file being uploaded.
filename (str): The name of the file to be uploaded.
contentType (str): The Content Type for the file being uploaded.
filename (str): The name of the file to be uploaded.
Returns:
A presigned upload URL from the specified service used for uploading
files.
A presigned upload URL from the specified service used for uploading
files.
**/
getUploadUrl: function(contentType, filename) {
......@@ -528,11 +528,11 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
data: JSON.stringify({contentType: contentType, filename: filename}),
contentType: jsonContentType
}).done(function(data) {
if (data.success) { defer.resolve(data.url); }
else { defer.rejectWith(this, [data.msg]); }
}).fail(function() {
defer.rejectWith(this, [gettext('Could not retrieve upload url.')]);
});
if (data.success) { defer.resolve(data.url); }
else { defer.rejectWith(this, [data.msg]); }
}).fail(function() {
defer.rejectWith(this, [gettext('Could not retrieve upload url.')]);
});
}).promise();
},
......@@ -540,7 +540,7 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
Get a download url used to download related files for the submission.
Returns:
A temporary download URL for retrieving documents from s3.
A temporary download URL for retrieving documents from s3.
**/
getDownloadUrl: function() {
......@@ -549,28 +549,28 @@ if (typeof OpenAssessment.Server === "undefined" || !OpenAssessment.Server) {
$.ajax({
type: "POST", url: url, data: JSON.stringify({}), contentType: jsonContentType
}).done(function(data) {
if (data.success) { defer.resolve(data.url); }
else { defer.rejectWith(this, [data.msg]); }
}).fail(function() {
defer.rejectWith(this, [gettext('Could not retrieve download url.')]);
});
if (data.success) { defer.resolve(data.url); }
else { defer.rejectWith(this, [data.msg]); }
}).fail(function() {
defer.rejectWith(this, [gettext('Could not retrieve download url.')]);
});
}).promise();
},
/**
Cancel the submission from peer grading pool.
Args:
submissionUUID: ID for submission to be cancelled from pool.
comments: reason to cancel the submission
         **/
cancelSubmission: function (submissionUUID, comments) {
Cancel the submission from peer grading pool.
Args:
submissionUUID: ID for submission to be cancelled from pool.
comments: reason to cancel the submission
         **/
cancelSubmission: function(submissionUUID, comments) {
var url = this.url('cancel_submission');
var payload = JSON.stringify({
submission_uuid: submissionUUID,
comments: comments
});
return $.Deferred(function (defer) {
$.ajax({ type: "POST", url: url, data: payload, contentType: jsonContentType }).done(
return $.Deferred(function(defer) {
$.ajax({type: "POST", url: url, data: payload, contentType: jsonContentType}).done(
function(data) {
if (data.success) {
defer.resolveWith(this, [data.msg]);
......
/**
JavaScript shared between all open assessment modules.
WARNING: Don't add anything to this file until you're
absolutely sure there isn't a way to encapsulate it in
an object!
**/
JavaScript shared between all open assessment modules.
WARNING: Don't add anything to this file until you're
absolutely sure there isn't a way to encapsulate it in
an object!
**/
/* Namespace for open assessment */
/* jshint ignore:start */
......@@ -14,25 +13,22 @@ if (typeof OpenAssessment == "undefined" || !OpenAssessment) {
}
/* jshint ignore:end */
// Stub gettext if the runtime doesn't provide it
if (typeof window.gettext === 'undefined') {
window.gettext = function(text) { return text; };
}
// If ngettext isn't found (workbench, testing, etc.), return the simplistic english version
if (typeof window.ngetgext === 'undefined') {
window.ngettext = function (singular_text, plural_text, n) {
window.ngettext = function(singularText, pluralText, n) {
if (n > 1) {
return plural_text;
return pluralText;
} else {
return singular_text;
return singularText;
}
};
}
// Stub event logging if the runtime doesn't provide it
if (typeof window.Logger === 'undefined') {
window.Logger = {
......@@ -40,7 +36,6 @@ if (typeof window.Logger === 'undefined') {
};
}
// Stub MathJax is the runtime doesn't provide it
if (typeof window.MathJax === 'undefined') {
window.MathJax = {
......@@ -49,4 +44,4 @@ if (typeof window.MathJax === 'undefined') {
Queue: function() {}
}
};
}
\ No newline at end of file
}
......@@ -92,7 +92,7 @@ OpenAssessment.Container.prototype = {
// Find items already in the container and install click
// handlers for the delete buttons.
$("." + this.removeButtonClass, this.containerElement).click(
function (eventData) {
function(eventData) {
var item = container.createContainerItem(eventData.target);
container.remove(item);
}
......@@ -137,7 +137,7 @@ OpenAssessment.Container.prototype = {
// Install a click handler for the delete button
if (this.addRemoveEnabled) {
containerItem.find('.' + this.removeButtonClass)
.click(function (eventData) {
.click(function(eventData) {
var containerItem = container.createContainerItem(eventData.target);
container.remove(containerItem);
});
......@@ -176,7 +176,7 @@ OpenAssessment.Container.prototype = {
array: The values representing each container item.
**/
getItemValues: function () {
getItemValues: function() {
var values = [];
var container = this;
......
......@@ -35,7 +35,7 @@ OpenAssessment.ItemUtilities = {
var label = $(element).attr('data-label');
var name = $(element).val();
// We don't want the lack of a label to make it look like - 1 points.
if (label === ""){
if (label === "") {
label = gettext('Unnamed Option');
}
var singularString = label + " - " + points + " point";
......@@ -65,16 +65,16 @@ OpenAssessment.ItemUtilities = {
};
/**
The Prompt Class is used to construct and maintain references to prompts from within a prompts
container object. Constructs a new Prompt element.
The Prompt Class is used to construct and maintain references to prompts from within a prompts
container object. Constructs a new Prompt element.
Args:
element (OpenAssessment.Container): The container that the prompt is a member of.
notifier (OpenAssessment.Notifier): Used to send notifications of updates to prompts.
Args:
element (OpenAssessment.Container): The container that the prompt is a member of.
notifier (OpenAssessment.Notifier): Used to send notifications of updates to prompts.
Returns:
OpenAssessment.Prompt
**/
Returns:
OpenAssessment.Prompt
**/
OpenAssessment.Prompt = function(element, notifier) {
this.element = element;
this.notifier = notifier;
......@@ -82,15 +82,15 @@ OpenAssessment.Prompt = function(element, notifier) {
OpenAssessment.Prompt.prototype = {
/**
Finds the values currently entered in the Prompts's fields, and returns them.
Finds the values currently entered in the Prompts's fields, and returns them.
Returns:
object literal of the form:
{
'description': 'Write a nice long essay about anything.'
}
**/
getFieldValues: function () {
Returns:
object literal of the form:
{
'description': 'Write a nice long essay about anything.'
}
**/
getFieldValues: function() {
var fields = {
description: this.description()
};
......@@ -98,15 +98,15 @@ OpenAssessment.Prompt.prototype = {
},
/**
Get or set the description of the prompt.
Get or set the description of the prompt.
Args:
text (string, optional): If provided, set the description of the prompt.
Args:
text (string, optional): If provided, set the description of the prompt.
Returns:
string
Returns:
string
**/
**/
description: function(text) {
var sel = $('.openassessment_prompt_description', this.element);
return OpenAssessment.Fields.stringField(sel, text);
......@@ -115,10 +115,10 @@ OpenAssessment.Prompt.prototype = {
addEventListeners: function() {},
/**
Hook into the event handler for addition of a prompt.
Hook into the event handler for addition of a prompt.
*/
addHandler: function (){
*/
addHandler: function() {
this.notifier.notificationFired(
"promptAdd",
{
......@@ -128,10 +128,10 @@ OpenAssessment.Prompt.prototype = {
},
/**
Hook into the event handler for removal of a prompt.
Hook into the event handler for removal of a prompt.
*/
removeHandler: function (){
*/
removeHandler: function() {
this.notifier.notificationFired(
"promptRemove",
{
......@@ -143,75 +143,75 @@ OpenAssessment.Prompt.prototype = {
updateHandler: function() {},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the option is valid.
Returns:
Boolean indicating whether the option is valid.
**/
**/
validate: function() {
return true;
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of strings
Returns:
list of strings
**/
**/
validationErrors: function() {
return [];
},
/**
Clear all validation errors from the UI.
**/
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {}
};
/**
The RubricOption Class used to construct and maintain references to rubric options from within an options
container object. Constructs a new RubricOption element.
The RubricOption Class used to construct and maintain references to rubric options from within an options
container object. Constructs a new RubricOption element.
Args:
element (OpenAssessment.Container): The container that the option is a member of.
notifier (OpenAssessment.Notifier): Used to send notifications of updates to rubric options.
Args:
element (OpenAssessment.Container): The container that the option is a member of.
notifier (OpenAssessment.Notifier): Used to send notifications of updates to rubric options.
Returns:
OpenAssessment.RubricOption
**/
Returns:
OpenAssessment.RubricOption
**/
OpenAssessment.RubricOption = function(element, notifier) {
this.element = element;
this.notifier = notifier;
this.pointsField = new OpenAssessment.IntField(
$(".openassessment_criterion_option_points", this.element),
{ min: 0, max: 999 }
{min: 0, max: 999}
);
};
OpenAssessment.RubricOption.prototype = {
/**
Adds event listeners specific to this container item.
**/
Adds event listeners specific to this container item.
**/
addEventListeners: function() {
// Install a focus out handler for container changes.
$(this.element).focusout($.proxy(this.updateHandler, this));
},
/**
Finds the values currently entered in the Option's fields, and returns them.
Finds the values currently entered in the Option's fields, and returns them.
Returns:
object literal of the form:
{
'name': 'Real Bad',
'points': 1,
'explanation': 'Essay was primarily composed of emojis.'
}
**/
getFieldValues: function () {
Returns:
object literal of the form:
{
'name': 'Real Bad',
'points': 1,
'explanation': 'Essay was primarily composed of emojis.'
}
**/
getFieldValues: function() {
var fields = {
label: this.label(),
points: this.points(),
......@@ -230,45 +230,45 @@ OpenAssessment.RubricOption.prototype = {
},
/**
Get or set the label of the option.
Get or set the label of the option.
Args:
label (string, optional): If provided, set the label to this string.
Args:
label (string, optional): If provided, set the label to this string.
Returns:
string
Returns:
string
**/
**/
label: function(label) {
var sel = $('.openassessment_criterion_option_label', this.element);
return OpenAssessment.Fields.stringField(sel, label);
},
/**
Get or set the point value of the option.
Get or set the point value of the option.
Args:
points (int, optional): If provided, set the point value of the option.
Args:
points (int, optional): If provided, set the point value of the option.
Returns:
int
Returns:
int
**/
**/
points: function(points) {
if (points !== undefined) { this.pointsField.set(points); }
return this.pointsField.get();
},
/**
Get or set the explanation for the option.
Get or set the explanation for the option.
Args:
explanation (string, optional): If provided, set the explanation to this string.
Args:
explanation (string, optional): If provided, set the explanation to this string.
Returns:
string
Returns:
string
**/
**/
explanation: function(explanation) {
var sel = $('.openassessment_criterion_option_explanation', this.element);
return OpenAssessment.Fields.stringField(sel, explanation);
......@@ -278,7 +278,7 @@ OpenAssessment.RubricOption.prototype = {
Hook into the event handler for addition of a criterion option.
*/
addHandler: function (){
addHandler: function() {
var criterionElement = $(this.element).closest(".openassessment_criterion");
var criterionName = $(criterionElement).data('criterion');
......@@ -310,7 +310,7 @@ OpenAssessment.RubricOption.prototype = {
Hook into the event handler for removal of a criterion option.
*/
removeHandler: function (){
removeHandler: function() {
var criterionName = $(this.element).data('criterion');
var optionName = $(this.element).data('option');
this.notifier.notificationFired(
......@@ -327,7 +327,7 @@ OpenAssessment.RubricOption.prototype = {
modified.
*/
updateHandler: function(){
updateHandler: function() {
var fields = this.getFieldValues();
var criterionName = $(this.element).data('criterion');
var optionName = $(this.element).data('option');
......@@ -345,47 +345,47 @@ OpenAssessment.RubricOption.prototype = {
},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the option is valid.
Returns:
Boolean indicating whether the option is valid.
**/
**/
validate: function() {
return this.pointsField.validate();
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
Returns:
list of string
**/
**/
validationErrors: function() {
var hasError = (this.pointsField.validationErrors().length > 0);
return hasError ? ["Option points are invalid"] : [];
},
/**
Clear all validation errors from the UI.
**/
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {
this.pointsField.clearValidationErrors();
}
};
/**
The RubricCriterion Class is used to construct and get information from a rubric element within
the DOM.
The RubricCriterion Class is used to construct and get information from a rubric element within
the DOM.
Args:
element (JQuery Object): The selection which describes the scope of the criterion.
notifier (OpenAssessment.Notifier): Used to send notifications of updates to rubric criteria.
Args:
element (JQuery Object): The selection which describes the scope of the criterion.
notifier (OpenAssessment.Notifier): Used to send notifications of updates to rubric criteria.
Returns:
OpenAssessment.RubricCriterion
Returns:
OpenAssessment.RubricCriterion
**/
OpenAssessment.RubricCriterion = function(element, notifier) {
this.element = element;
......@@ -404,13 +404,12 @@ OpenAssessment.RubricCriterion = function(element, notifier) {
);
};
OpenAssessment.RubricCriterion.prototype = {
/**
Invoked by the container to add event listeners to all child containers
of this item, and add event listeners specific to this container item.
**/
Invoked by the container to add event listeners to all child containers
of this item, and add event listeners specific to this container item.
**/
addEventListeners: function() {
this.optionContainer.addEventListeners();
// Install a focus out handler for container changes.
......@@ -418,25 +417,25 @@ OpenAssessment.RubricCriterion.prototype = {
},
/**
Finds the values currently entered in the Criterion's fields, and returns them.
Finds the values currently entered in the Criterion's fields, and returns them.
Returns:
object literal of the form:
{
'name': 'Emoji Content',
'prompt': 'How expressive was the author with their words, and how much did they rely on emojis?',
'feedback': 'optional',
'options': [
{
'name': 'Real Bad',
'points': 1,
'explanation': 'Essay was primarily composed of emojis.'
},
...
]
}
**/
getFieldValues: function () {
Returns:
object literal of the form:
{
'name': 'Emoji Content',
'prompt': 'How expressive was the author with their words, and how much did they rely on emojis?',
'feedback': 'optional',
'options': [
{
'name': 'Real Bad',
'points': 1,
'explanation': 'Essay was primarily composed of emojis.'
},
...
]
}
**/
getFieldValues: function() {
var fields = {
label: this.label(),
prompt: this.prompt(),
......@@ -456,49 +455,49 @@ OpenAssessment.RubricCriterion.prototype = {
},
/**
Get or set the label of the criterion.
Get or set the label of the criterion.
Args:
label (string, optional): If provided, set the label to this string.
Args:
label (string, optional): If provided, set the label to this string.
Returns:
string
Returns:
string
**/
**/
label: function(label) {
return OpenAssessment.Fields.stringField(this.labelSel, label);
},
/**
Get or set the prompt of the criterion.
Get or set the prompt of the criterion.
Args:
prompt (string, optional): If provided, set the prompt to this string.
Args:
prompt (string, optional): If provided, set the prompt to this string.
Returns:
string
Returns:
string
**/
**/
prompt: function(prompt) {
return OpenAssessment.Fields.stringField(this.promptSel, prompt);
},
/**
Get the feedback value for the criterion.
This is one of: "disabled", "optional", or "required".
Get the feedback value for the criterion.
This is one of: "disabled", "optional", or "required".
Returns:
string
Returns:
string
**/
**/
feedback: function() {
return $('.openassessment_criterion_feedback', this.element).val();
},
/**
Add an option to the criterion.
Uses the client-side template to create the new option.
**/
Add an option to the criterion.
Uses the client-side template to create the new option.
**/
addOption: function() {
this.optionContainer.add();
},
......@@ -507,7 +506,7 @@ OpenAssessment.RubricCriterion.prototype = {
Hook into the event handler for addition of a criterion.
*/
addHandler: function (){
addHandler: function() {
var criteria = $(".openassessment_criterion", this.element.parent());
// Create the unique name for this option.
var name = OpenAssessment.ItemUtilities.createUniqueName(criteria, "data-criterion");
......@@ -520,7 +519,7 @@ OpenAssessment.RubricCriterion.prototype = {
Hook into the event handler for removal of a criterion.
*/
removeHandler: function(){
removeHandler: function() {
var criterionName = $(this.element).data('criterion');
this.notifier.notificationFired("criterionRemove", {'criterionName': criterionName});
},
......@@ -529,7 +528,7 @@ OpenAssessment.RubricCriterion.prototype = {
Hook into the event handler when a rubric criterion is modified.
*/
updateHandler: function(){
updateHandler: function() {
var fields = this.getFieldValues();
var criterionName = fields.name;
var criterionLabel = fields.label;
......@@ -540,12 +539,12 @@ OpenAssessment.RubricCriterion.prototype = {
},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the criterion is valid.
Returns:
Boolean indicating whether the criterion is valid.
**/
**/
validate: function() {
// The criterion prompt is required.
var isValid = (this.prompt() !== "");
......@@ -561,14 +560,14 @@ OpenAssessment.RubricCriterion.prototype = {
return isValid;
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
Returns:
list of string
**/
**/
validationErrors: function() {
var errors = [];
......@@ -586,8 +585,8 @@ OpenAssessment.RubricCriterion.prototype = {
},
/**
Clear all validation errors from the UI.
**/
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {
// Clear criterion prompt errors
this.promptSel.removeClass("openassessment_highlighted_field");
......@@ -599,18 +598,17 @@ OpenAssessment.RubricCriterion.prototype = {
}
};
/**
The TrainingExample class is used to construct and retrieve information from its element within the DOM
Args:
element (JQuery Object): the selection which identifies the scope of the training example.
element (JQuery Object): the selection which identifies the scope of the training example.
Returns:
OpenAssessment.TrainingExample
OpenAssessment.TrainingExample
**/
OpenAssessment.TrainingExample = function(element){
OpenAssessment.TrainingExample = function(element) {
this.element = element;
this.criteria = $(".openassessment_training_example_criterion_option", this.element);
this.answer = $('.openassessment_training_example_essay_part textarea', this.element);
......@@ -620,12 +618,12 @@ OpenAssessment.TrainingExample.prototype = {
/**
Returns the values currently stored in the fields associated with this training example.
**/
getFieldValues: function () {
getFieldValues: function() {
// Iterates through all of the options selected by the training example, and adds them
// to a list.
var optionsSelected = this.criteria.map(
function () {
function() {
return {
criterion: $(this).data('criterion'),
option: $(this).prop('value')
......@@ -643,8 +641,8 @@ OpenAssessment.TrainingExample.prototype = {
addHandler: function() {
// Goes through and instantiates the option description in the training example for each option.
$(".openassessment_training_example_criterion_option", this.element) .each( function () {
$('option', this).each(function(){
$(".openassessment_training_example_criterion_option", this.element) .each(function() {
$('option', this).each(function() {
OpenAssessment.ItemUtilities.refreshOptionString($(this));
});
});
......@@ -654,12 +652,12 @@ OpenAssessment.TrainingExample.prototype = {
updateHandler: function() {},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the criterion is valid.
Returns:
Boolean indicating whether the criterion is valid.
**/
**/
validate: function() {
var isValid = true;
......@@ -678,13 +676,13 @@ OpenAssessment.TrainingExample.prototype = {
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
Returns:
list of string
**/
**/
validationErrors: function() {
var errors = [];
this.criteria.each(
......@@ -699,15 +697,15 @@ OpenAssessment.TrainingExample.prototype = {
},
/**
Retrieve all elements representing items in this container.
Retrieve all elements representing items in this container.
Returns:
array of container item objects
Returns:
array of container item objects
**/
**/
clearValidationErrors: function() {
this.criteria.each(
function() { $(this).removeClass("openassessment_highlighted_field"); }
);
}
};
\ No newline at end of file
};
......@@ -3,14 +3,14 @@
The constructor initializes the DOM for editing.
Args:
runtime (Runtime): an XBlock runtime instance.
element (DOM element): The DOM element representing this XBlock.
server (OpenAssessment.Server): The interface to the XBlock server.
data (Object literal): The data object passed from XBlock backend.
runtime (Runtime): an XBlock runtime instance.
element (DOM element): The DOM element representing this XBlock.
server (OpenAssessment.Server): The interface to the XBlock server.
data (Object literal): The data object passed from XBlock backend.
Returns:
OpenAssessment.StudioView
**/
OpenAssessment.StudioView
**/
OpenAssessment.StudioView = function(runtime, element, server, data) {
this.element = element;
......@@ -63,7 +63,7 @@ OpenAssessment.StudioView = function(runtime, element, server, data) {
// Initialize the rubric tab view
this.rubricView = new OpenAssessment.EditRubricView(
$("#oa_rubric_editor_wrapper", this.element).get(0),
new OpenAssessment.Notifier([
new OpenAssessment.Notifier([
studentTrainingListener
])
);
......@@ -76,9 +76,9 @@ OpenAssessment.StudioView = function(runtime, element, server, data) {
OpenAssessment.StudioView.prototype = {
/**
Adjusts the modal's height, position and padding to be larger for OA editing only (Does not impact other modals)
**/
fixModalHeight: function () {
Adjusts the modal's height, position and padding to be larger for OA editing only (Does not impact other modals)
**/
fixModalHeight: function() {
// Add the full height class to every element from the XBlock
// to the modal window in Studio.
$(this.element)
......@@ -93,14 +93,14 @@ OpenAssessment.StudioView.prototype = {
},
/**
Initializes the tabs that seperate the sections of the editor.
Initializes the tabs that seperate the sections of the editor.
Because this function relies on the OpenAssessment Name space, the tab that it first
active will be the one that the USER was presented with, regardless of which editor they
were using. I.E. If I leave Editor A in the settings state, and enter editor B, editor B
will automatically open with the settings state.
Because this function relies on the OpenAssessment Name space, the tab that it first
active will be the one that the USER was presented with, regardless of which editor they
were using. I.E. If I leave Editor A in the settings state, and enter editor B, editor B
will automatically open with the settings state.
**/
**/
initializeTabs: function() {
// If this is the first editor that the user has opened, default to the prompt view.
if (typeof(OpenAssessment.lastOpenEditingTab) === "undefined") {
......@@ -124,10 +124,10 @@ OpenAssessment.StudioView.prototype = {
},
/**
Save the problem's XML definition to the server.
If the problem has been released, make the user confirm the save.
**/
save: function () {
Save the problem's XML definition to the server.
If the problem has been released, make the user confirm the save.
**/
save: function() {
var view = this;
this.saveTabState();
......@@ -154,7 +154,7 @@ OpenAssessment.StudioView.prototype = {
// Check whether the problem has been released; if not,
// warn the user and allow them to cancel.
this.server.checkReleased().done(
function (isReleased) {
function(isReleased) {
if (isReleased) {
view.confirmPostReleaseUpdate($.proxy(view.updateEditorContext, view));
}
......@@ -162,30 +162,30 @@ OpenAssessment.StudioView.prototype = {
view.updateEditorContext();
}
}
).fail(function (errMsg) {
).fail(function(errMsg) {
view.showError(errMsg);
});
}
},
/**
Make the user confirm that he/she wants to update a problem
that has already been released.
Args:
onConfirm (function): A function that accepts no arguments,
executed if the user confirms the update.
**/
confirmPostReleaseUpdate: function (onConfirm) {
Make the user confirm that he/she wants to update a problem
that has already been released.
Args:
onConfirm (function): A function that accepts no arguments,
executed if the user confirms the update.
**/
confirmPostReleaseUpdate: function(onConfirm) {
var msg = gettext("This problem has already been released. Any changes will apply only to future assessments.");
// TODO: classier confirm dialog
if (confirm(msg)) { onConfirm(); }
},
/**
Save the updated problem definition to the server.
**/
updateEditorContext: function () {
Save the updated problem definition to the server.
**/
updateEditorContext: function() {
// Notify the client-side runtime that we are starting
// to save so it can show the "Saving..." notification
this.runtime.notify('save', {state: 'start'});
......@@ -209,16 +209,16 @@ OpenAssessment.StudioView.prototype = {
// Notify the client-side runtime that we finished saving
// so it can hide the "Saving..." notification.
// Then reload the view.
function () { view.runtime.notify('save', {state: 'end'}); }
function() { view.runtime.notify('save', {state: 'end'}); }
).fail(
function (msg) { view.showError(msg); }
function(msg) { view.showError(msg); }
);
},
/**
Cancel editing.
**/
cancel: function () {
Cancel editing.
**/
cancel: function() {
// Notify the client-side runtime so it will close the editing modal
this.saveTabState();
this.runtime.notify('cancel', {});
......@@ -228,19 +228,19 @@ OpenAssessment.StudioView.prototype = {
Display an error message to the user.
Args:
errorMsg (string): The error message to display.
errorMsg (string): The error message to display.
**/
showError: function (errorMsg) {
showError: function(errorMsg) {
this.runtime.notify('error', {msg: errorMsg});
},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the view is valid.
Returns:
Boolean indicating whether the view is valid.
**/
**/
validate: function() {
var settingsValid = this.settingsView.validate();
var rubricValid = this.rubricView.validate();
......@@ -248,14 +248,14 @@ OpenAssessment.StudioView.prototype = {
return settingsValid && rubricValid && promptsValid;
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
Returns:
list of string
**/
**/
validationErrors: function() {
return this.settingsView.validationErrors().concat(
this.rubricView.validationErrors().concat(
......@@ -265,23 +265,22 @@ OpenAssessment.StudioView.prototype = {
},
/**
Clear all validation errors from the UI.
**/
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {
this.settingsView.clearValidationErrors();
this.rubricView.clearValidationErrors();
this.promptsView.clearValidationErrors();
},
}
};
/* XBlock entry point for Studio view */
/* jshint unused:false */
function OpenAssessmentEditor(runtime, element, data) {
/**
Initialize the editing interface on page load.
**/
Initialize the editing interface on page load.
**/
var server = new OpenAssessment.Server(runtime, element);
new OpenAssessment.StudioView(runtime, element, server, data);
}
/**
Interface for editing peer assessment settings.
Interface for editing peer assessment settings.
Args:
element (DOM element): The DOM element representing this view.
Args:
element (DOM element): The DOM element representing this view.
Returns:
OpenAssessment.EditPeerAssessmentView
Returns:
OpenAssessment.EditPeerAssessmentView
**/
**/
OpenAssessment.EditPeerAssessmentView = function(element) {
this.element = element;
this.name = "peer-assessment";
this.mustGradeField = new OpenAssessment.IntField(
$("#peer_assessment_must_grade", this.element),
{ min: 0, max: 99 }
{min: 0, max: 99}
);
this.mustBeGradedByField = new OpenAssessment.IntField(
$("#peer_assessment_graded_by", this.element),
{ min: 0, max: 99 }
{min: 0, max: 99}
);
// Configure the toggle checkbox to enable/disable this assessment
......@@ -47,20 +47,20 @@ OpenAssessment.EditPeerAssessmentView = function(element) {
OpenAssessment.EditPeerAssessmentView.prototype = {
/**
Return a description of the assessment.
Returns:
object literal
Example usage:
>>> editPeerView.description();
{
must_grade: 5,
must_be_graded_by: 2,
start: null,
due: "2014-04-1T00:00"
}
**/
Return a description of the assessment.
Returns:
object literal
Example usage:
>>> editPeerView.description();
{
must_grade: 5,
must_be_graded_by: 2,
start: null,
due: "2014-04-1T00:00"
}
**/
description: function() {
return {
must_grade: this.mustGradeNum(),
......@@ -71,100 +71,100 @@ OpenAssessment.EditPeerAssessmentView.prototype = {
},
/**
Get or set whether the assessment is enabled.
Get or set whether the assessment is enabled.
Args:
isEnabled (boolean, optional): If provided, set the enabled state of the assessment.
Args:
isEnabled (boolean, optional): If provided, set the enabled state of the assessment.
Returns:
boolean
***/
Returns:
boolean
***/
isEnabled: function(isEnabled) {
var sel = $("#include_peer_assessment", this.element);
return OpenAssessment.Fields.booleanField(sel, isEnabled);
},
/**
Toggle whether the assessment is enabled or disabled.
This triggers the actual click event and is mainly useful for testing.
**/
Toggle whether the assessment is enabled or disabled.
This triggers the actual click event and is mainly useful for testing.
**/
toggleEnabled: function() {
$("#include_peer_assessment", this.element).click();
},
/**
Get or set the required number of submissions a student must peer-assess.
Get or set the required number of submissions a student must peer-assess.
Args:
num (int, optional): If provided, set the required number of assessments.
Args:
num (int, optional): If provided, set the required number of assessments.
Returns:
int
**/
Returns:
int
**/
mustGradeNum: function(num) {
if (num !== undefined) { this.mustGradeField.set(num); }
return this.mustGradeField.get();
},
/**
Get or set the required number of peer-assessments a student must receive.
Get or set the required number of peer-assessments a student must receive.
Args:
num (int, optional): If provided, set the required number of assessments.
Args:
num (int, optional): If provided, set the required number of assessments.
Returns:
int
**/
Returns:
int
**/
mustBeGradedByNum: function(num) {
if (num !== undefined) { this.mustBeGradedByField.set(num); }
return this.mustBeGradedByField.get();
},
/**
Get or set the start date and time of the assessment.
Get or set the start date and time of the assessment.
Args:
dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Args:
dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Returns:
string (ISO-formatted UTC datetime)
**/
Returns:
string (ISO-formatted UTC datetime)
**/
startDatetime: function(dateString, timeString) {
return this.startDatetimeControl.datetime(dateString, timeString);
},
/**
Get or set the due date and time of the assessment.
Get or set the due date and time of the assessment.
Args:
dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Args:
dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Returns:
string (ISO-formatted UTC datetime)
**/
Returns:
string (ISO-formatted UTC datetime)
**/
dueDatetime: function(dateString, timeString) {
return this.dueDatetimeControl.datetime(dateString, timeString);
},
/**
Gets the ID of the assessment
Gets the ID of the assessment
Returns:
string (CSS ID of the Element object)
**/
Returns:
string (CSS ID of the Element object)
**/
getID: function() {
return $(this.element).attr('id');
},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the view is valid.
Returns:
Boolean indicating whether the view is valid.
**/
**/
validate: function() {
var startValid = this.startDatetimeControl.validate();
var dueValid = this.dueDatetimeControl.validate();
......@@ -173,14 +173,14 @@ OpenAssessment.EditPeerAssessmentView.prototype = {
return startValid && dueValid && mustGradeValid && mustBeGradedByValid;
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
Returns:
list of string
**/
**/
validationErrors: function() {
var errors = [];
if (this.startDatetimeControl.validationErrors().length > 0) {
......@@ -192,15 +192,15 @@ OpenAssessment.EditPeerAssessmentView.prototype = {
if (this.mustGradeField.validationErrors().length > 0) {
errors.push("Peer assessment must grade is invalid");
}
if(this.mustBeGradedByField.validationErrors().length > 0) {
if (this.mustBeGradedByField.validationErrors().length > 0) {
errors.push("Peer assessment must be graded by is invalid");
}
return errors;
},
/**
Clear all validation errors from the UI.
**/
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {
this.startDatetimeControl.clearValidationErrors();
this.dueDatetimeControl.clearValidationErrors();
......@@ -209,17 +209,16 @@ OpenAssessment.EditPeerAssessmentView.prototype = {
},
};
/**
Interface for editing self assessment settings.
Interface for editing self assessment settings.
Args:
element (DOM element): The DOM element representing this view.
Args:
element (DOM element): The DOM element representing this view.
Returns:
OpenAssessment.EditSelfAssessmentView
Returns:
OpenAssessment.EditSelfAssessmentView
**/
**/
OpenAssessment.EditSelfAssessmentView = function(element) {
this.element = element;
this.name = "self-assessment";
......@@ -251,19 +250,19 @@ OpenAssessment.EditSelfAssessmentView = function(element) {
OpenAssessment.EditSelfAssessmentView.prototype = {
/**
Return a description of the assessment.
Return a description of the assessment.
Returns:
object literal
Returns:
object literal
Example usage:
>>> editSelfView.description();
{
start: null,
due: "2014-04-1T00:00"
}
Example usage:
>>> editSelfView.description();
{
start: null,
due: "2014-04-1T00:00"
}
**/
**/
description: function() {
return {
start: this.startDatetime(),
......@@ -272,86 +271,86 @@ OpenAssessment.EditSelfAssessmentView.prototype = {
},
/**
Get or set whether the assessment is enabled.
Get or set whether the assessment is enabled.
Args:
isEnabled (boolean, optional): If provided, set the enabled state of the assessment.
Args:
isEnabled (boolean, optional): If provided, set the enabled state of the assessment.
Returns:
boolean
***/
Returns:
boolean
***/
isEnabled: function(isEnabled) {
var sel = $("#include_self_assessment", this.element);
return OpenAssessment.Fields.booleanField(sel, isEnabled);
},
/**
Toggle whether the assessment is enabled or disabled.
This triggers the actual click event and is mainly useful for testing.
**/
Toggle whether the assessment is enabled or disabled.
This triggers the actual click event and is mainly useful for testing.
**/
toggleEnabled: function() {
$("#include_self_assessment", this.element).click();
},
/**
Get or set the start date and time of the assessment.
Get or set the start date and time of the assessment.
Args:
dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Args:
dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Returns:
string (ISO-formatted UTC datetime)
**/
Returns:
string (ISO-formatted UTC datetime)
**/
startDatetime: function(dateString, timeString) {
return this.startDatetimeControl.datetime(dateString, timeString);
},
/**
Get or set the due date and time of the assessment.
Get or set the due date and time of the assessment.
Args:
dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Args:
dateString (string, optional): If provided, set the date (YY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Returns:
string (ISO-formatted UTC datetime)
**/
Returns:
string (ISO-formatted UTC datetime)
**/
dueDatetime: function(dateString, timeString) {
return this.dueDatetimeControl.datetime(dateString, timeString);
},
/**
Gets the ID of the assessment
Gets the ID of the assessment
Returns:
string (CSS ID of the Element object)
**/
Returns:
string (CSS ID of the Element object)
**/
getID: function() {
return $(this.element).attr('id');
},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the view is valid.
Returns:
Boolean indicating whether the view is valid.
**/
**/
validate: function() {
var startValid = this.startDatetimeControl.validate();
var dueValid = this.dueDatetimeControl.validate();
return startValid && dueValid;
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
Returns:
list of string
**/
**/
validationErrors: function() {
var errors = [];
if (this.startDatetimeControl.validationErrors().length > 0) {
......@@ -364,8 +363,8 @@ OpenAssessment.EditSelfAssessmentView.prototype = {
},
/**
Clear all validation errors from the UI.
**/
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {
this.startDatetimeControl.clearValidationErrors();
this.dueDatetimeControl.clearValidationErrors();
......@@ -373,15 +372,15 @@ OpenAssessment.EditSelfAssessmentView.prototype = {
};
/**
Interface for editing self assessment settings.
Interface for editing self assessment settings.
Args:
element (DOM element): The DOM element representing this view.
Args:
element (DOM element): The DOM element representing this view.
Returns:
OpenAssessment.EditStudentTrainingView
Returns:
OpenAssessment.EditStudentTrainingView
**/
**/
OpenAssessment.EditStudentTrainingView = function(element) {
this.element = element;
this.name = "student-training";
......@@ -411,32 +410,32 @@ OpenAssessment.EditStudentTrainingView = function(element) {
OpenAssessment.EditStudentTrainingView.prototype = {
/**
Return a description of the assessment.
Returns:
object literal
Example usage:
>>> editTrainingView.description();
{
examples: [
{
answer: ("I love pokemon 1", "I love pokemon 2"),
options_selected: [
{
criterion: "brevity",
option: "suberb"
},
criterion: "accuracy",
option: "alright"
}
...
]
},
...
]
}
**/
Return a description of the assessment.
Returns:
object literal
Example usage:
>>> editTrainingView.description();
{
examples: [
{
answer: ("I love pokemon 1", "I love pokemon 2"),
options_selected: [
{
criterion: "brevity",
option: "suberb"
},
criterion: "accuracy",
option: "alright"
}
...
]
},
...
]
}
**/
description: function() {
return {
examples: this.exampleContainer.getItemValues()
......@@ -444,44 +443,44 @@ OpenAssessment.EditStudentTrainingView.prototype = {
},
/**
Get or set whether the assessment is enabled.
Get or set whether the assessment is enabled.
Args:
isEnabled (boolean, optional): If provided, set the enabled state of the assessment.
Args:
isEnabled (boolean, optional): If provided, set the enabled state of the assessment.
Returns:
boolean
***/
Returns:
boolean
***/
isEnabled: function(isEnabled) {
var sel = $("#include_student_training", this.element);
return OpenAssessment.Fields.booleanField(sel, isEnabled);
},
/**
Toggle whether the assessment is enabled or disabled.
This triggers the actual click event and is mainly useful for testing.
**/
Toggle whether the assessment is enabled or disabled.
This triggers the actual click event and is mainly useful for testing.
**/
toggleEnabled: function() {
$("#include_student_training", this.element).click();
},
/**
Gets the ID of the assessment
Gets the ID of the assessment
Returns:
string (CSS ID of the Element object)
**/
Returns:
string (CSS ID of the Element object)
**/
getID: function() {
return $(this.element).attr('id');
},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the view is valid.
Returns:
Boolean indicating whether the view is valid.
**/
**/
validate: function() {
var isValid = true;
......@@ -493,13 +492,13 @@ OpenAssessment.EditStudentTrainingView.prototype = {
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
Returns:
list of string
**/
**/
validationErrors: function() {
var errors = [];
$.each(this.exampleContainer.getAllItems(), function() {
......@@ -509,8 +508,8 @@ OpenAssessment.EditStudentTrainingView.prototype = {
},
/**
Clear all validation errors from the UI.
**/
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {
$.each(this.exampleContainer.getAllItems(), function() {
this.clearValidationErrors();
......@@ -518,24 +517,24 @@ OpenAssessment.EditStudentTrainingView.prototype = {
},
/**
Adds a new training example by copying the training example template.
Primarily used for testing.
**/
Adds a new training example by copying the training example template.
Primarily used for testing.
**/
addTrainingExample: function() {
this.exampleContainer.add();
}
};
/**
Interface for editing example-based assessment settings.
Interface for editing example-based assessment settings.
Args:
element (DOM element): The DOM element representing this view.
Args:
element (DOM element): The DOM element representing this view.
Returns:
OpenAssessment.EditExampleBasedAssessmentView
Returns:
OpenAssessment.EditExampleBasedAssessmentView
**/
**/
OpenAssessment.EditExampleBasedAssessmentView = function(element) {
this.element = element;
this.name = "example-based-assessment";
......@@ -553,18 +552,18 @@ OpenAssessment.EditExampleBasedAssessmentView = function(element) {
OpenAssessment.EditExampleBasedAssessmentView.prototype = {
/**
Return a description of the assessment.
Return a description of the assessment.
Returns:
object literal
Returns:
object literal
Example usage:
>>> editTrainingView.description();
{
examples_xml: "XML DEFINITION HERE",
}
Example usage:
>>> editTrainingView.description();
{
examples_xml: "XML DEFINITION HERE",
}
**/
**/
description: function() {
return {
examples_xml: this.exampleDefinitions()
......@@ -572,53 +571,53 @@ OpenAssessment.EditExampleBasedAssessmentView.prototype = {
},
/**
Get or set whether the assessment is enabled.
Get or set whether the assessment is enabled.
Args:
isEnabled (boolean, optional): If provided, set the enabled state of the assessment.
Args:
isEnabled (boolean, optional): If provided, set the enabled state of the assessment.
Returns:
boolean
***/
Returns:
boolean
***/
isEnabled: function(isEnabled) {
var sel = $("#include_ai_assessment", this.element);
return OpenAssessment.Fields.booleanField(sel, isEnabled);
},
/**
Toggle whether the assessment is enabled or disabled.
This triggers the actual click event and is mainly useful for testing.
**/
Toggle whether the assessment is enabled or disabled.
This triggers the actual click event and is mainly useful for testing.
**/
toggleEnabled: function() {
$("#include_ai_assessment", this.element).click();
},
/**
Get or set the XML defining the training examples.
Get or set the XML defining the training examples.
Args:
xml (string, optional): The XML of the training example definitions.
Args:
xml (string, optional): The XML of the training example definitions.
Returns:
string
Returns:
string
**/
**/
exampleDefinitions: function(xml) {
var sel = $("#ai_training_examples", this.element);
return OpenAssessment.Fields.stringField(sel, xml);
},
/**
Gets the ID of the assessment
Gets the ID of the assessment
Returns:
string (CSS ID of the Element object)
**/
Returns:
string (CSS ID of the Element object)
**/
getID: function() {
return $(this.element).attr('id');
},
validate: function() { return true; },
validationErrors: function() { return []; },
clearValidationErrors: function() {},
};
\ No newline at end of file
clearValidationErrors: function() {}
};
/**
Utilities for reading / writing fields.
**/
Utilities for reading / writing fields.
**/
OpenAssessment.Fields = {
stringField: function(sel, value) {
if (value !== undefined) { sel.val(value); }
......@@ -10,21 +10,20 @@ OpenAssessment.Fields = {
booleanField: function(sel, value) {
if (value !== undefined) { sel.prop("checked", value); }
return sel.prop("checked");
},
}
};
/**
Integer input.
Integer input.
Args:
inputSel (JQuery selector or DOM element): The input field.
Args:
inputSel (JQuery selector or DOM element): The input field.
Keyword args:
min (int): The minimum value allowed in the input.
max (int): The maximum value allowed in the input.
Keyword args:
min (int): The minimum value allowed in the input.
max (int): The maximum value allowed in the input.
**/
**/
OpenAssessment.IntField = function(inputSel, restrictions) {
this.max = restrictions.max;
this.min = restrictions.min;
......@@ -34,39 +33,39 @@ OpenAssessment.IntField = function(inputSel, restrictions) {
OpenAssessment.IntField.prototype = {
/**
Retrieve the integer value from the input.
Decimal values will be truncated, and non-numeric
values will become NaN.
Retrieve the integer value from the input.
Decimal values will be truncated, and non-numeric
values will become NaN.
Returns:
integer or NaN
**/
Returns:
integer or NaN
**/
get: function() {
return parseInt(this.input.val().trim(), 10);
},
/**
Set the input value.
Set the input value.
Args:
val (int or string)
Args:
val (int or string)
**/
**/
set: function(val) {
this.input.val(val);
},
/**
Mark validation errors if the field does not satisfy the restrictions.
Fractional values are not considered valid integers.
Mark validation errors if the field does not satisfy the restrictions.
Fractional values are not considered valid integers.
This will trim whitespace from the field, so " 34 " would be considered
a valid input.
This will trim whitespace from the field, so " 34 " would be considered
a valid input.
Returns:
Boolean indicating whether the field's value is valid.
Returns:
Boolean indicating whether the field's value is valid.
**/
**/
validate: function() {
var value = this.get();
var isValid = !isNaN(value) && value >= this.min && value <= this.max;
......@@ -83,41 +82,40 @@ OpenAssessment.IntField.prototype = {
},
/**
Clear any validation errors from the UI.
**/
Clear any validation errors from the UI.
**/
clearValidationErrors: function() {
this.input.removeClass("openassessment_highlighted_field");
},
/**
Return a list of validation errors currently displayed
in the UI. Mainly useful for testing.
Return a list of validation errors currently displayed
in the UI. Mainly useful for testing.
Returns:
list of strings
Returns:
list of strings
**/
**/
validationErrors: function() {
var hasError = this.input.hasClass("openassessment_highlighted_field");
return hasError ? ["Int field is invalid"] : [];
},
}
};
/**
Show and hide elements based on a checkbox.
Args:
checkboxSel (JQuery selector): The checkbox used to toggle whether sections
are shown or hidden.
shownSel (JQuery selector): The section to show when the checkbox is checked.
hiddenSel (JQuery selector): The section to show when the checkbox is unchecked.
notifier (OpenAssessment.Notifier): Receives notifications when the checkbox state changes.
Sends the following notifications:
* toggleOn
* toggleOff
**/
Show and hide elements based on a checkbox.
Args:
checkboxSel (JQuery selector): The checkbox used to toggle whether sections
are shown or hidden.
shownSel (JQuery selector): The section to show when the checkbox is checked.
hiddenSel (JQuery selector): The section to show when the checkbox is unchecked.
notifier (OpenAssessment.Notifier): Receives notifications when the checkbox state changes.
Sends the following notifications:
* toggleOn
* toggleOff
**/
OpenAssessment.ToggleControl = function(checkboxSel, shownSel, hiddenSel, notifier) {
this.checkbox = checkboxSel;
this.shownSection = shownSel;
......@@ -127,15 +125,15 @@ OpenAssessment.ToggleControl = function(checkboxSel, shownSel, hiddenSel, notifi
OpenAssessment.ToggleControl.prototype = {
/**
Install the event handler for the checkbox,
passing in the toggle control object as the event data.
Install the event handler for the checkbox,
passing in the toggle control object as the event data.
Args:
checkboxSelector (string): The CSS selector string for the checkbox.
Args:
checkboxSelector (string): The CSS selector string for the checkbox.
Returns:
OpenAssessment.ToggleControl
**/
Returns:
OpenAssessment.ToggleControl
**/
install: function() {
this.checkbox.change(
this, function(event) {
......@@ -164,16 +162,15 @@ OpenAssessment.ToggleControl.prototype = {
}
};
/**
Date and time input fields.
Date and time input fields.
Args:
element (DOM element): The parent element of the control inputs.
datePicker (string): The CSS selector for the date input field.
timePicker (string): The CSS selector for the time input field.
Args:
element (DOM element): The parent element of the control inputs.
datePicker (string): The CSS selector for the date input field.
timePicker (string): The CSS selector for the time input field.
**/
**/
OpenAssessment.DatetimeControl = function(element, datePicker, timePicker) {
this.element = element;
this.datePicker = datePicker;
......@@ -182,15 +179,15 @@ OpenAssessment.DatetimeControl = function(element, datePicker, timePicker) {
OpenAssessment.DatetimeControl.prototype = {
/**
Configure the date and time picker inputs.
Configure the date and time picker inputs.
Returns:
OpenAssessment.DatetimeControl
Returns:
OpenAssessment.DatetimeControl
**/
**/
install: function() {
var dateString = $(this.datePicker, this.element).val();
$(this.datePicker, this.element).datepicker({ showButtonPanel: true })
$(this.datePicker, this.element).datepicker({showButtonPanel: true})
.datepicker("option", "dateFormat", "yy-mm-dd")
.datepicker("setDate", dateString);
$(this.timePicker, this.element).timepicker({
......@@ -201,16 +198,16 @@ OpenAssessment.DatetimeControl.prototype = {
},
/**
Get or set the date and time.
Get or set the date and time.
Args:
dateString (string, optional): If provided, set the date (YYYY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Args:
dateString (string, optional): If provided, set the date (YYYY-MM-DD).
timeString (string, optional): If provided, set the time (HH:MM, 24-hour clock).
Returns:
ISO-formatted datetime string.
Returns:
ISO-formatted datetime string.
**/
**/
datetime: function(dateString, timeString) {
var datePickerSel = $(this.datePicker, this.element);
var timePickerSel = $(this.timePicker, this.element);
......@@ -220,12 +217,12 @@ OpenAssessment.DatetimeControl.prototype = {
},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the fields are valid.
Returns:
Boolean indicating whether the fields are valid.
**/
**/
validate: function() {
var dateString = $(this.datePicker, this.element).val();
var timeString = $(this.timePicker, this.element).val();
......@@ -247,7 +244,7 @@ OpenAssessment.DatetimeControl.prototype = {
//time validation
var matches = timeString.match(/^\d{2}:\d{2}$/g);
var isTimeValid = (matches !== null);
if(!isTimeValid) {
if (!isTimeValid) {
$(this.timePicker, this.element).addClass("openassessment_highlighted_field");
}
......@@ -255,21 +252,21 @@ OpenAssessment.DatetimeControl.prototype = {
},
/**
Clear all validation errors from the UI.
**/
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {
$(this.datePicker, this.element).removeClass("openassessment_highlighted_field");
$(this.timePicker, this.element).removeClass("openassessment_highlighted_field");
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
Returns:
list of string
**/
**/
validationErrors: function() {
var errors = [];
var dateHasError = $(this.datePicker, this.element).hasClass("openassessment_highlighted_field");
......@@ -279,24 +276,23 @@ OpenAssessment.DatetimeControl.prototype = {
if (timeHasError) { errors.push("Time is invalid"); }
return errors;
},
}
};
/**
Show and hide elements based on select options.
Args:
selectSel (JQuery selector): The select used to toggle whether sections
are shown or hidden.
mapping (Object): A mapping object that is used to specify the relationship
between option and section. e.g.
{
option1: selector1,
option2: selector2,
}
When an option is selected, the section is shown and all other sections will be hidden.
notifier (OpenAssessment.Notifier): Receives notifications when the select state changes.
selectSel (JQuery selector): The select used to toggle whether sections
are shown or hidden.
mapping (Object): A mapping object that is used to specify the relationship
between option and section. e.g.
{
option1: selector1,
option2: selector2,
}
When an option is selected, the section is shown and all other sections will be hidden.
notifier (OpenAssessment.Notifier): Receives notifications when the select state changes.
Sends the following notifications:
* selectionChanged
......@@ -343,9 +339,9 @@ OpenAssessment.SelectControl.prototype = {
This is similar to string field but allow you to pass in a custom validation function to validate the input field.
Args:
inputSel (JQuery selector or DOM element): The input field.
validator (callable): The callback for custom validation function. The function should accept
one parameter for the value of the input and returns an array of errors strings. If not error, return [].
inputSel (JQuery selector or DOM element): The input field.
validator (callable): The callback for custom validation function. The function should accept
one parameter for the value of the input and returns an array of errors strings. If not error, return [].
*/
OpenAssessment.InputControl = function(inputSel, validator) {
this.input = $(inputSel);
......@@ -359,7 +355,7 @@ OpenAssessment.InputControl.prototype = {
Retrieve the string value from the input.
Returns:
string
string
**/
get: function() {
return this.input.val();
......@@ -369,7 +365,7 @@ OpenAssessment.InputControl.prototype = {
Set the input value.
Args:
val (string)
val (string)
**/
set: function(val) {
......@@ -380,7 +376,7 @@ OpenAssessment.InputControl.prototype = {
Mark validation errors if the field does not pass the validation callback function.
Returns:
Boolean indicating whether the field's value is valid.
Boolean indicating whether the field's value is valid.
**/
validate: function() {
......@@ -407,7 +403,7 @@ OpenAssessment.InputControl.prototype = {
in the UI.
Returns:
list of strings that contain error messages
list of strings that contain error messages
**/
validationErrors: function() {
......
/**
Dynamically update student training examples based on
changes to the prompts or the rubric.
**/
Dynamically update student training examples based on
changes to the prompts or the rubric.
**/
OpenAssessment.StudentTrainingListener = function() {
this.element = $('#oa_student_training_editor');
this.alert = new OpenAssessment.ValidationAlert();
......@@ -10,7 +10,7 @@ OpenAssessment.StudentTrainingListener = function() {
OpenAssessment.StudentTrainingListener.prototype = {
/**
Add a answer part in the training examples when a prompt is added.
Add a answer part in the training examples when a prompt is added.
*/
promptAdd: function() {
var view = this.element;
......@@ -23,7 +23,7 @@ OpenAssessment.StudentTrainingListener.prototype = {
},
/**
Remove the answer part in the training examples when a prompt is removed.
Remove the answer part in the training examples when a prompt is removed.
*/
promptRemove: function(data) {
var view = this.element;
......@@ -35,11 +35,11 @@ OpenAssessment.StudentTrainingListener.prototype = {
been updated.
Args:
criterionName (str): The name of the criterion that contains the updated
option.
name (str): The name of the option.
label (str): The label for the option.
points (int): The point value for the option.
criterionName (str): The name of the criterion that contains the updated
option.
name (str): The name of the option.
label (str): The label for the option.
points (int): The point value for the option.
*/
optionUpdated: function(data) {
this._optionSel(data.criterionName).each(
......@@ -63,11 +63,11 @@ OpenAssessment.StudentTrainingListener.prototype = {
HTML. This will be resolved server-side.
Args:
criterionName (str): The name of the criterion that will have an
additional option.
name (str): The name of the new option.
label (str): The new option label.
points (int): The point value of the new option.
criterionName (str): The name of the criterion that will have an
additional option.
name (str): The name of the new option.
label (str): The new option label.
points (int): The point value of the new option.
*/
optionAdd: function(data) {
// First, check to see if the criterion exists on the training examples
......@@ -93,10 +93,9 @@ OpenAssessment.StudentTrainingListener.prototype = {
});
if (criterionAdded) {
/* jshint maxlen:300 */
this.displayAlertMsg(
gettext("Criterion Added"),
gettext("You have added a criterion. You will need to select an option for the criterion in the Learner Training step. To do this, click the Settings tab.")
gettext("You have added a criterion. You will need to select an option for the criterion in the Learner Training step. To do this, click the Settings tab.") // jscs:ignore maximumLineLength
);
}
},
......@@ -111,9 +110,9 @@ OpenAssessment.StudentTrainingListener.prototype = {
invoked.
Args:
criterionName (str): The name of the criterion where the option is
being removed.
name (str): The option being removed.
criterionName (str): The name of the criterion where the option is
being removed.
name (str): The option being removed.
*/
optionRemove: function(data) {
......@@ -123,10 +122,10 @@ OpenAssessment.StudentTrainingListener.prototype = {
var criterionOption = this;
if ($(criterionOption).val() === data.name.toString()) {
$(criterionOption).val("")
.addClass("openassessment_highlighted_field")
.click(function() {
$(criterionOption).removeClass("openassessment_highlighted_field");
});
.addClass("openassessment_highlighted_field")
.click(function() {
$(criterionOption).removeClass("openassessment_highlighted_field");
});
invalidated = true;
}
......@@ -141,10 +140,9 @@ OpenAssessment.StudentTrainingListener.prototype = {
});
if (invalidated) {
/* jshint maxlen:300 */
this.displayAlertMsg(
gettext("Option Deleted"),
gettext("You have deleted an option. That option has been removed from its criterion in the sample responses in the Learner Training step. You might have to select a new option for the criterion.")
gettext("You have deleted an option. That option has been removed from its criterion in the sample responses in the Learner Training step. You might have to select a new option for the criterion.") // jscs:ignore maximumLineLength
);
}
},
......@@ -163,7 +161,7 @@ OpenAssessment.StudentTrainingListener.prototype = {
notified.
Args:
criterionName (str): The criterion where all options have been removed.
criterionName (str): The criterion where all options have been removed.
*/
removeAllOptions: function(data) {
......@@ -177,10 +175,9 @@ OpenAssessment.StudentTrainingListener.prototype = {
});
if (changed) {
/* jshint maxlen:300 */
this.displayAlertMsg(
gettext("Option Deleted"),
gettext("You have deleted all the options for this criterion. The criterion has been removed from the sample responses in the Learner Training step.")
gettext("You have deleted all the options for this criterion. The criterion has been removed from the sample responses in the Learner Training step.") // jscs:ignore maximumLineLength
);
}
},
......@@ -191,7 +188,7 @@ OpenAssessment.StudentTrainingListener.prototype = {
to reflect this change.
Args:
criterionName (str): The name of the criterion removed.
criterionName (str): The name of the criterion removed.
*/
criterionRemove: function(data) {
......@@ -199,16 +196,15 @@ OpenAssessment.StudentTrainingListener.prototype = {
var sel = '.openassessment_training_example_criterion[data-criterion="' + data.criterionName + '"]';
$(sel, this.element).each(
function() {
$(this).remove();
$(this).remove();
changed = true;
}
);
if (changed) {
/* jshint maxlen:300 */
this.displayAlertMsg(
gettext("Criterion Deleted"),
gettext("You have deleted a criterion. The criterion has been removed from the example responses in the Learner Training step.")
gettext("You have deleted a criterion. The criterion has been removed from the example responses in the Learner Training step.") // jscs:ignore maximumLineLength
);
}
},
......@@ -218,14 +214,14 @@ OpenAssessment.StudentTrainingListener.prototype = {
at least one training example, and that student training is enabled.
Args:
title (str): Title of the alert message.
msg (str): Message body for the alert.
title (str): Title of the alert message.
msg (str): Message body for the alert.
*/
displayAlertMsg: function(title, msg) {
if ($("#include_student_training", this.element).is(":checked") &&
// Check for at least more than one example, to exclude the template
$(".openassessment_training_example", this.element).length > 1) {
$(".openassessment_training_example", this.element).length > 1) {
this.alert.setMessage(title, msg).show();
}
},
......@@ -235,8 +231,8 @@ OpenAssessment.StudentTrainingListener.prototype = {
has changed in the rubric.
Args:
criterionName (str): Name of the criterion
criterionLabel (str): New label to replace on the training examples.
criterionName (str): Name of the criterion
criterionLabel (str): New label to replace on the training examples.
*/
criterionUpdated: function(data) {
var sel = '.openassessment_training_example_criterion[data-criterion="' + data.criterionName + '"]';
......@@ -255,8 +251,8 @@ OpenAssessment.StudentTrainingListener.prototype = {
examples.
Args:
criterionName (str): The name of the criterion being added.
label (str): The label for the new criterion.
criterionName (str): The name of the criterion being added.
label (str): The label for the new criterion.
*/
criterionAdd: function(data) {
var view = this.element;
......@@ -275,23 +271,23 @@ OpenAssessment.StudentTrainingListener.prototype = {
},
/**
Retrieve the available criteria labels for training examples.
This is mainly useful for testing.
Retrieve the available criteria labels for training examples.
This is mainly useful for testing.
The returned array will always contain an extra example
for the client-side template for new examples.
The returned array will always contain an extra example
for the client-side template for new examples.
Returns:
Array of object literals mapping criteria names to labels.
Returns:
Array of object literals mapping criteria names to labels.
Example usage:
>>> listener.examplesCriteriaLabels();
>>> [
>>> { criterion_1: "abcd", criterion_2: "xyz" },
>>> { criterion_1: "abcd", criterion_2: "xyz" }
>>> ]
Example usage:
>>> listener.examplesCriteriaLabels();
>>> [
>>> { criterion_1: "abcd", criterion_2: "xyz" },
>>> { criterion_1: "abcd", criterion_2: "xyz" }
>>> ]
**/
**/
examplesCriteriaLabels: function() {
var examples = [];
$(".openassessment_training_example_criteria_selections", this.element).each(
......@@ -312,34 +308,34 @@ OpenAssessment.StudentTrainingListener.prototype = {
},
/**
Retrieve the available option labels for training examples.
This is mainly useful for testing.
Retrieve the available option labels for training examples.
This is mainly useful for testing.
The returned array will always contain an extra example
for the client-side template for new examples.
The returned array will always contain an extra example
for the client-side template for new examples.
Returns:
Array of object literals
Returns:
Array of object literals
Example usage:
>>> listener.examplesOptionsLabels();
>>> [
>>> {
Example usage:
>>> listener.examplesOptionsLabels();
>>> [
>>> {
>>> criterion_1: {
>>> "": "Not Scored",
>>> option_1: "First Option - 1 points",
>>> option_2: "Second Option - 2 points",
>>> }
>>> },
>>> {
>>> {
>>> criterion_1: {
>>> "": "Not Scored",
>>> option_1: "First Option - 1 points",
>>> option_2: "Second Option - 2 points",
>>> }
>>> }
>>> ]
**/
>>> ]
**/
examplesOptionsLabels: function() {
var examples = [];
$(".openassessment_training_example_criteria_selections", this.element).each(
......@@ -365,12 +361,11 @@ OpenAssessment.StudentTrainingListener.prototype = {
}
};
/**
Show a warning when a user disables an assessment,
since any data in the disabled section won't be persisted
on save.
**/
Show a warning when a user disables an assessment,
since any data in the disabled section won't be persisted
on save.
**/
OpenAssessment.AssessmentToggleListener = function() {
this.alert = new OpenAssessment.ValidationAlert();
};
......
......@@ -44,4 +44,4 @@ OpenAssessment.Notifier.prototype = {
}
}
}
};
\ No newline at end of file
};
/**
Editing interface for the prompts.
Editing interface for the prompts.
Args:
element (DOM element): The DOM element representing this view.
Args:
element (DOM element): The DOM element representing this view.
Returns:
OpenAssessment.EditPromptsView
Returns:
OpenAssessment.EditPromptsView
**/
**/
OpenAssessment.EditPromptsView = function(element, notifier) {
this.element = element;
this.editorElement = $(this.element).closest("#openassessment-editor");
......@@ -27,36 +27,35 @@ OpenAssessment.EditPromptsView = function(element, notifier) {
this.promptsContainer.addEventListeners();
};
OpenAssessment.EditPromptsView.prototype = {
/**
Construct a list of prompts definitions from the editor UI.
Returns:
list of prompt objects
Example usage:
>>> editPromptsView.promptsDefinition();
[
{
uuid: "cfvgbh657",
description: "Description",
order_num: 0,
},
...
]
**/
Construct a list of prompts definitions from the editor UI.
Returns:
list of prompt objects
Example usage:
>>> editPromptsView.promptsDefinition();
[
{
uuid: "cfvgbh657",
description: "Description",
order_num: 0,
},
...
]
**/
promptsDefinition: function() {
var prompts = this.promptsContainer.getItemValues();
return prompts;
},
/**
Add a new prompt.
Uses a client-side template to create the new prompt.
**/
Add a new prompt.
Uses a client-side template to create the new prompt.
**/
addPrompt: function() {
if (this.addRemoveEnabled) {
this.promptsContainer.add();
......@@ -64,11 +63,11 @@ OpenAssessment.EditPromptsView.prototype = {
},
/**
Remove a prompt.
Remove a prompt.
Args:
item (OpenAssessment.RubricCriterion): The criterion item to remove.
**/
Args:
item (OpenAssessment.RubricCriterion): The criterion item to remove.
**/
removePrompt: function(item) {
if (this.addRemoveEnabled) {
this.promptsContainer.remove(item);
......@@ -76,56 +75,56 @@ OpenAssessment.EditPromptsView.prototype = {
},
/**
Retrieve all prompts.
Retrieve all prompts.
Returns:
Array of OpenAssessment.Prompt objects.
Returns:
Array of OpenAssessment.Prompt objects.
**/
**/
getAllPrompts: function() {
return this.promptsContainer.getAllItems();
},
/**
Retrieve a prompt item from the prompts.
Retrieve a prompt item from the prompts.
Args:
index (int): The index of the prompt, starting from 0.
Args:
index (int): The index of the prompt, starting from 0.
Returns:
OpenAssessment.Prompt or null
Returns:
OpenAssessment.Prompt or null
**/
**/
getPromptItem: function(index) {
return this.promptsContainer.getItem(index);
},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the view is valid.
Returns:
Boolean indicating whether the view is valid.
**/
**/
validate: function() {
return true;
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
Returns:
list of string
**/
**/
validationErrors: function() {
var errors = [];
return errors;
},
/**
Clear all validation errors from the UI.
**/
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {}
};
\ No newline at end of file
};
/**
Interface for editing rubric definitions.
Interface for editing rubric definitions.
Args:
element (DOM element): The DOM element representing the rubric.
notifier (OpenAssessment.Notifier): Used to notify other views about updates to the rubric.
Args:
element (DOM element): The DOM element representing the rubric.
notifier (OpenAssessment.Notifier): Used to notify other views about updates to the rubric.
This view fires the following notification events:
* optionAdd: An option was added to the rubric.
* optionRemove: An option was removed from the rubric.
* optionUpdated: An option's label and/or points were updated in the rubric.
* criterionRemove: A criterion was removed from the rubric.
* criterionUpdated: A criterion's label was updated in the rubric.
This view fires the following notification events:
* optionAdd: An option was added to the rubric.
* optionRemove: An option was removed from the rubric.
* optionUpdated: An option's label and/or points were updated in the rubric.
* criterionRemove: A criterion was removed from the rubric.
* criterionUpdated: A criterion's label was updated in the rubric.
**/
**/
OpenAssessment.EditRubricView = function(element, notifier) {
this.element = element;
this.criterionAddButton = $('#openassessment_rubric_add_criterion', this.element);
......@@ -32,43 +32,43 @@ OpenAssessment.EditRubricView = function(element, notifier) {
OpenAssessment.EditRubricView.prototype = {
/**
Construct a list of criteria definitions from the editor UI.
Returns:
list of criteria objects
Example usage:
>>> editRubricView.criteriaDefinition();
[
{
name: "Criterion",
prompt: "Prompt",
order_num: 0,
feedback: "disabled",
options: [
{
order_num: 0,
points: 1,
name: "Good",
explanation: "Explanation"
},
...
]
},
...
]
**/
Construct a list of criteria definitions from the editor UI.
Returns:
list of criteria objects
Example usage:
>>> editRubricView.criteriaDefinition();
[
{
name: "Criterion",
prompt: "Prompt",
order_num: 0,
feedback: "disabled",
options: [
{
order_num: 0,
points: 1,
name: "Good",
explanation: "Explanation"
},
...
]
},
...
]
**/
criteriaDefinition: function() {
var criteria = this.criteriaContainer.getItemValues();
// Add order_num fields for criteria and options
for (var criterion_idx = 0; criterion_idx < criteria.length; criterion_idx++) {
var criterion = criteria[criterion_idx];
criterion.order_num = criterion_idx;
for (var option_idx = 0; option_idx < criterion.options.length; option_idx++) {
var option = criterion.options[option_idx];
option.order_num = option_idx;
for (var criterionIndex = 0; criterionIndex < criteria.length; criterionIndex++) {
var criterion = criteria[criterionIndex];
criterion.order_num = criterionIndex;
for (var optionIndex = 0; optionIndex < criterion.options.length; optionIndex++) {
var option = criterion.options[optionIndex];
option.order_num = optionIndex;
}
}
......@@ -76,156 +76,156 @@ OpenAssessment.EditRubricView.prototype = {
},
/**
Get or set the feedback prompt in the editor.
This is the prompt shown to students when giving "overall" feedback
on a submission.
Get or set the feedback prompt in the editor.
This is the prompt shown to students when giving "overall" feedback
on a submission.
Args:
text (string, optional): If provided, set the feedback prompt to this value.
Args:
text (string, optional): If provided, set the feedback prompt to this value.
Returns:
string
Returns:
string
**/
**/
feedbackPrompt: function(text) {
var sel = $("#openassessment_rubric_feedback", this.element);
return OpenAssessment.Fields.stringField(sel, text);
},
/**
Get or set the default feedback response text in the editor.
The text is used as a student's default response to the feedback
prompt.
Get or set the default feedback response text in the editor.
The text is used as a student's default response to the feedback
prompt.
Args:
text (string, option): If provided, sets the default text to this value.
Args:
text (string, option): If provided, sets the default text to this value.
Returns:
string
Returns:
string
**/
**/
feedback_default_text: function(text) {
var sel = $("#openassessment_rubric_feedback_default_text", this.element);
return OpenAssessment.Fields.stringField(sel, text);
},
/**
Add a new criterion to the rubric.
Uses a client-side template to create the new criterion.
**/
Add a new criterion to the rubric.
Uses a client-side template to create the new criterion.
**/
addCriterion: function() {
this.criteriaContainer.add();
},
/**
Remove a criterion from the rubric.
Remove a criterion from the rubric.
Args:
item (OpenAssessment.RubricCriterion): The criterion item to remove.
**/
Args:
item (OpenAssessment.RubricCriterion): The criterion item to remove.
**/
removeCriterion: function(item) {
this.criteriaContainer.remove(item);
},
/**
Retrieve all criteria from the rubric.
Retrieve all criteria from the rubric.
Returns:
Array of OpenAssessment.RubricCriterion objects.
Returns:
Array of OpenAssessment.RubricCriterion objects.
**/
**/
getAllCriteria: function() {
return this.criteriaContainer.getAllItems();
},
/**
Retrieve a criterion item from the rubric.
Retrieve a criterion item from the rubric.
Args:
index (int): The index of the criterion, starting from 0.
Args:
index (int): The index of the criterion, starting from 0.
Returns:
OpenAssessment.RubricCriterion or null
Returns:
OpenAssessment.RubricCriterion or null
**/
**/
getCriterionItem: function(index) {
return this.criteriaContainer.getItem(index);
},
/**
Add a new option to the rubric.
Add a new option to the rubric.
Args:
criterionIndex (int): The index of the criterion to which
the option will be added (starts from 0).
Args:
criterionIndex (int): The index of the criterion to which
the option will be added (starts from 0).
**/
**/
addOption: function(criterionIndex) {
var criterionItem = this.getCriterionItem(criterionIndex);
criterionItem.optionContainer.add();
},
/**
Remove an option from the rubric.
Remove an option from the rubric.
Args:
criterionIndex (int): The index of the criterion, starting from 0.
item (OpenAssessment.RubricOption): The option item to remove.
Args:
criterionIndex (int): The index of the criterion, starting from 0.
item (OpenAssessment.RubricOption): The option item to remove.
**/
**/
removeOption: function(criterionIndex, item) {
var criterionItem = this.getCriterionItem(criterionIndex);
criterionItem.optionContainer.remove(item);
},
/**
Retrieve all options for a particular criterion.
Retrieve all options for a particular criterion.
Args:
criterionIndex (int): The index of the criterion, starting from 0.
Args:
criterionIndex (int): The index of the criterion, starting from 0.
Returns:
Array of OpenAssessment.RubricOption
**/
Returns:
Array of OpenAssessment.RubricOption
**/
getAllOptions: function(criterionIndex) {
var criterionItem = this.getCriterionItem(criterionIndex);
return criterionItem.optionContainer.getAllItems();
},
/**
Retrieve a particular option from the rubric.
Retrieve a particular option from the rubric.
Args:
criterionIndex (int): The index of the criterion, starting from 0.
optionIndex (int): The index of the option within the criterion,
starting from 0.
Args:
criterionIndex (int): The index of the criterion, starting from 0.
optionIndex (int): The index of the option within the criterion,
starting from 0.
Returns:
OpenAssessment.RubricOption
Returns:
OpenAssessment.RubricOption
**/
**/
getOptionItem: function(criterionIndex, optionIndex) {
var criterionItem = this.getCriterionItem(criterionIndex);
return criterionItem.optionContainer.getItem(optionIndex);
},
/**
Mark validation errors.
Mark validation errors.
Returns:
Boolean indicating whether the view is valid.
Returns:
Boolean indicating whether the view is valid.
**/
**/
validate: function() {
var criteria = this.getAllCriteria();
var isValid = criteria.length > 0;
if (!isValid) {
this.criterionAddButton
.addClass("openassessment_highlighted_field")
.click( function() {
$(this).removeClass("openassessment_highlighted_field");
}
);
.click(function() {
$(this).removeClass("openassessment_highlighted_field");
}
);
}
$.each(criteria, function() {
......@@ -235,14 +235,14 @@ OpenAssessment.EditRubricView.prototype = {
return isValid;
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
Returns:
list of string
**/
**/
validationErrors: function() {
var errors = [];
......@@ -259,8 +259,8 @@ OpenAssessment.EditRubricView.prototype = {
},
/**
Clear all validation errors from the UI.
**/
Clear all validation errors from the UI.
**/
clearValidationErrors: function() {
this.criterionAddButton.removeClass("openassessment_highlighted_field");
......
......@@ -38,7 +38,7 @@ OpenAssessment.EditSettingsView = function(element, assessmentViews, data) {
this.leaderboardIntField = new OpenAssessment.IntField(
$("#openassessment_leaderboard_editor", this.element),
{ min: 0, max: 100 }
{min: 0, max: 100}
);
this.fileTypeWhiteListInputField = new OpenAssessment.InputControl(
......@@ -67,13 +67,12 @@ OpenAssessment.EditSettingsView = function(element, assessmentViews, data) {
this.initializeSortableAssessments();
};
OpenAssessment.EditSettingsView.prototype = {
/**
Installs click listeners which initialize drag and drop functionality for assessment modules.
**/
initializeSortableAssessments: function () {
initializeSortableAssessments: function() {
var view = this;
// Initialize Drag and Drop of Assessment Modules
$('#openassessment_assessment_module_settings_editors', view.element).sortable({
......@@ -255,7 +254,7 @@ OpenAssessment.EditSettingsView.prototype = {
// Find all assessment modules within our element in the DOM,
// and append their definitions to the description
$('.openassessment_assessment_module_settings_editor', this.assessmentsElement).each(
function () {
function() {
var asmntView = view.assessmentViews[$(this).attr('id')];
if (asmntView.isEnabled()) {
var description = asmntView.description();
......@@ -280,7 +279,7 @@ OpenAssessment.EditSettingsView.prototype = {
var editorAssessments = [];
var view = this;
$('.openassessment_assessment_module_settings_editor', this.assessmentsElement).each(
function () {
function() {
var asmntView = view.assessmentViews[$(this).attr('id')];
editorAssessments.push(asmntView.name);
}
......
......@@ -48,7 +48,7 @@ OpenAssessment.ValidationAlert.prototype = {
'border-top-left-radius': '3px'
};
$('.oa_editor_content_wrapper', this.editorElement).each( function () {
$('.oa_editor_content_wrapper', this.editorElement).each(function() {
$(this).css(styles);
});
......@@ -61,12 +61,12 @@ OpenAssessment.ValidationAlert.prototype = {
Returns:
OpenAssessment.ValidationAlert
*/
show : function() {
show: function() {
var view = this;
if (this.isVisible()){
if (this.isVisible()) {
$(this.element).animate(
{'background-color': view.ALERT_YELLOW}, 300, 'swing', function () {
{'background-color': view.ALERT_YELLOW}, 300, 'swing', function() {
$(this).animate({'background-color': view.DARK_GREY}, 700, 'swing');
}
);
......@@ -84,7 +84,7 @@ OpenAssessment.ValidationAlert.prototype = {
'border-top-left-radius': '0px'
};
$('.oa_editor_content_wrapper', this.editorElement).each(function () {
$('.oa_editor_content_wrapper', this.editorElement).each(function() {
$(this).css(styles);
});
......
......@@ -16,7 +16,8 @@
"phantomjs": "^1.9.11",
"sinon": "^1.10.3",
"uglify-js": "2.3.6",
"jshint": "2.8.0"
"jshint": "2.8.0",
"jscs": "2.6.0"
},
"scripts": {
"test": "./node_modules/karma/bin/karma start --reporters spec,coverage"
......
......@@ -6,7 +6,7 @@
git+https://github.com/edx/XBlock.git@xblock-0.4.1#egg=XBlock==0.4.1
# edx-submissions
git+https://github.com/edx/edx-submissions.git@0.1.2#egg=edx-submissions==0.1.2
git+https://github.com/edx/edx-submissions.git@0.1.3#egg=edx-submissions==0.1.3
# Third Party Requirements
boto>=2.32.1,<3.0.0
......
-r base.txt
-r test-acceptance.txt
coverage==3.7.1
coverage==4.0.2
django-nose==1.4.1
mock==1.0.1
moto==0.2.22
pep8==1.5.7
moto==0.3.1
pep8==1.6.2
pylint<1.0
git+https://github.com/edx/django-pyfs.git@1.0.3#egg=django-pyfs==1.0.3
......
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