diff --git a/cms/static/client_templates/metadata_editor.html b/cms/static/client_templates/metadata_editor.html
index bf618bd6f1..6780c4f1da 100644
--- a/cms/static/client_templates/metadata_editor.html
+++ b/cms/static/client_templates/metadata_editor.html
@@ -1,7 +1,6 @@
\ No newline at end of file
diff --git a/cms/static/client_templates/metadata_option_entry.html b/cms/static/client_templates/metadata_option_entry.html
index e69de29bb2..3a1cd30337 100644
--- a/cms/static/client_templates/metadata_option_entry.html
+++ b/cms/static/client_templates/metadata_option_entry.html
@@ -0,0 +1,12 @@
+
+ <%= model.get('display_name') %>
+
+ <% _.each(model.get('options'), function(option) { %>
+ <%= option %>
+ <% }) %>
+
+
+ ↩
+
+
+<%= model.get('help') %>
diff --git a/cms/static/client_templates/metadata_string_entry.html b/cms/static/client_templates/metadata_string_entry.html
index 494a4ff97a..647e48400a 100644
--- a/cms/static/client_templates/metadata_string_entry.html
+++ b/cms/static/client_templates/metadata_string_entry.html
@@ -1,9 +1,8 @@
- <%= model.get('display_name') %>
-
-
+ <%= model.get('display_name') %>
+
↩
-<%= model.get('help') %>
\ No newline at end of file
+<%= model.get('help') %>
diff --git a/cms/static/js/views/metadata_editor_view.js b/cms/static/js/views/metadata_editor_view.js
index 6c1665d294..4e35deba9f 100644
--- a/cms/static/js/views/metadata_editor_view.js
+++ b/cms/static/js/views/metadata_editor_view.js
@@ -19,12 +19,19 @@ CMS.Views.Metadata.Editor = Backbone.View.extend({
var counter = 0;
_.each(self.model.attributes,
function(item, key) {
- self.views[key] = new CMS.Views.Metadata.Generic({
- el: self.$el.find('.metadata_entry')[counter],
- model: new CMS.Models.Metadata(item)
- }
- );
- counter+=1;
+ var data = {
+ 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.
+ self.views[key] = new CMS.Views.Metadata.Option(data);
+ }
+ else {
+ self.views[key] = new CMS.Views.Metadata.String(data);
+ }
+
});
}
);
diff --git a/cms/static/js/views/metadata_number_view.js b/cms/static/js/views/metadata_number_view.js
new file mode 100644
index 0000000000..a1be53eafa
--- /dev/null
+++ b/cms/static/js/views/metadata_number_view.js
@@ -0,0 +1,14 @@
+if (!CMS.Views['Metadata']) CMS.Views.Metadata = {};
+
+CMS.Views.Metadata.Number = CMS.Views.Metadata.String.extend({
+
+ getValue: function() {
+ var stringVal = this.$el.find('#' + this.uniqueId).val();
+ if (this.isInteger) {
+ return parseInt(stringVal)
+ }
+ else {
+ return parseFloat(stringVal)
+ }
+ }
+});
\ No newline at end of file
diff --git a/cms/static/js/views/metadata_option_view.js b/cms/static/js/views/metadata_option_view.js
index e69de29bb2..28c49fb3d4 100644
--- a/cms/static/js/views/metadata_option_view.js
+++ b/cms/static/js/views/metadata_option_view.js
@@ -0,0 +1,37 @@
+if (!CMS.Views['Metadata']) CMS.Views.Metadata = {};
+
+CMS.Views.Metadata.Option = Backbone.View.extend({
+
+ // Model class ...
+ events : {
+ },
+
+ initialize : function() {
+ var self = this;
+ this.uniqueId = _.uniqueId('metadata_option_entry_');
+ // instantiates an editor template for each update in the collection
+ window.templateLoader.loadRemoteTemplate("metadata_option_entry",
+ "/static/client_templates/metadata_option_entry.html",
+ function (raw_template) {
+ self.template = _.template(raw_template);
+ self.$el.append(self.template({model: self.model, uniqueId: self.uniqueId}));
+ $('#' + self.uniqueId + " option").filter(function() {
+ return $(this).text() === self.model.get('value');
+ }).prop('selected', true);
+ if (self.model.get('explicitly_set')) {
+ self.$el.addClass('is-set');
+ self.$el.find('#'+self.uniqueId + " .setting-clear").addClass('active');
+ }
+
+ }
+ );
+ },
+
+ modified: function () {
+ return this.getValue() !== this.model.getOriginalValue();
+ },
+
+ getValue: function() {
+ return this.$el.find('#' + this.uniqueId).find(":selected").text();
+ }
+});
diff --git a/cms/static/js/views/metadata_string_view.js b/cms/static/js/views/metadata_string_view.js
index 53937f3a47..465b75ba8b 100644
--- a/cms/static/js/views/metadata_string_view.js
+++ b/cms/static/js/views/metadata_string_view.js
@@ -1,6 +1,6 @@
if (!CMS.Views['Metadata']) CMS.Views.Metadata = {};
-CMS.Views.Metadata.Generic = Backbone.View.extend({
+CMS.Views.Metadata.String = Backbone.View.extend({
// Model class ...
events : {
@@ -8,12 +8,17 @@ CMS.Views.Metadata.Generic = Backbone.View.extend({
initialize : function() {
var self = this;
+ this.uniqueId = _.uniqueId('metadata_string_entry_');
// instantiates an editor template for each update in the collection
- window.templateLoader.loadRemoteTemplate("metadata_entry",
+ window.templateLoader.loadRemoteTemplate("metadata_string_entry",
"/static/client_templates/metadata_string_entry.html",
function (raw_template) {
self.template = _.template(raw_template);
- self.$el.append(self.template({model: self.model}));
+ self.$el.append(self.template({model: self.model, uniqueId: self.uniqueId}));
+ if (self.model.get('explicitly_set')) {
+ self.$el.addClass('is-set');
+ self.$el.find('#'+self.uniqueId + " .setting-clear").addClass('active');
+ }
}
);
},
@@ -23,6 +28,6 @@ CMS.Views.Metadata.Generic = Backbone.View.extend({
},
getValue: function() {
- return this.$el.find('.editor').val();
+ return this.$el.find('#' + this.uniqueId).val();
}
});
diff --git a/cms/templates/base.html b/cms/templates/base.html
index 5825cdb1b9..6649affefb 100644
--- a/cms/templates/base.html
+++ b/cms/templates/base.html
@@ -53,6 +53,7 @@
+
diff --git a/common/lib/xmodule/xmodule/capa_module.py b/common/lib/xmodule/xmodule/capa_module.py
index 479cd5a759..004411e509 100644
--- a/common/lib/xmodule/xmodule/capa_module.py
+++ b/common/lib/xmodule/xmodule/capa_module.py
@@ -68,7 +68,8 @@ class CapaFields(object):
showanswer = String(help="When to show the problem answer to the student", scope=Scope.settings, default="closed",
values=["answered", "always", "attempted", "closed", "never"])
force_save_button = Boolean(help="Whether to force the save button to appear on the page", scope=Scope.settings, default=False)
- rerandomize = Randomization(help="When to rerandomize the problem", default="always", scope=Scope.settings)
+ rerandomize = Randomization(help="When to rerandomize the problem", default="always", scope=Scope.settings,
+ values=["always", "onreset", "never", "per_student"])
data = String(help="XML data for the problem", scope=Scope.content)
correct_map = Object(help="Dictionary with the correctness of current student answers", scope=Scope.user_state, default={})
input_state = Object(help="Dictionary for maintaining the state of inputtypes", scope=Scope.user_state)
diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py
index 8b5ae3e63f..f3b249adff 100644
--- a/common/lib/xmodule/xmodule/x_module.py
+++ b/common/lib/xmodule/xmodule/x_module.py
@@ -648,8 +648,13 @@ class XModuleDescriptor(XModuleFields, HTMLSnippet, ResourceTemplates, XBlock):
'inheritable': inheritable,
'explicitly_set': explicitly_set}
+ values = [] if field.values is None else field.values
+ for index, choice in enumerate(values):
+ values[index] = field.to_json(choice)
+
simple_metadata[field.name] = {'value': field.to_json(value),
'display_name' : field.display_name,
+ 'options' : values,
'default_value': field.to_json(default_value),
'inheritable': inheritable,
'explicitly_set': explicitly_set,