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
7d78ddaa
Commit
7d78ddaa
authored
Aug 12, 2014
by
gradyward
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Documentation
parent
f092b446
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
147 additions
and
38 deletions
+147
-38
openassessment/xblock/static/js/openassessment-studio.min.js
+0
-0
openassessment/xblock/static/js/src/studio/oa_container_item.js
+93
-13
openassessment/xblock/static/js/src/studio/oa_edit.js
+1
-0
openassessment/xblock/static/js/src/studio/oa_edit_ai.js
+42
-25
openassessment/xblock/static/js/src/studio/oa_edit_assessment.js
+2
-0
openassessment/xblock/static/js/src/studio/oa_edit_listeners.js
+0
-0
openassessment/xblock/studio_mixin.py
+9
-0
No files found.
openassessment/xblock/static/js/openassessment-studio.min.js
View file @
7d78ddaa
This source diff could not be displayed because it is too large. You can
view the blob
instead.
openassessment/xblock/static/js/src/studio/oa_container_item.js
View file @
7d78ddaa
...
...
@@ -63,11 +63,21 @@ OpenAssessment.ItemUtilities = {
$
(
element
).
text
(
finalLabel
);
},
addClassToAllButOne
:
function
(
element
,
selectorToHide
,
selectorToShow
,
className
){
$
(
selectorToHide
,
element
).
each
(
function
()
{
/**
Adds a class to all elements of a given type except for a single element.
The primary use of this function is to allow paired highlighting and showing.
Args:
element (JQuery Element): The parent element that we want to search within
whoToAddTo (JQuery Selector): The selector that we search for, and subsequently add the class to.
dontAddToMe (JQuery Selector): The selector that we search for and remove the class from
className (str): The Class of interest (is--hidden or is--faded in most contexts)
*/
addClassToAllButOne
:
function
(
element
,
whoToAddTo
,
dontAddToMe
,
className
){
$
(
whoToAddTo
,
element
).
each
(
function
()
{
$
(
this
).
addClass
(
className
);
});
$
(
selectorToShow
,
element
).
removeClass
(
className
);
$
(
dontAddToMe
,
element
).
removeClass
(
className
);
}
};
...
...
@@ -610,7 +620,19 @@ OpenAssessment.TrainingExample.prototype = {
}
};
/**
The AIExample class is used to construct and retrieve information from its element within the DOM
Note the similarity of the AI Example class and the TrainingExample Class.
Args:
element (JQuery Object): the selection which identifies the scope of the AI training example.
Returns:
OpenAssessment.AIExample
**/
OpenAssessment
.
AIExample
=
function
(
element
){
// Hides the element on load
this
.
element
=
$
(
element
).
addClass
(
'is--hidden'
);
this
.
labelSel
=
$
(
'.openassessment_ai_example_label_field'
,
this
.
element
).
find
(
'input'
).
first
();
this
.
answer
=
$
(
'.openassessment_ai_example_essay'
,
this
.
element
).
first
();
...
...
@@ -635,20 +657,23 @@ OpenAssessment.AIExample.prototype = {
}
).
get
();
// Adds the label and answer to the dictionary definition of the AI example
return
{
answer
:
this
.
answer
.
prop
(
'value'
),
label
:
this
.
labelSel
.
prop
(
'value'
),
options_selected
:
optionsSelected
};
},
addHandler
:
function
()
{
// Goes through and
instantiat
es the option description in the training example for each option.
// Goes through and
refresh
es the option description in the training example for each option.
$
(
".openassessment_ai_example_criterion_option"
,
this
.
element
)
.
each
(
function
()
{
$
(
'option'
,
this
).
each
(
function
(){
OpenAssessment
.
ItemUtilities
.
refreshOptionString
(
$
(
this
));
});
});
// Constructs a unique name for the example so that it can be paired with a AIMenuItem
$
(
this
.
element
).
attr
(
'data-example'
,
OpenAssessment
.
ItemUtilities
.
createUniqueName
(
this
.
element
,
'data-example'
)
);
...
...
@@ -657,17 +682,28 @@ OpenAssessment.AIExample.prototype = {
},
addEventListeners
:
function
()
{
// Install a focus out handler
for container change
s.
// Install a focus out handler
to propagate label changes to their corresponding menu item
s.
$
(
this
.
labelSel
).
focusout
(
$
.
proxy
(
this
.
updateHandler
,
this
));
},
removeHandler
:
function
()
{},
updateHandler
:
function
()
{
var
view
=
this
;
$
(
".openassessment_ai_example_menu_item[data-example='"
+
$
(
this
.
element
).
attr
(
'data-example'
)
+
"']"
)
.
find
(
'h2'
).
first
()
// On an update of the label field, we need to find the corresponding menu item and change
// it's text to be the new value for the label field.
var
sel
=
".openassessment_ai_example_menu_item[data-example='"
+
$
(
this
.
element
).
attr
(
'data-example'
)
+
"']"
$
(
sel
,
$
(
this
.
element
).
closest
(
'#openassessment_ai_editor_menu_and_editor'
))
.
find
(
'h2'
)
.
first
()
.
text
(
$
(
view
.
labelSel
).
val
());
},
/**
Mark validation errors.
Returns:
Boolean indicating whether the criterion is valid.
**/
validate
:
function
()
{
var
isValid
=
true
;
...
...
@@ -685,6 +721,14 @@ OpenAssessment.AIExample.prototype = {
return
isValid
;
},
/**
Return a list of validation errors visible in the UI.
Mainly useful for testing.
Returns:
list of string
**/
validationErrors
:
function
()
{
var
errors
=
[];
this
.
criteria
.
each
(
...
...
@@ -709,28 +753,50 @@ OpenAssessment.AIExample.prototype = {
this
.
criteria
.
each
(
function
()
{
$
(
this
).
removeClass
(
"openassessment_highlighted_field"
);
}
);
}
},
removeHandler
:
function
()
{}
};
/**
The AIExampleMenuItem class is used as a partner to the AIExample class, with the idea being a 1:1 relationship
maintains a menu which can be used to navigate through examples, displaying one at a time.
Args:
element (JQuery Object): the selection which identifies the scope of the AI Menu Item.
Returns:
OpenAssessment.AIExampleMenuItem
**/
OpenAssessment
.
AIExampleMenuItem
=
function
(
element
){
this
.
element
=
element
;
this
.
labelSel
=
$
(
'.openassessment_ai_example_label_field'
,
this
.
element
);
// The first element up the DOM tree which contains both the editing panels and the menu items.
this
.
menuAndEditor
=
$
(
this
.
element
).
closest
(
'#openassessment_ai_editor_menu_and_editor'
);
};
OpenAssessment
.
AIExampleMenuItem
.
prototype
=
{
/**
Adds a click handler to the item that will display its corresponding panel, while highlighting
itself and removing higlighting from all other menu items.
**/
addEventListeners
:
function
()
{
var
exampleName
=
$
(
this
.
element
).
attr
(
'data-example'
);
var
view
=
this
;
$
(
this
.
element
).
click
(
function
()
{
// Hides all of the examples, then displays the one which has the same data-example value as the menu item.
OpenAssessment
.
ItemUtilities
.
addClassToAllButOne
(
$
(
view
.
element
).
closest
(
'#openassessment_ai_editor_menu_and_editor'
)
,
view
.
menuAndEditor
,
'.openassessment_ai_editor_single_visibility'
,
'.openassessment_ai_example[data-example="'
+
exampleName
+
'"]'
,
'is--hidden'
);
// Adds a "faded" look to all of the menu items, and then bolds the one which has the same data-example value.
OpenAssessment
.
ItemUtilities
.
addClassToAllButOne
(
$
(
view
.
element
).
closest
(
'#openassessment_ai_editor_menu_and_editor'
)
,
view
.
menuAndEditor
,
'.openassessment_ai_menu_single_visibility'
,
'.openassessment_ai_example_menu_item[data-example="'
+
exampleName
+
'"]'
,
'is--faded'
...
...
@@ -738,23 +804,37 @@ OpenAssessment.AIExampleMenuItem.prototype = {
});
},
/**
Finds the example that the MenuItem corresponds to, and removes it from the DOM after doing some checks
to examine what element should next be displayed.
*/
removeHandler
:
function
()
{
var
pairedExample
=
$
(
'.openassessment_ai_example[data-example="'
+
$
(
this
.
element
).
attr
(
'data-example'
)
+
'"]'
);
// Finds the paired example
var
pairedExample
=
$
(
'.openassessment_ai_example[data-example="'
+
$
(
this
.
element
).
attr
(
'data-example'
)
+
'"]'
,
this
.
menuAndEditor
);
// Boolean indicating whether or not the paired example is the last example in the list
var
lastExample
=
$
(
'.openassessment_ai_example'
,
$
(
pairedExample
).
parent
()).
length
==
1
;
// Boolean indicating whether or not the paired example is currently selected
var
currentlySelected
=
!
$
(
pairedExample
).
hasClass
(
'is--hidden'
);
// If either of the above are true, when we delete from the MenuItem, we want the "empty" screen to show up.
if
(
lastExample
||
currentlySelected
){
$
(
'#openassessment_ai_example_editor_background'
,
$
(
pairedExample
).
parent
()).
removeClass
(
'is--hidden'
);
}
$
(
pairedExample
).
remove
();
},
getFieldValues
:
function
()
{},
/**
On add, we create a unique name for the exampleMenuItem, and because we only instantiate AIExampleMenuItems
at the same time as we instantiate AIExamples, these numbers always match, because they share the same generation
code. Note that this is certainly a weak point of this solution, and should be changed if adequate time is
provided.
*/
addHandler
:
function
()
{
$
(
this
.
element
).
attr
(
'data-example'
,
OpenAssessment
.
ItemUtilities
.
createUniqueName
(
this
.
element
,
'data-example'
)
);
this
.
addEventListeners
();
},
getFieldValues
:
function
()
{},
updateHandler
:
function
()
{},
validate
:
function
()
{
return
true
;
},
validationErrors
:
function
()
{
return
[];
},
...
...
openassessment/xblock/static/js/src/studio/oa_edit.js
View file @
7d78ddaa
...
...
@@ -61,6 +61,7 @@ OpenAssessment.StudioView = function(runtime, element, server) {
])
);
// Initialize the AI Example Editing Tab
this
.
aiView
=
new
OpenAssessment
.
EditAIView
(
$
(
"#oa_ai_editor_wrapper"
,
this
.
element
).
get
(
0
)
);
...
...
openassessment/xblock/static/js/src/studio/oa_edit_ai.js
View file @
7d78ddaa
/**
Interface for editing example definitions for AI assessment (Example Based Assessment).
Args:
element (DOM element): The DOM element representing the Examples Tab.
**/
OpenAssessment
.
EditAIView
=
function
(
element
)
{
var
view
=
this
;
this
.
element
=
element
;
this
.
menuAndEditor
=
$
(
"#openassessment_ai_editor_menu_and_editor"
,
this
.
element
);
this
.
exampleAddButton
=
$
(
'#openassessment_ai_menu_add_example'
,
this
.
element
);
// The container for the examples stored in the view
this
.
exampleContainer
=
new
OpenAssessment
.
Container
(
OpenAssessment
.
AIExample
,
{
containerElement
:
$
(
"#openassessment_ai_examples"
,
this
.
element
).
get
(
0
),
templateElement
:
$
(
"#openassessment_ai_example_template"
,
this
.
element
).
get
(
0
),
addButtonElement
:
$
(
"#openassessment_ai_menu_add_example"
,
this
.
element
).
get
(
0
),
removeButtonClass
:
"openassessment_ai_example_remove_button"
,
// Note that we do not add or remove using buttons, but rely on the MenuItem to perform that operation
addButtonElement
:
"nope_we_dont_add_here"
,
removeButtonClass
:
"nope_we_dont_remove_here"
,
containerItemClass
:
"openassessment_ai_example"
}
);
this
.
exampleContainer
.
addEventListeners
();
// A corresponding menu for the examples. There is a 1:1 relationship between the two.
this
.
exampleMenuContainer
=
new
OpenAssessment
.
Container
(
OpenAssessment
.
AIExampleMenuItem
,
{
containerElement
:
$
(
"#openassessment_ai_example_menu"
,
this
.
element
).
get
(
0
),
...
...
@@ -25,30 +36,34 @@ OpenAssessment.EditAIView = function(element) {
);
this
.
exampleMenuContainer
.
addEventListeners
();
// Instantiates the button which switches between Normal editing mode and Import XML mode.
$
(
"#openassessment_ai_editor_upload_xml"
,
this
.
element
).
click
(
function
()
{
// Hides all editing panels, then shows the editing XML panel.
OpenAssessment
.
ItemUtilities
.
addClassToAllButOne
(
$
(
this
).
closest
(
"#openassessment_ai_editor_menu_and_editor"
)
,
view
.
menuAndEditor
,
'.openassessment_ai_editor_single_visibility'
,
'#openassessment_ai_editor_import_xml'
,
'is--hidden'
);
// Fades all menu items, then bods the selected menu item.
OpenAssessment
.
ItemUtilities
.
addClassToAllButOne
(
$
(
this
).
closest
(
"#openassessment_ai_editor_menu_and_editor"
)
,
view
.
menuAndEditor
,
'.openassessment_ai_menu_single_visibility'
,
'#openassessment_ai_editor_upload_xml'
,
'is--faded'
);
});
// Identical to the above, but used for CSV upload
$
(
"#openassessment_ai_editor_upload_csv"
,
this
.
element
).
click
(
function
()
{
OpenAssessment
.
ItemUtilities
.
addClassToAllButOne
(
$
(
this
).
closest
(
"#openassessment_ai_editor_menu_and_editor"
)
,
view
.
menuAndEditor
,
'.openassessment_ai_editor_single_visibility'
,
'#openassessment_ai_editor_import_csv'
,
'is--hidden'
);
OpenAssessment
.
ItemUtilities
.
addClassToAllButOne
(
$
(
this
).
closest
(
"#openassessment_ai_editor_menu_and_editor"
)
,
view
.
menuAndEditor
,
'.openassessment_ai_menu_single_visibility'
,
'#openassessment_ai_editor_upload_csv'
,
'is--faded'
...
...
@@ -60,23 +75,6 @@ OpenAssessment.EditAIView = function(element) {
OpenAssessment
.
EditAIView
.
prototype
=
{
exampleDefinition
:
function
()
{
return
this
.
exampleContainer
.
getItemValues
();
},
addExample
:
function
()
{
this
.
exampleContainer
.
add
();
this
.
exampleMenuContainer
.
add
();
},
removeExample
:
function
(
item
)
{
this
.
exampleContainer
.
remove
(
item
);
},
getExampleItem
:
function
(
index
)
{
return
this
.
exampleContainer
.
getItem
(
index
);
},
/**
Retrieve all examples from the AI Tab.
...
...
@@ -145,5 +143,24 @@ OpenAssessment.EditAIView.prototype = {
$
.
each
(
this
.
getAllExamples
(),
function
()
{
this
.
clearValidationErrors
();
});
}
},
// TESTING METHODS, to clean up and make utile.
exampleDefinition
:
function
()
{
return
this
.
exampleContainer
.
getItemValues
();
},
addExample
:
function
()
{
this
.
exampleContainer
.
add
();
this
.
exampleMenuContainer
.
add
();
},
removeExample
:
function
(
item
)
{
this
.
exampleContainer
.
remove
(
item
);
},
getExampleItem
:
function
(
index
)
{
return
this
.
exampleContainer
.
getItem
(
index
);
},
};
openassessment/xblock/static/js/src/studio/oa_edit_assessment.js
View file @
7d78ddaa
...
...
@@ -549,6 +549,7 @@ OpenAssessment.EditExampleBasedAssessmentView = function(element) {
])
).
install
();
// Have the enable checkbox also toggle whether or not to display the EXAMPLES tab.
$
(
"#include_ai_assessment"
,
this
.
element
).
click
(
function
()
{
$
(
'#oa_editor_tab_ai'
).
toggleClass
(
'is--hidden'
);
});
...
...
@@ -609,6 +610,7 @@ OpenAssessment.EditExampleBasedAssessmentView.prototype = {
**/
exampleDefinitions
:
function
(
xml
)
{
// Needs global search power because we include the ai_training_examples in a different section (the Examples tab)
var
sel
=
$
(
"#ai_training_examples"
);
return
OpenAssessment
.
Fields
.
stringField
(
sel
,
xml
);
},
...
...
openassessment/xblock/static/js/src/studio/oa_edit_listeners.js
View file @
7d78ddaa
This diff is collapsed.
Click to expand it.
openassessment/xblock/studio_mixin.py
View file @
7d78ddaa
...
...
@@ -296,7 +296,16 @@ class StudioMixin(object):
def
_construct_scored_rubrics_for_examples
(
self
,
original_example_list
):
"""
Creates a version of an example list where each criterion has the value of the option selected
as a field of it, with the goal of removing the need for a nested query in the templates.
Synthesizes:
(Option Selected, Criterion) and (Criterion -> Options) into (Criterion -> Options + Option Selected)
Args:
original_example_list (list of example dicts): Dictionary representation of our examples
Returns:
(list of dict): examples now with the criteria having "option_selected" return the name of an option.
"""
example_list
=
[]
for
example
in
original_example_list
:
...
...
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