287 lines
9.7 KiB
JavaScript
287 lines
9.7 KiB
JavaScript
/* this view should own everything on the page which has controls effecting its operation
|
|
generate other views for the individual editors.
|
|
The render here adds views for each update/handout by delegating to their collections but does not
|
|
generate any html for the surrounding page.
|
|
*/
|
|
CMS.Views.CourseInfoEdit = Backbone.View.extend({
|
|
// takes CMS.Models.CourseInfo as model
|
|
tagName: 'div',
|
|
|
|
render: function() {
|
|
// instantiate the ClassInfoUpdateView and delegate the proper dom to it
|
|
new CMS.Views.ClassInfoUpdateView({
|
|
el: this.$('#course-update-view'),
|
|
collection: this.model.get('updates')
|
|
});
|
|
|
|
new CMS.Views.ClassInfoHandoutsView({
|
|
el: this.$('#course-handouts-view'),
|
|
model: this.model.get('handouts')
|
|
});
|
|
return this;
|
|
}
|
|
});
|
|
|
|
// ??? Programming style question: should each of these classes be in separate files?
|
|
CMS.Views.ClassInfoUpdateView = Backbone.View.extend({
|
|
// collection is CourseUpdateCollection
|
|
events: {
|
|
"click .new-update-button" : "onNew",
|
|
"click .save-button" : "onSave",
|
|
"click .cancel-button" : "onCancel",
|
|
"click .edit-button" : "onEdit",
|
|
"click .delete-button" : "onDelete"
|
|
},
|
|
|
|
initialize: function() {
|
|
var self = this;
|
|
// instantiates an editor template for each update in the collection
|
|
window.templateLoader.loadRemoteTemplate("course_info_update",
|
|
// TODO Where should the template reside? how to use the static.url to create the path?
|
|
"/static/client_templates/course_info_update.html",
|
|
function (raw_template) {
|
|
self.template = _.template(raw_template);
|
|
self.render();
|
|
}
|
|
);
|
|
},
|
|
|
|
render: function () {
|
|
// iterate over updates and create views for each using the template
|
|
var updateEle = this.$el.find("#course-update-list");
|
|
// remove and then add all children
|
|
$(updateEle).empty();
|
|
var self = this;
|
|
this.collection.each(function (update) {
|
|
var newEle = self.template({ updateModel : update });
|
|
$(updateEle).append(newEle);
|
|
});
|
|
this.$el.find(".new-update-form").hide();
|
|
this.$el.find('.date').datepicker({ 'dateFormat': 'MM d, yy' });
|
|
return this;
|
|
},
|
|
|
|
onNew: function(event) {
|
|
event.preventDefault();
|
|
var self = this;
|
|
// create new obj, insert into collection, and render this one ele overriding the hidden attr
|
|
var newModel = new CMS.Models.CourseUpdate();
|
|
this.collection.add(newModel, {at : 0});
|
|
|
|
var $newForm = $(this.template({ updateModel : newModel }));
|
|
|
|
var updateEle = this.$el.find("#course-update-list");
|
|
$(updateEle).prepend($newForm);
|
|
|
|
var $textArea = $newForm.find(".new-update-content").first();
|
|
if (this.$codeMirror == null ) {
|
|
this.$codeMirror = CodeMirror.fromTextArea($textArea.get(0), {
|
|
mode: "text/html",
|
|
lineNumbers: true,
|
|
lineWrapping: true,
|
|
});
|
|
}
|
|
|
|
$newForm.addClass('editing');
|
|
this.$currentPost = $newForm.closest('li');
|
|
|
|
window.$modalCover.show();
|
|
window.$modalCover.bind('click', function() {
|
|
self.closeEditor(self, true);
|
|
});
|
|
|
|
$('.date').datepicker('destroy');
|
|
$('.date').datepicker({ 'dateFormat': 'MM d, yy' });
|
|
},
|
|
|
|
onSave: function(event) {
|
|
event.preventDefault();
|
|
var targetModel = this.eventModel(event);
|
|
targetModel.set({ date : this.dateEntry(event).val(), content : this.$codeMirror.getValue() });
|
|
// push change to display, hide the editor, submit the change
|
|
targetModel.save({}, {error : CMS.ServerError});
|
|
this.closeEditor(this);
|
|
},
|
|
|
|
onCancel: function(event) {
|
|
event.preventDefault();
|
|
// change editor contents back to model values and hide the editor
|
|
$(this.editor(event)).hide();
|
|
var targetModel = this.eventModel(event);
|
|
this.closeEditor(this, !targetModel.id);
|
|
},
|
|
|
|
onEdit: function(event) {
|
|
event.preventDefault();
|
|
var self = this;
|
|
this.$currentPost = $(event.target).closest('li');
|
|
this.$currentPost.addClass('editing');
|
|
|
|
$(this.editor(event)).show();
|
|
var $textArea = this.$currentPost.find(".new-update-content").first();
|
|
if (this.$codeMirror == null ) {
|
|
this.$codeMirror = CodeMirror.fromTextArea($textArea.get(0), {
|
|
mode: "text/html",
|
|
lineNumbers: true,
|
|
lineWrapping: true,
|
|
});
|
|
}
|
|
|
|
window.$modalCover.show();
|
|
var targetModel = this.eventModel(event);
|
|
window.$modalCover.bind('click', function() {
|
|
self.closeEditor(self);
|
|
});
|
|
},
|
|
|
|
onDelete: function(event) {
|
|
event.preventDefault();
|
|
// TODO ask for confirmation
|
|
// remove the dom element and delete the model
|
|
var targetModel = this.eventModel(event);
|
|
this.modelDom(event).remove();
|
|
var cacheThis = this;
|
|
targetModel.destroy({success : function (model, response) {
|
|
cacheThis.collection.fetch({success : function() {cacheThis.render();},
|
|
error : CMS.ServerError});
|
|
},
|
|
error : CMS.ServerError
|
|
});
|
|
},
|
|
|
|
closeEditor: function(self, removePost) {
|
|
var targetModel = self.collection.getByCid(self.$currentPost.attr('name'));
|
|
|
|
if(removePost) {
|
|
self.$currentPost.remove();
|
|
}
|
|
|
|
// close the modal and insert the appropriate data
|
|
self.$currentPost.removeClass('editing');
|
|
self.$currentPost.find('.date-display').html(targetModel.get('date'));
|
|
self.$currentPost.find('.date').val(targetModel.get('date'));
|
|
self.$currentPost.find('.update-contents').html(targetModel.get('content'));
|
|
self.$currentPost.find('.new-update-content').val(targetModel.get('content'));
|
|
self.$currentPost.find('form').hide();
|
|
window.$modalCover.unbind('click');
|
|
window.$modalCover.hide();
|
|
this.$codeMirror = null;
|
|
self.$currentPost.find('.CodeMirror').remove();
|
|
},
|
|
|
|
// Dereferencing from events to screen elements
|
|
eventModel: function(event) {
|
|
// not sure if it should be currentTarget or delegateTarget
|
|
return this.collection.getByCid($(event.currentTarget).attr("name"));
|
|
},
|
|
|
|
modelDom: function(event) {
|
|
return $(event.currentTarget).closest("li");
|
|
},
|
|
|
|
editor: function(event) {
|
|
var li = $(event.currentTarget).closest("li");
|
|
if (li) return $(li).find("form").first();
|
|
},
|
|
|
|
dateEntry: function(event) {
|
|
var li = $(event.currentTarget).closest("li");
|
|
if (li) return $(li).find(".date").first();
|
|
},
|
|
|
|
contentEntry: function(event) {
|
|
return $(event.currentTarget).closest("li").find(".new-update-content").first();
|
|
},
|
|
|
|
dateDisplay: function(event) {
|
|
return $(event.currentTarget).closest("li").find("#date-display").first();
|
|
},
|
|
|
|
contentDisplay: function(event) {
|
|
return $(event.currentTarget).closest("li").find(".update-contents").first();
|
|
}
|
|
|
|
});
|
|
|
|
// the handouts view is dumb right now; it needs tied to a model and all that jazz
|
|
CMS.Views.ClassInfoHandoutsView = Backbone.View.extend({
|
|
// collection is CourseUpdateCollection
|
|
events: {
|
|
"click .save-button" : "onSave",
|
|
"click .cancel-button" : "onCancel",
|
|
"click .edit-button" : "onEdit"
|
|
},
|
|
|
|
initialize: function() {
|
|
var self = this;
|
|
this.model.fetch(
|
|
{
|
|
complete: function() {
|
|
window.templateLoader.loadRemoteTemplate("course_info_handouts",
|
|
"/static/client_templates/course_info_handouts.html",
|
|
function (raw_template) {
|
|
self.template = _.template(raw_template);
|
|
self.render();
|
|
}
|
|
);
|
|
},
|
|
error : CMS.ServerError
|
|
}
|
|
);
|
|
},
|
|
|
|
render: function () {
|
|
var updateEle = this.$el;
|
|
var self = this;
|
|
this.$el.html(
|
|
$(this.template( {
|
|
model: this.model
|
|
})
|
|
)
|
|
);
|
|
this.$preview = this.$el.find('.handouts-content');
|
|
this.$form = this.$el.find(".edit-handouts-form");
|
|
this.$editor = this.$form.find('.handouts-content-editor');
|
|
this.$form.hide();
|
|
|
|
return this;
|
|
},
|
|
|
|
onEdit: function(event) {
|
|
var self = this;
|
|
this.$editor.val(this.$preview.html());
|
|
this.$form.show();
|
|
if (this.$codeMirror == null) {
|
|
this.$codeMirror = CodeMirror.fromTextArea(this.$editor.get(0), {
|
|
mode: "text/html",
|
|
lineNumbers: true,
|
|
lineWrapping: true,
|
|
});
|
|
}
|
|
window.$modalCover.show();
|
|
window.$modalCover.bind('click', function() {
|
|
self.closeEditor(self);
|
|
});
|
|
},
|
|
|
|
onSave: function(event) {
|
|
this.model.set('data', this.$codeMirror.getValue());
|
|
this.render();
|
|
this.model.save({}, {error: CMS.ServerError});
|
|
this.$form.hide();
|
|
this.closeEditor(this);
|
|
},
|
|
|
|
onCancel: function(event) {
|
|
this.$form.hide();
|
|
this.closeEditor(this);
|
|
},
|
|
|
|
closeEditor: function(self) {
|
|
this.$form.hide();
|
|
window.$modalCover.unbind('click');
|
|
window.$modalCover.hide();
|
|
self.$form.find('.CodeMirror').remove();
|
|
this.$codeMirror = null;
|
|
}
|
|
}); |