-
+
diff --git a/cms/static/js/views/metadata_editor_view.js b/cms/static/js/views/metadata_editor_view.js
index a051255dd2..9a1c324732 100644
--- a/cms/static/js/views/metadata_editor_view.js
+++ b/cms/static/js/views/metadata_editor_view.js
@@ -30,15 +30,15 @@ CMS.Views.Metadata.Editor = Backbone.View.extend({
el: self.$el.find('.metadata_entry')[counter++],
model: new CMS.Models.Metadata(item)
};
- if (item.options.length > 0) {
- // Right now, all our option types only hold strings. Should really support
- // any type though.
+ if (item.type === 'Select') {
self.views.push(new CMS.Views.Metadata.Option(data));
}
+ else if (item.type === 'Integer' || item.type === 'Float') {
+ self.views.push(new CMS.Views.Metadata.Number(data));
+ }
else {
self.views.push(new CMS.Views.Metadata.String(data));
}
-
});
}
);
@@ -151,6 +151,28 @@ CMS.Views.Metadata.String = CMS.Views.Metadata.AbstractEditor.extend({
}
});
+CMS.Views.Metadata.Number = CMS.Views.Metadata.AbstractEditor.extend({
+
+ events : {
+ "change input" : "updateModel",
+ "keypress .setting-input" : "showClearButton" ,
+ "click .setting-clear" : "clear"
+ },
+
+ getTemplateName : function () {
+ return "metadata_number_entry";
+ },
+
+ getValueFromEditor : function () {
+ return this.$el.find('#' + this.uniqueId).val();
+ },
+
+ setValueInEditor : function (value) {
+ this.$el.find('input').val(value);
+ }
+});
+
+
CMS.Views.Metadata.Option = CMS.Views.Metadata.AbstractEditor.extend({
events : {
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index 91deb45a46..b33cf5fb8c 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -63,7 +63,8 @@ class ComplexEncoder(json.JSONEncoder):
class CapaFields(object):
attempts = StringyInteger(help="Number of attempts taken by the student on this problem", default=0, scope=Scope.user_state)
max_attempts = StringyInteger(display_name="Maximum Attempts",
- help="When set, this specifies the number of times the student can try to answer this problem.", scope=Scope.settings)
+ help="This specifies the number of times the student can try to answer this problem. If unset, infinite attempts are allowed.",
+ values = {"min" : 1 }, scope=Scope.settings)
due = Date(help="Date that this problem is due by", scope=Scope.settings)
graceperiod = Timedelta(help="Amount of time after the due date that submissions will be accepted", scope=Scope.settings)
showanswer = String(display_name="Show Answer",
@@ -87,7 +88,8 @@ class CapaFields(object):
done = Boolean(help="Whether the student has answered the problem", scope=Scope.user_state)
seed = StringyInteger(help="Random seed for this student", scope=Scope.user_state)
weight = StringyFloat(display_name="Problem Weight",
- help="Specifies the number of points the problem is worth. By default, each response field in the problem is worth one point.",
+ help="Specifies the number of points the problem is worth. If unset, each response field in the problem is worth one point.",
+ values = {"min" : 0 },
scope=Scope.settings)
markdown = String(help="Markdown source of this module", scope=Scope.settings)
source_code = String(help="Source code for LaTeX and Word problems. This feature is not well-supported.",
diff --git a/common/lib/xmodule/xmodule/combined_open_ended_module.py b/common/lib/xmodule/xmodule/combined_open_ended_module.py
index 1e965e6c6b..b170fa9a7d 100644
--- a/common/lib/xmodule/xmodule/combined_open_ended_module.py
+++ b/common/lib/xmodule/xmodule/combined_open_ended_module.py
@@ -57,7 +57,8 @@ class CombinedOpenEndedFields(object):
ready_to_reset = Boolean(help="If the problem is ready to be reset or not.", default=False,
scope=Scope.user_state)
attempts = Integer(display_name="Maximum Attempts",
- help="Specifies the number of times the student can try to answer this problem.", default=1, scope=Scope.settings)
+ help="Specifies the number of times the student can try to answer this problem.", default=1,
+ scope=Scope.settings)
# TODO: move values to Boolean in xblock.
is_graded = Boolean(display_name="Graded", help="Whether or not the problem is graded.", default=False, scope=Scope.settings,
values=[{'display_name': "True", "value": True}, {'display_name': "False", "value": False}])
diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py
index 3b094e04a5..5c22106f75 100644
--- a/common/lib/xmodule/xmodule/x_module.py
+++ b/common/lib/xmodule/xmodule/x_module.py
@@ -9,7 +9,7 @@ from pkg_resources import resource_listdir, resource_string, resource_isdir
from xmodule.modulestore import Location
from xmodule.modulestore.exceptions import ItemNotFoundError
-from xblock.core import XBlock, Scope, String
+from xblock.core import XBlock, Scope, String, Integer, Float
log = logging.getLogger(__name__)
@@ -649,17 +649,29 @@ class XModuleDescriptor(XModuleFields, HTMLSnippet, ResourceTemplates, XBlock):
'inheritable': inheritable,
'explicitly_set': explicitly_set}
+ # We support the following editors:
+ # 1. A select editor for fields with a list of possible values (includes Booleans).
+ # 2. Number editor for integers and floats.
+ # 3. A generic string editor for anything else (editing JSON representation of the value).
+ type = "Generic"
+ # TODO: test all this logic
values = [] if field.values is None else field.values
- for index, choice in enumerate(values):
- json_choice = choice
- # TODO: test this logic.
- if hasattr(json_choice, 'value'):
- json_choice['value'] = field.to_json(json_choice['value'])
- else:
- json_choice = field.to_json(json_choice)
- values[index] = json_choice
-
+ if isinstance(values, list):
+ if len(values) > 0:
+ type = "Select"
+ for index, choice in enumerate(values):
+ json_choice = choice
+ if hasattr(json_choice, 'value'):
+ json_choice['value'] = field.to_json(json_choice['value'])
+ else:
+ json_choice = field.to_json(json_choice)
+ values[index] = json_choice
+ elif isinstance(field, Integer):
+ type = "Integer"
+ elif isinstance(field, Float):
+ type = "Float"
simple_metadata[field.name] = {'field_name' : field.name,
+ 'type' : type,
'display_name' : field.display_name,
'value': field.to_json(value),
'options' : values,