Commit 82899d6d by cahrens

Number view.

parent 0aaaf84f
<div class="wrapper-comp-setting"> <div class="wrapper-comp-setting">
<label class="label setting-label" for="<%= uniqueId %>"><%= model.get('display_name') %></label> <label class="label setting-label" for="<%= uniqueId %>"><%= model.get('display_name') %></label>
<input class="input setting-input" type="number" min=".1" max= "10" step=".1" id="<%= uniqueId %>" value='<%= model.get("value") %>'/> <input class="input setting-input" type="number" min="1" max= "10" step="1" id="<%= uniqueId %>" value='<%= model.get("value") %>'/>
<button class="action setting-clear inactive" type="button" name="setting-clear" value="Clear" data-tooltip="Clear"> <button class="action setting-clear inactive" type="button" name="setting-clear" value="Clear" data-tooltip="Clear">
<i class="ss-icon ss-symbolicons-block undo">&#x21A9;</i><span class="sr">Clear Value</span> <i class="ss-icon ss-symbolicons-block undo">&#x21A9;</i><span class="sr">Clear Value</span>
</button> </button>
......
...@@ -30,15 +30,15 @@ CMS.Views.Metadata.Editor = Backbone.View.extend({ ...@@ -30,15 +30,15 @@ CMS.Views.Metadata.Editor = Backbone.View.extend({
el: self.$el.find('.metadata_entry')[counter++], el: self.$el.find('.metadata_entry')[counter++],
model: new CMS.Models.Metadata(item) model: new CMS.Models.Metadata(item)
}; };
if (item.options.length > 0) { if (item.type === 'Select') {
// Right now, all our option types only hold strings. Should really support
// any type though.
self.views.push(new CMS.Views.Metadata.Option(data)); 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 { else {
self.views.push(new CMS.Views.Metadata.String(data)); self.views.push(new CMS.Views.Metadata.String(data));
} }
}); });
} }
); );
...@@ -151,6 +151,28 @@ CMS.Views.Metadata.String = CMS.Views.Metadata.AbstractEditor.extend({ ...@@ -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({ CMS.Views.Metadata.Option = CMS.Views.Metadata.AbstractEditor.extend({
events : { events : {
......
...@@ -63,7 +63,8 @@ class ComplexEncoder(json.JSONEncoder): ...@@ -63,7 +63,8 @@ class ComplexEncoder(json.JSONEncoder):
class CapaFields(object): class CapaFields(object):
attempts = StringyInteger(help="Number of attempts taken by the student on this problem", default=0, scope=Scope.user_state) 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", 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) 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) graceperiod = Timedelta(help="Amount of time after the due date that submissions will be accepted", scope=Scope.settings)
showanswer = String(display_name="Show Answer", showanswer = String(display_name="Show Answer",
...@@ -87,7 +88,8 @@ class CapaFields(object): ...@@ -87,7 +88,8 @@ class CapaFields(object):
done = Boolean(help="Whether the student has answered the problem", scope=Scope.user_state) 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) seed = StringyInteger(help="Random seed for this student", scope=Scope.user_state)
weight = StringyFloat(display_name="Problem Weight", 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) scope=Scope.settings)
markdown = String(help="Markdown source of this module", 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.", source_code = String(help="Source code for LaTeX and Word problems. This feature is not well-supported.",
......
...@@ -57,7 +57,8 @@ class CombinedOpenEndedFields(object): ...@@ -57,7 +57,8 @@ class CombinedOpenEndedFields(object):
ready_to_reset = Boolean(help="If the problem is ready to be reset or not.", default=False, ready_to_reset = Boolean(help="If the problem is ready to be reset or not.", default=False,
scope=Scope.user_state) scope=Scope.user_state)
attempts = Integer(display_name="Maximum Attempts", 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. # 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, 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}]) values=[{'display_name': "True", "value": True}, {'display_name': "False", "value": False}])
......
...@@ -9,7 +9,7 @@ from pkg_resources import resource_listdir, resource_string, resource_isdir ...@@ -9,7 +9,7 @@ from pkg_resources import resource_listdir, resource_string, resource_isdir
from xmodule.modulestore import Location from xmodule.modulestore import Location
from xmodule.modulestore.exceptions import ItemNotFoundError 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__) log = logging.getLogger(__name__)
...@@ -649,17 +649,29 @@ class XModuleDescriptor(XModuleFields, HTMLSnippet, ResourceTemplates, XBlock): ...@@ -649,17 +649,29 @@ class XModuleDescriptor(XModuleFields, HTMLSnippet, ResourceTemplates, XBlock):
'inheritable': inheritable, 'inheritable': inheritable,
'explicitly_set': explicitly_set} '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 values = [] if field.values is None else field.values
if isinstance(values, list):
if len(values) > 0:
type = "Select"
for index, choice in enumerate(values): for index, choice in enumerate(values):
json_choice = choice json_choice = choice
# TODO: test this logic.
if hasattr(json_choice, 'value'): if hasattr(json_choice, 'value'):
json_choice['value'] = field.to_json(json_choice['value']) json_choice['value'] = field.to_json(json_choice['value'])
else: else:
json_choice = field.to_json(json_choice) json_choice = field.to_json(json_choice)
values[index] = 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, simple_metadata[field.name] = {'field_name' : field.name,
'type' : type,
'display_name' : field.display_name, 'display_name' : field.display_name,
'value': field.to_json(value), 'value': field.to_json(value),
'options' : values, 'options' : values,
......
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