Commit 339949f9 by Don Mitchell

Another checkpoint before pull/merge

parent 7fecf1f2
CMS.Models.Location = Backbone.Models.extend({
defaults: {
tag: "",
name: "",
org: "",
course: "",
category: "",
name: ""
......@@ -9,7 +9,7 @@ CMS.Models.Location = Backbone.Models.extend({
toUrl: function(overrides) {
return
(overrides['tag'] ? overrides['tag'] : this.get('tag')) + "://" +
(overrides['name'] ? overrides['name'] : this.get('name')) + "/" +
(overrides['org'] ? overrides['org'] : this.get('org')) + "/" +
(overrides['course'] ? overrides['course'] : this.get('course')) + "/" +
(overrides['category'] ? overrides['category'] : this.get('category')) + "/" +
(overrides['name'] ? overrides['name'] : this.get('name')) + "/";
......
CMS.Models.Settings.CourseDetails = Backbone.Models.extend({
defaults: {
location : null, # a Location model, required
start_date: null,
end_date: null,
milestones: null, # a CourseRelativeCollection
start_date: null, # maps to 'start'
end_date: null, # maps to 'end'
enrollment_start: null,
enrollment_end: null,
syllabus: null,
overview: "",
statement: "",
intro_video: null,
requirements: "",
effort: null, # an int or null
textbooks: null, # a CourseRelativeCollection
prereqs: null, # a CourseRelativeCollection
faqs: null # a CourseRelativeCollection
effort: null # an int or null
},
// When init'g from html script, ensure you pass {parse: true} as an option (2nd arg to reset)
......@@ -20,18 +16,6 @@ CMS.Models.Settings.CourseDetails = Backbone.Models.extend({
if (attributes['location']) {
attributes.location = new CMS.Models.Location(attributes.location);
};
if (attributes['milestones']) {
attributes.milestones = new CMS.Models.CourseRelativeCollection(attributes.milestones);
};
if (attributes['textbooks']) {
attributes.textbooks = new CMS.Models.CourseRelativeCollection(attributes.textbooks);
};
if (attributes['prereqs']) {
attributes.prereqs = new CMS.Models.CourseRelativeCollection(attributes.prereqs);
};
if (attributes['faqs']) {
attributes.faqs = new CMS.Models.CourseRelativeCollection(attributes.faqs);
};
},
urlRoot: function() {
......
......@@ -8,6 +8,19 @@ CMS.Models.Settings.CourseSettings = Backbone.Model.extend({
grading: null,
problems: null,
discussions: null
},
retrieve: function(submodel, callback) {
if (this.get(submodel)) callback();
else switch (submodel) {
case 'details':
this.set('details', new CMS.Models.Settings.CourseDetails({location: this.get('courseLocation')})).fetch({
success : callback
});
break;
default:
break;
}
}
// write getters which get the relevant sub model from the server if not already loaded
})
\ No newline at end of file
......@@ -2,17 +2,61 @@ CMS.Views.Settings.Main = Backbone.View.extend({
// Model class is CMS.Models.Settings.CourseSettings
// allow navigation between the tabs
events: {
'click .settings-page-menu a': "showSettingsTab"
'click .settings-page-menu a': "showSettingsTab",
'blur input' : 'updateModel'
},
currentTab: null,
subviews: {}, # indexed by tab name
initialize: function() {
// load templates
this.currentTab = this.$el.find('.settings-page-menu .is-shown').attr('data-section');
// create the initial subview
this.subviews[this.currentTab] = this.createSubview();
// fill in fields
this.$el.find("#course-name-input").val(this.model.get('courseLocation').get('name'));
this.$el.find("#course-organization-input").val(this.model.get('courseLocation').get('org'));
this.$el.find("#course-number-input").val(this.model.get('courseLocation').get('course'));
this.render();
},
render: function() {
// create any necessary subviews and put them onto the page
if (!this.model.has(this.currentTab)) {
// TODO disable screen until fetch completes?
this.model.retrieve(this.currentTab, function() {
this.subviews[this.currentTab] = this.createSubview();
this.subviews[this.currentTab].render();
});
}
}
else this.callRenderFunction();
return this;
},
createSubview: function() {
switch (this.currentTab) {
case 'details':
return new CMS.Views.Settings.Details({
el: this.$el.find('.settings-' + this.currentTab),
model: this.model.get(this.currentTab);
});
break;
case 'faculty':
break;
case 'grading':
break;
case 'problems':
break;
case 'discussions':
break;
}
},
currentTab: null,
showSettingsTab: function(e) {
this.currentTab = $(e.target).attr('data-section');
$('.settings-page-section > section').hide();
......@@ -20,10 +64,42 @@ CMS.Views.Settings.Main = Backbone.View.extend({
$('.settings-page-menu .is-shown').removeClass('is-shown');
$(e.target).addClass('is-shown');
// fetch model for the tab if not loaded already
if (!this.model.has(this.currentTab)) {
// TODO disable screen until fetch completes?
this.model.retrieve(this.currentTab, function() { this.render(); });
}
this.render();
}
})
\ No newline at end of file
});
CMS.Views.Settings.Details = Backbone.View.extend({
// Model class is CMS.Models.Settings.CourseDetails
events : {
"blur input" : "updateModel"
},
render: function() {
if (this.model.has('start_date')) this.$el.find('#course-start-date-input').datepicker('setDate', this.model.get('start_date'));
if (this.model.has('end_date')) this.$el.find('#course-end-date-input').datepicker('setDate', this.model.get('end_date'));
if (this.model.has('enrollment_start')) this.$el.find('#course-enrollment-start-input').datepicker('setDate', this.model.get('enrollment_start'));
if (this.model.has('enrollment_end')) this.$el.find('#course-enrollment-end-input').datepicker('setDate', this.model.get('enrollment_end'));
},
updateModel: function(event) {
// figure out which field
switch (event.currentTarget.id) {
case 'course-start-date-input':
this.model.set('start_date', $(event.currentTarget).datepicker('getDate'));
break;
case 'course-end-date-input':
this.model.set('end_date', $(event.currentTarget).datepicker('getDate'));
break;
case 'course-enrollment-start-date-input':
this.model.set('enrollment_start', $(event.currentTarget).datepicker('getDate'));
break;
case 'course-enrollment-end-date-input':
this.model.set('enrollment_end', $(event.currentTarget).datepicker('getDate'));
break;
default:
break;
}
// save the updated model
this.model.save();
}
});
\ No newline at end of file
......@@ -28,6 +28,7 @@
el: $('.main-wrapper'),
model : settingsModel)
});
$('.set-date').datepicker({ 'dateFormat': 'm/d/yy' });
editor.render();
});
......@@ -56,7 +57,6 @@
$('.new-grade-button').bind('click', addNewGrade);
$body.on('click', '.remove-button', removeGrade);
$('.set-date').datepicker({ 'dateFormat': 'm/d/yy' });
})();
function addNewGrade(e) {
......@@ -146,7 +146,7 @@
<div class="field">
<div class="input">
<input type="text" class="long" id="course-name-input" value="[Course Name]" disabled="disabled">
<span class="tip tip-stacked">This is used in <a href="[COURSE_SUMMARY_URL]">your course URL</a>, and cannot be changed</span>
<span class="tip tip-stacked">This is used in <a href="${get_lms_link_for_item(context_course.location,True)}">your course URL</a>, and cannot be changed</span>
</div>
</div>
</div>
......@@ -156,7 +156,7 @@
<div class="field">
<div class="input">
<input type="text" class="long" id="course-organization-input" value="[Course Organization]" disabled="disabled">
<span class="tip tip-stacked">This is used in <a href="[COURSE_SUMMARY_URL]">your course URL</a>, and cannot be changed</span>
<span class="tip tip-stacked">This is used in <a href="${get_lms_link_for_item(context_course.location,True)}">your course URL</a>, and cannot be changed</span>
</div>
</div>
</div>
......@@ -167,7 +167,7 @@
<div class="input">
<input type="text" class="short" id="course-number-input" value="[Course No.]" disabled="disabled">
<span class="tip tip-inline">e.g. 101x</span>
<span class="tip tip-stacked">This is used in <a href="[COURSE_SUMMARY_URL]">your course URL</a>, and cannot be changed</span>
<span class="tip tip-stacked">This is used in <a href="${get_lms_link_for_item(context_course.location,True)}">your course URL</a>, and cannot be changed</span>
</div>
</div>
</div>
......@@ -255,7 +255,7 @@
<div class="field">
<div class="input">
<textarea class="long tall edit-box tinymce" id="course-overview"></textarea>
<span class="tip tip-stacked">Introductions, prerequisites, FAQs that are used on <a href="[COURSE_SUMMARY_URL]">your course summary page</a></span>
<span class="tip tip-stacked">Introductions, prerequisites, FAQs that are used on <a href="${get_lms_link_for_item(context_course.location,True)}">your course summary page</a></span>
</div>
</div>
</div>
......
from common.djangoapps.models.course_relative import CourseRelativeMember
### A basic question is whether to break the details into schedule, intro, requirements, and misc sub objects
class CourseDetails:
def __init__(self, location):
self.course_location = location # a Location obj
self.start_date = None
self.end_date = None
self.milestones = []
self.start_date = None # 'start'
self.end_date = None # 'end'
self.enrollment_start = None
self.enrollment_end = None
self.syllabus = None # a pdf file asset
self.overview = "" # html to render as the overview
self.statement = ""
self.intro_video = None # a video pointer
self.requirements = "" # html
self.effort = None # int hours/week
self.textbooks = [] # linked_asset
self.prereqs = [] # linked_asset
self.faqs = [] # summary_detail_pair
@classmethod
def fetch(cls, course_location):
......@@ -28,9 +22,3 @@ class CourseDetails:
return course
class CourseMilestone(CourseRelativeMember):
def __init__(self, location, idx):
CourseRelativeMember.__init__(self, location, idx)
self.date = None
self.description = ""
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