Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-ora2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-ora2
Commits
9896d39f
Commit
9896d39f
authored
Mar 26, 2014
by
Will Daly
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #203 from edx/will/saved-but-not-submitted
TIM-304
parents
94a82c6b
6a28f277
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
464 additions
and
63 deletions
+464
-63
apps/openassessment/templates/openassessmentblock/response/oa_response.html
+2
-1
apps/openassessment/xblock/static/js/fixtures/oa_response.html
+55
-0
apps/openassessment/xblock/static/js/openassessment.min.js
+0
-0
apps/openassessment/xblock/static/js/spec/oa_base.js
+9
-23
apps/openassessment/xblock/static/js/spec/oa_edit.js
+14
-14
apps/openassessment/xblock/static/js/spec/oa_response.js
+127
-0
apps/openassessment/xblock/static/js/src/oa_base.js
+0
-0
apps/openassessment/xblock/static/js/src/oa_edit.js
+21
-21
apps/openassessment/xblock/static/js/src/oa_response.js
+232
-0
apps/openassessment/xblock/submission_mixin.py
+2
-1
apps/openassessment/xblock/test/test_save_response.py
+2
-3
No files found.
apps/openassessment/templates/openassessmentblock/response/oa_response.html
View file @
9896d39f
...
...
@@ -71,7 +71,8 @@
<ul
class=
"list list--actions"
>
<li
class=
"list--actions__item"
>
<a
aria-role=
"button"
href=
"#"
id=
"step--response__submit"
class=
"action action--submit step--response__submit is--disabled"
>
<a
aria-role=
"button"
href=
"#"
id=
"step--response__submit"
class=
"action action--submit step--response__submit {{ submit_enabled|yesno:"
,
is--disabled
"
}}"
>
<span
class=
"copy"
>
Submit your response and move to the next step
</span>
<i
class=
"ico icon-caret-right"
></i>
</a>
...
...
apps/openassessment/xblock/static/js/fixtures/oa_response.html
0 → 100644
View file @
9896d39f
<div
id=
"openassessment-base"
>
<ol>
<li
id=
"openassessment__response"
class=
"openassessment__steps__step step--response ui-toggle-visibility"
>
<div
class=
"ui-toggle-visibility__content"
>
<div
class=
"wrapper--step__content"
>
<div
class=
"step__content"
>
<form
id=
"response__submission"
class=
"response__submission"
>
<ol
class=
"list list--fields response__submission__content"
>
<li
class=
"field field--textarea submission__answer"
id=
"submission__answer"
>
<label
class=
"sr"
for=
"submission__answer__value"
>
Provide your response to the question.
</label>
<textarea
id=
"submission__answer__value"
placeholder=
""
></textarea>
<span
class=
"tip"
>
You may continue to work on your response until you submit it.
</span>
</li>
</ol>
<div
class=
"response__submission__actions"
>
<div
class=
"message message--inline message--error message--error-server"
>
<h3
class=
"message__title"
>
We could not save your progress
</h3>
</div>
<ul
class=
"list list--actions"
>
<li
class=
"list--actions__item"
>
<button
type=
"submit"
id=
"submission__save"
class=
"action action--save submission__save is--disabled"
>
Save Your Progress
</button>
<div
id=
"response__save_status"
class=
"response__submission__status"
>
<h3
class=
"response__submission__status__title"
>
<span
class=
"sr"
>
Your Working Submission Status:
</span>
Unsaved draft
</h3>
</div>
</li>
</ul>
</div>
</form>
</div>
<div
class=
"step__actions"
>
<div
class=
"message message--inline message--error message--error-server"
>
<h3
class=
"message__title"
>
We could not submit your response
</h3>
</div>
<ul
class=
"list list--actions"
>
<li
class=
"list--actions__item"
>
<a
aria-role=
"button"
href=
"#"
id=
"step--response__submit"
class=
"action action--submit step--response__submit is--disabled"
>
<span
class=
"copy"
>
Submit your response and move to the next step
</span>
<i
class=
"ico icon-caret-right"
></i>
</a>
</li>
</ul>
</div>
</div>
</div>
</li>
</ol>
</div>
apps/openassessment/xblock/static/js/openassessment.min.js
View file @
9896d39f
This diff is collapsed.
Click to expand it.
apps/openassessment/xblock/static/js/spec/oa_base.js
View file @
9896d39f
...
...
@@ -2,7 +2,7 @@
Tests for OA student-facing views.
**/
describe
(
"OpenAssessment.Base
UI
"
,
function
()
{
describe
(
"OpenAssessment.Base
View
"
,
function
()
{
// Stub server that returns dummy data
var
StubServer
=
function
()
{
...
...
@@ -15,12 +15,6 @@ describe("OpenAssessment.BaseUI", function() {
grade
:
"Test fragment"
};
this
.
submit
=
function
(
submission
)
{
return
$
.
Deferred
(
function
(
defer
)
{
defer
.
resolveWith
(
this
,
[
'student'
,
0
]);
}).
promise
();
};
this
.
peerAssess
=
function
(
submissionId
,
optionsSelected
,
feedback
)
{
return
$
.
Deferred
(
function
(
defer
)
{
defer
.
resolve
();
}).
promise
();
};
...
...
@@ -42,7 +36,7 @@ describe("OpenAssessment.BaseUI", function() {
this
.
feedbackOptions
=
options
;
// Return a promise that always resolves successfully
return
$
.
Deferred
(
function
(
defer
)
{
defer
.
resolve
()
}).
promise
();
return
$
.
Deferred
(
function
(
defer
)
{
defer
.
resolve
()
;
}).
promise
();
};
};
...
...
@@ -50,7 +44,7 @@ describe("OpenAssessment.BaseUI", function() {
var
runtime
=
{};
var
server
=
null
;
var
ui
=
null
;
var
view
=
null
;
/**
Wait for subviews to load before executing callback.
...
...
@@ -60,7 +54,7 @@ describe("OpenAssessment.BaseUI", function() {
**/
var
loadSubviews
=
function
(
callback
)
{
runs
(
function
()
{
ui
.
load
();
view
.
load
();
});
waitsFor
(
function
()
{
...
...
@@ -85,21 +79,13 @@ describe("OpenAssessment.BaseUI", function() {
// Create the object under test
var
el
=
$
(
"#openassessment-base"
).
get
(
0
);
ui
=
new
OpenAssessment
.
BaseUI
(
runtime
,
el
,
server
);
});
it
(
"Sends a submission to the server"
,
function
()
{
loadSubviews
(
function
()
{
spyOn
(
server
,
'submit'
).
andCallThrough
();
ui
.
submit
();
expect
(
server
.
submit
).
toHaveBeenCalled
();
});
view
=
new
OpenAssessment
.
BaseView
(
runtime
,
el
,
server
);
});
it
(
"Sends a peer assessment to the server"
,
function
()
{
loadSubviews
(
function
()
{
spyOn
(
server
,
'peerAssess'
).
andCallThrough
();
ui
.
peerAssess
();
view
.
peerAssess
();
expect
(
server
.
peerAssess
).
toHaveBeenCalled
();
});
});
...
...
@@ -107,7 +93,7 @@ describe("OpenAssessment.BaseUI", function() {
it
(
"Sends a self assessment to the server"
,
function
()
{
loadSubviews
(
function
()
{
spyOn
(
server
,
'selfAssess'
).
andCallThrough
();
ui
.
selfAssess
();
view
.
selfAssess
();
expect
(
server
.
selfAssess
).
toHaveBeenCalled
();
});
});
...
...
@@ -126,10 +112,10 @@ describe("OpenAssessment.BaseUI", function() {
// Create the object under test
var
el
=
$
(
"#openassessment-base"
).
get
(
0
);
ui
=
new
OpenAssessment
.
BaseUI
(
runtime
,
el
,
server
);
view
=
new
OpenAssessment
.
BaseView
(
runtime
,
el
,
server
);
// Submit feedback on an assessment
ui
.
submitFeedbackOnAssessment
();
view
.
submitFeedbackOnAssessment
();
// Expect that the feedback was retrieved from the DOM and sent to the server
expect
(
server
.
feedbackText
).
toEqual
(
'I disliked the feedback I received.'
);
...
...
apps/openassessment/xblock/static/js/spec/oa_edit.js
View file @
9896d39f
...
...
@@ -2,7 +2,7 @@
Tests for OA XBlock editing.
**/
describe
(
"OpenAssessment.Studio
UI
"
,
function
()
{
describe
(
"OpenAssessment.Studio
View
"
,
function
()
{
var
runtime
=
{
notify
:
function
(
type
,
data
)
{}
...
...
@@ -52,7 +52,7 @@ describe("OpenAssessment.StudioUI", function() {
};
var
server
=
null
;
var
ui
=
null
;
var
view
=
null
;
beforeEach
(
function
()
{
...
...
@@ -68,24 +68,24 @@ describe("OpenAssessment.StudioUI", function() {
// Create the object under test
var
el
=
$
(
'#openassessment-edit'
).
get
(
0
);
ui
=
new
OpenAssessment
.
StudioUI
(
runtime
,
el
,
server
);
view
=
new
OpenAssessment
.
StudioView
(
runtime
,
el
,
server
);
});
it
(
"loads the XML definition"
,
function
()
{
// Initialize the
UI
ui
.
load
();
// Initialize the
view
view
.
load
();
// Expect that the XML definition was loaded
var
contents
=
ui
.
codeBox
.
getValue
();
var
contents
=
view
.
codeBox
.
getValue
();
expect
(
contents
).
toEqual
(
'<openassessment></openassessment>'
);
});
it
(
"saves the XML definition"
,
function
()
{
// Update the XML
ui
.
codeBox
.
setValue
(
'<openassessment>test!</openassessment>'
);
view
.
codeBox
.
setValue
(
'<openassessment>test!</openassessment>'
);
// Save the updated XML
ui
.
save
();
view
.
save
();
// Expect the saving notification to start/end
expect
(
runtime
.
notify
).
toHaveBeenCalledWith
(
'save'
,
{
state
:
'start'
});
...
...
@@ -100,31 +100,31 @@ describe("OpenAssessment.StudioUI", function() {
server
.
isReleased
=
true
;
// Stub the confirmation step (avoid showing the dialog)
spyOn
(
ui
,
'confirmPostReleaseUpdate'
).
andCallFake
(
spyOn
(
view
,
'confirmPostReleaseUpdate'
).
andCallFake
(
function
(
onConfirm
)
{
onConfirm
();
}
);
// Save the updated XML
ui
.
save
();
view
.
save
();
// Verify that the user was asked to confirm the changes
expect
(
ui
.
confirmPostReleaseUpdate
).
toHaveBeenCalled
();
expect
(
view
.
confirmPostReleaseUpdate
).
toHaveBeenCalled
();
});
it
(
"cancels editing"
,
function
()
{
ui
.
cancel
();
view
.
cancel
();
expect
(
runtime
.
notify
).
toHaveBeenCalledWith
(
'cancel'
,
{});
});
it
(
"displays an error when server reports a load XML error"
,
function
()
{
server
.
loadError
=
true
;
ui
.
load
();
view
.
load
();
expect
(
runtime
.
notify
).
toHaveBeenCalledWith
(
'error'
,
{
msg
:
'Test error'
});
});
it
(
"displays an error when server reports an update XML error"
,
function
()
{
server
.
updateError
=
true
;
ui
.
save
(
'<openassessment>test!</openassessment>'
);
view
.
save
(
'<openassessment>test!</openassessment>'
);
expect
(
runtime
.
notify
).
toHaveBeenCalledWith
(
'error'
,
{
msg
:
'Test error'
});
});
...
...
apps/openassessment/xblock/static/js/spec/oa_response.js
0 → 100644
View file @
9896d39f
/**
Tests for OpenAssessment response (submission) step.
**/
describe
(
"OpenAssessment.ResponseView"
,
function
()
{
// Stub server
var
StubServer
=
function
()
{
var
successPromise
=
$
.
Deferred
(
function
(
defer
)
{
defer
.
resolve
();
}
).
promise
();
this
.
save
=
function
(
submission
)
{
return
successPromise
;
};
this
.
submit
=
function
(
submission
)
{
return
successPromise
;
};
this
.
render
=
function
(
step
)
{
return
successPromise
;
};
};
// Stub base view
var
StubBaseView
=
function
()
{
this
.
showLoadError
=
function
(
msg
)
{};
this
.
toggleActionError
=
function
(
msg
,
step
)
{};
this
.
setUpCollapseExpand
=
function
(
sel
)
{};
this
.
renderPeerAssessmentStep
=
function
()
{};
};
// Stubs
var
baseView
=
null
;
var
server
=
null
;
// View under test
var
view
=
null
;
beforeEach
(
function
()
{
// Load the DOM fixture
jasmine
.
getFixtures
().
fixturesPath
=
'base/fixtures'
;
loadFixtures
(
'oa_response.html'
);
// Create the stub server
server
=
new
StubServer
();
// Create the stub base view
baseView
=
new
StubBaseView
();
// Create and install the view
var
el
=
$
(
'#openassessment-base'
).
get
(
0
);
view
=
new
OpenAssessment
.
ResponseView
(
el
,
server
,
baseView
);
view
.
installHandlers
();
});
it
(
"updates submit/save buttons and save status when response text changes"
,
function
()
{
// Response is blank --> save/submit buttons disabled
view
.
response
(
''
);
view
.
responseChanged
();
expect
(
view
.
submitEnabled
()).
toBe
(
false
);
expect
(
view
.
saveEnabled
()).
toBe
(
false
);
expect
(
view
.
saveStatus
()).
toContain
(
'Unsaved draft'
);
// Response is not blank --> submit button enabled
view
.
response
(
'Test response'
);
view
.
responseChanged
();
expect
(
view
.
submitEnabled
()).
toBe
(
true
);
expect
(
view
.
saveEnabled
()).
toBe
(
true
);
expect
(
view
.
saveStatus
()).
toContain
(
'Unsaved draft'
);
});
it
(
"updates submit/save buttons and save status when the user saves a response"
,
function
()
{
// Response is blank --> save/submit button is disabled
view
.
response
(
''
);
view
.
save
();
expect
(
view
.
submitEnabled
()).
toBe
(
false
);
expect
(
view
.
saveEnabled
()).
toBe
(
false
);
expect
(
view
.
saveStatus
()).
toContain
(
'Saved but not submitted'
);
// Response is not blank --> submit button enabled
view
.
response
(
'Test response'
);
view
.
save
();
expect
(
view
.
submitEnabled
()).
toBe
(
true
);
expect
(
view
.
saveEnabled
()).
toBe
(
false
);
expect
(
view
.
saveStatus
()).
toContain
(
'Saved but not submitted'
);
});
it
(
"shows unsaved draft only when response text has changed"
,
function
()
{
// Save the initial response
view
.
response
(
'Lorem ipsum'
);
view
.
save
();
expect
(
view
.
saveEnabled
()).
toBe
(
false
);
expect
(
view
.
saveStatus
()).
toContain
(
'Saved but not submitted'
);
// Keep the text the same, but trigger an update
// Should still be saved
view
.
response
(
'Lorem ipsum'
);
view
.
responseChanged
();
expect
(
view
.
saveEnabled
()).
toBe
(
false
);
expect
(
view
.
saveStatus
()).
toContain
(
'Saved but not submitted'
);
// Change the text
// This should cause it to change to unsaved draft
view
.
response
(
'changed '
);
view
.
responseChanged
();
expect
(
view
.
saveEnabled
()).
toBe
(
true
);
expect
(
view
.
saveStatus
()).
toContain
(
'Unsaved draft'
);
});
it
(
"sends the saved submission to the server"
,
function
()
{
spyOn
(
server
,
'save'
).
andCallThrough
();
view
.
response
(
'Test response'
);
view
.
save
();
expect
(
server
.
save
).
toHaveBeenCalledWith
(
'Test response'
);
});
it
(
"submits a response to the server"
,
function
()
{
spyOn
(
server
,
'submit'
).
andCallThrough
();
view
.
response
(
'Test response'
);
view
.
submit
();
expect
(
server
.
submit
).
toHaveBeenCalledWith
(
'Test response'
);
});
});
apps/openassessment/xblock/static/js/src/oa_base.js
View file @
9896d39f
This diff is collapsed.
Click to expand it.
apps/openassessment/xblock/static/js/src/oa_edit.js
View file @
9896d39f
...
...
@@ -8,7 +8,7 @@ if (typeof OpenAssessment == "undefined" || !OpenAssessment) {
/**
Interface for editing
UI
in Studio.
Interface for editing
view
in Studio.
The constructor initializes the DOM for editing.
Args:
...
...
@@ -17,9 +17,9 @@ Args:
server (OpenAssessment.Server): The interface to the XBlock server.
Returns:
OpenAssessment.Studio
UI
OpenAssessment.Studio
View
**/
OpenAssessment
.
Studio
UI
=
function
(
runtime
,
element
,
server
)
{
OpenAssessment
.
Studio
View
=
function
(
runtime
,
element
,
server
)
{
this
.
runtime
=
runtime
;
this
.
server
=
server
;
...
...
@@ -30,31 +30,31 @@ OpenAssessment.StudioUI = function(runtime, element, server) {
);
// Install click handlers
var
ui
=
this
;
var
view
=
this
;
$
(
element
).
find
(
'.openassessment-save-button'
).
click
(
function
(
eventData
)
{
ui
.
save
();
view
.
save
();
});
$
(
element
).
find
(
'.openassessment-cancel-button'
).
click
(
function
(
eventData
)
{
ui
.
cancel
();
view
.
cancel
();
});
};
OpenAssessment
.
Studio
UI
.
prototype
=
{
OpenAssessment
.
Studio
View
.
prototype
=
{
/**
Load the XBlock XML definition from the server and display it in the
UI
.
Load the XBlock XML definition from the server and display it in the
view
.
**/
load
:
function
()
{
var
ui
=
this
;
var
view
=
this
;
this
.
server
.
loadXml
().
done
(
function
(
xml
)
{
ui
.
codeBox
.
setValue
(
xml
);
view
.
codeBox
.
setValue
(
xml
);
}).
fail
(
function
(
msg
)
{
ui
.
showError
(
msg
);
view
.
showError
(
msg
);
}
);
},
...
...
@@ -64,17 +64,17 @@ OpenAssessment.StudioUI.prototype = {
If the problem has been released, make the user confirm the save.
**/
save
:
function
()
{
var
ui
=
this
;
var
view
=
this
;
// Check whether the problem has been released; if not,
// warn the user and allow them to cancel.
this
.
server
.
checkReleased
().
done
(
function
(
isReleased
)
{
if
(
isReleased
)
{
ui
.
confirmPostReleaseUpdate
(
$
.
proxy
(
ui
.
updateXml
,
ui
));
}
else
{
ui
.
updateXml
();
}
if
(
isReleased
)
{
view
.
confirmPostReleaseUpdate
(
$
.
proxy
(
view
.
updateXml
,
view
));
}
else
{
view
.
updateXml
();
}
}
).
fail
(
function
(
errMsg
)
{
ui
.
showError
(
msg
);
view
.
showError
(
msg
);
});
},
...
...
@@ -102,16 +102,16 @@ OpenAssessment.StudioUI.prototype = {
// Send the updated XML to the server
var
xml
=
this
.
codeBox
.
getValue
();
var
ui
=
this
;
var
view
=
this
;
this
.
server
.
updateXml
(
xml
).
done
(
function
()
{
// Notify the client-side runtime that we finished saving
// so it can hide the "Saving..." notification.
ui
.
runtime
.
notify
(
'save'
,
{
state
:
'end'
});
view
.
runtime
.
notify
(
'save'
,
{
state
:
'end'
});
// Reload the XML definition in the editor
ui
.
load
();
view
.
load
();
}).
fail
(
function
(
msg
)
{
ui
.
showError
(
msg
);
view
.
showError
(
msg
);
});
},
...
...
@@ -143,7 +143,7 @@ function OpenAssessmentEditor(runtime, element) {
**/
$
(
function
(
$
)
{
var
server
=
new
OpenAssessment
.
Server
(
runtime
,
element
);
var
ui
=
new
OpenAssessment
.
StudioUI
(
runtime
,
element
,
server
);
ui
.
load
();
var
view
=
new
OpenAssessment
.
StudioView
(
runtime
,
element
,
server
);
view
.
load
();
});
}
apps/openassessment/xblock/static/js/src/oa_response.js
0 → 100644
View file @
9896d39f
/* JavaScript for response (submission) view */
/* Namespace for open assessment */
if
(
typeof
OpenAssessment
==
"undefined"
||
!
OpenAssessment
)
{
OpenAssessment
=
{};
}
/**
Interface for response (submission) view.
Args:
element (DOM element): The DOM element representing the XBlock.
server (OpenAssessment.Server): The interface to the XBlock server.
baseView (OpenAssessment.BaseView): Container view.
Returns:
OpenAssessment.ResponseView
**/
OpenAssessment
.
ResponseView
=
function
(
element
,
server
,
baseView
)
{
this
.
element
=
element
;
this
.
server
=
server
;
this
.
baseView
=
baseView
;
this
.
savedResponse
=
""
;
};
OpenAssessment
.
ResponseView
.
prototype
=
{
/**
Load the response (submission) view.
**/
load
:
function
()
{
var
view
=
this
;
this
.
server
.
render
(
'submission'
).
done
(
function
(
html
)
{
// Load the HTML and install event handlers
$
(
'#openassessment__response'
,
view
.
element
).
replaceWith
(
html
);
view
.
installHandlers
();
}
).
fail
(
function
(
errMsg
)
{
view
.
baseView
.
showLoadError
(
'response'
);
});
},
/**
Install event handlers for the view.
**/
installHandlers
:
function
()
{
var
sel
=
$
(
'#openassessment__response'
,
this
.
element
);
var
view
=
this
;
// Install a click handler for collapse/expand
this
.
baseView
.
setUpCollapseExpand
(
sel
);
// Install change handler for textarea (to enable submission button)
this
.
savedResponse
=
this
.
response
();
var
handleChange
=
function
(
eventData
)
{
view
.
responseChanged
();
};
sel
.
find
(
'#submission__answer__value'
).
on
(
'change keyup drop paste'
,
handleChange
);
// Install a click handler for submission
sel
.
find
(
'#step--response__submit'
).
click
(
function
(
eventObject
)
{
// Override default form submission
eventObject
.
preventDefault
();
view
.
submit
();
}
);
// Install a click handler for the save button
sel
.
find
(
'#submission__save'
).
click
(
function
(
eventObject
)
{
// Override default form submission
eventObject
.
preventDefault
();
view
.
save
();
}
);
},
/**
Enable/disable the submit button.
Check that whether the submit button is enabled.
Args:
enabled (bool): If specified, set the state of the button.
Returns:
bool: Whether the button is enabled.
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'
)
{
return
!
sel
.
hasClass
(
'is--disabled'
);
}
else
{
sel
.
toggleClass
(
'is--disabled'
,
!
enabled
)
}
},
/**
Enable/disable the save button.
Check that whether the save button is enabled.
Args:
enabled (bool): If specified, set the state of the button.
Returns:
bool: Whether the button is enabled.
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'
)
{
return
!
sel
.
hasClass
(
'is--disabled'
);
}
else
{
sel
.
toggleClass
(
'is--disabled'
,
!
enabled
);
}
},
/**
Set the save status message.
Retrieve the save status message.
Args:
msg (string): If specified, the message to display.
Returns:
string: The current status message.
**/
saveStatus
:
function
(
msg
)
{
var
sel
=
$
(
'#response__save_status h3'
,
this
.
element
);
if
(
typeof
msg
===
'undefined'
)
{
return
sel
.
text
();
}
else
{
// Setting the HTML will overwrite the screen reader tag,
// so prepend it to the message.
sel
.
html
(
'<span class="sr">Your Working Submission Status:</span>
\
n'
+
msg
);
}
},
/**
Set the response text.
Retrieve the response text.
Args:
text (string): If specified, the text to set for the response.
Returns:
string: The current response text.
**/
response
:
function
(
text
)
{
var
sel
=
$
(
'#submission__answer__value'
,
this
.
element
);
if
(
typeof
text
===
'undefined'
)
{
return
sel
.
val
();
}
else
{
sel
.
val
(
text
);
}
},
/**
Enable/disable the submission and save buttons based on whether
the user has entered a response.
**/
responseChanged
:
function
()
{
// Enable the save/submit button only for non-blank responses
var
currentResponse
=
this
.
response
();
var
isBlank
=
(
currentResponse
!==
''
);
this
.
submitEnabled
(
isBlank
);
// Update the save button and status only if the response has changed
if
(
this
.
savedResponse
!==
currentResponse
)
{
this
.
saveEnabled
(
isBlank
);
this
.
saveStatus
(
'Unsaved draft'
);
}
},
/**
Save a response without submitting it.
**/
save
:
function
()
{
// Update the save status and error notifications
this
.
saveStatus
(
'Saving...'
);
this
.
baseView
.
toggleActionError
(
'save'
,
null
);
var
view
=
this
;
var
savedResponse
=
this
.
response
();
this
.
server
.
save
(
savedResponse
).
done
(
function
()
{
// Remember which response we saved, once the server confirms that it's been saved...
view
.
savedResponse
=
savedResponse
;
// ... but update the UI based on what the user may have entered
// since hitting the save button.
var
currentResponse
=
view
.
response
();
view
.
submitEnabled
(
currentResponse
!==
''
);
if
(
currentResponse
==
savedResponse
)
{
view
.
saveEnabled
(
false
);
view
.
saveStatus
(
"Saved but not submitted"
);
}
}).
fail
(
function
(
errMsg
)
{
view
.
saveStatus
(
'Error'
);
view
.
baseView
.
toggleActionError
(
'save'
,
errMsg
);
});
},
/**
Send a response submission to the server and update the view.
**/
submit
:
function
()
{
// Send the submission to the server
var
submission
=
$
(
'#submission__answer__value'
,
this
.
element
).
val
();
this
.
baseView
.
toggleActionError
(
'response'
,
null
);
var
view
=
this
;
var
baseView
=
this
.
baseView
;
this
.
server
.
submit
(
submission
).
done
(
// When we have successfully sent the submission, move on to the next step
function
(
studentId
,
attemptNum
)
{
view
.
load
();
baseView
.
renderPeerAssessmentStep
();
}
).
fail
(
function
(
errCode
,
errMsg
)
{
baseView
.
toggleActionError
(
'submit'
,
errMsg
);
});
}
};
apps/openassessment/xblock/submission_mixin.py
View file @
9896d39f
...
...
@@ -155,7 +155,7 @@ class SubmissionMixin(object):
Returns:
unicode
"""
return
_
(
u'Saved but not submitted'
)
if
self
.
has_saved
else
_
(
u'
Not saved
'
)
return
_
(
u'Saved but not submitted'
)
if
self
.
has_saved
else
_
(
u'
Unsaved draft
'
)
@XBlock.handler
def
render_submission
(
self
,
data
,
suffix
=
''
):
...
...
@@ -185,6 +185,7 @@ class SubmissionMixin(object):
context
=
{
"saved_response"
:
self
.
saved_response
,
"save_status"
:
self
.
save_status
,
"submit_enabled"
:
self
.
saved_response
!=
''
,
"submission_due"
:
sub_due
,
}
...
...
apps/openassessment/xblock/test/test_save_response.py
View file @
9896d39f
...
...
@@ -14,7 +14,7 @@ class SaveResponseTest(XBlockHandlerTestCase):
def
test_default_saved_response_blank
(
self
,
xblock
):
resp
=
self
.
request
(
xblock
,
'render_submission'
,
json
.
dumps
({}))
self
.
assertIn
(
'<textarea id="submission__answer__value" placeholder=""></textarea>'
,
resp
)
self
.
assertIn
(
'
Not saved
'
,
resp
)
self
.
assertIn
(
'
Unsaved draft
'
,
resp
)
@ddt.file_data
(
'data/save_responses.json'
)
@scenario
(
'data/save_scenario.xml'
,
user_id
=
"Perleman"
)
...
...
@@ -57,4 +57,4 @@ class SaveResponseTest(XBlockHandlerTestCase):
def
test_missing_submission_key
(
self
,
xblock
):
resp
=
self
.
request
(
xblock
,
'save_submission'
,
json
.
dumps
({}),
response_format
=
"json"
)
self
.
assertFalse
(
resp
[
'success'
])
self
.
assertIn
(
'submission'
,
resp
[
'msg'
])
\ No newline at end of file
self
.
assertIn
(
'submission'
,
resp
[
'msg'
])
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment