diff --git a/cms/static/coffee/src/models/module.coffee b/cms/static/coffee/src/models/module.coffee index c3988b26e0..6e5c8ac785 100644 --- a/cms/static/coffee/src/models/module.coffee +++ b/cms/static/coffee/src/models/module.coffee @@ -10,7 +10,3 @@ class CMS.Models.Module extends Backbone.Model @unset('module') delete attributes.module super(attributes) - - save: (args...) -> - @set(data: @module.save()) if @module - super(args...) diff --git a/cms/static/coffee/src/views/module_edit.coffee b/cms/static/coffee/src/views/module_edit.coffee index b9d0245ed9..8a9120db9e 100644 --- a/cms/static/coffee/src/views/module_edit.coffee +++ b/cms/static/coffee/src/views/module_edit.coffee @@ -3,58 +3,65 @@ class CMS.Views.ModuleEdit extends Backbone.View className: 'xmodule_edit' initialize: -> - @delegate() + @module = @options.module + @module.onUpdate(@save) - @$component_editor = @$el.find('.component-editor') - @$metadata = @$component_editor.find('.metadata_edit') + @setEvents() - delegate: -> + $component_editor: -> @$el.find('.component-editor') + + setEvents: -> id = @$el.data('id') - events = {} - events["click .component-editor[data-id=#{ id }] .cancel-button"] = 'cancel' - events["click .component-editor[data-id=#{ id }] .save-button"] = 'save' - events["click .component-actions[data-id=#{ id }] .edit-button"] = 'edit' + @events = {} + @events["click .component-editor[data-id=#{ id }] .cancel-button"] = 'clickCancelButton' + @events["click .component-editor[data-id=#{ id }] .save-button"] = 'clickSaveButton' + @events["click .component-actions[data-id=#{ id }] .edit-button"] = 'clickEditButton' - @delegateEvents(events) + @delegateEvents() metadata: -> # cdodge: package up metadata which is separated into a number of input fields # there's probably a better way to do this, but at least this lets me continue to move onwards _metadata = {} - if @$metadata + $metadata = @$component_editor().find('.metadata_edit') + + if $metadata # walk through the set of elments which have the 'xmetadata_name' attribute and # build up a object to pass back to the server on the subsequent POST - _metadata[$(el).data("metadata-name")] = el.value for el in $('[data-metadata-name]', @$metadata) + _metadata[$(el).data("metadata-name")] = el.value for el in $('[data-metadata-name]', $metadata) _metadata - save: (event) => - event.preventDefault() - @model.save( - metadata: @metadata() - ).done((preview) => + save: (data) => + @model.set(data) + @model.save().done((preview) => alert("Your changes have been saved.") - - new_el = $(preview) - @$el.replaceWith(new_el) - @$el = new_el - @delegate() - - @model.module = XModule.loadModule(@$el) + $preview = $(preview) + @$el.replaceWith($preview) + @setElement($preview) + @module.constructor(@$el) XModule.loadModules(@$el) + ).fail( -> alert("There was an error saving your changes. Please try again.") ) - cancel: (event) -> + clickSaveButton: (event) => + event.preventDefault() + data = @module.save() + data.metadata = @metadata() + + @save(data) + + clickCancelButton: (event) -> event.preventDefault() @$el.removeClass('editing') - @$component_editor.slideUp(150) + @$component_editor().slideUp(150) - edit: (event) -> + clickEditButton: (event) -> event.preventDefault() @$el.addClass('editing') - @$component_editor.slideDown(150) + @$component_editor().slideDown(150) diff --git a/cms/static/js/base.js b/cms/static/js/base.js index c560524676..78b61fff0f 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -14,16 +14,13 @@ $(document).ready(function() { $newComponentStep2 = $('.new-component-step-2'); $newComponentButton = $('.new-component-button'); - $(document).bind('XModule.loaded', function(e, element) { - if ($(element).hasClass('.xmodule_display')) { - return - } + $(document).bind('XModule.loaded.edit', function(e, element, module) { var previewType = $(element).data('preview-type'); var moduleType = $(element).data('type'); new CMS.Views.ModuleEdit({ el: element, + module: module, model: new CMS.Models.Module({ - module: $(element).data('module'), id: $(element).data('id'), type: moduleType == 'None' ? null : moduleType, previewType: previewType == 'None' ? null : previewType, diff --git a/common/lib/xmodule/xmodule/js/src/discussion/display.coffee b/common/lib/xmodule/xmodule/js/src/discussion/display.coffee index 27a67f5aab..a350cf9866 100644 --- a/common/lib/xmodule/xmodule/js/src/discussion/display.coffee +++ b/common/lib/xmodule/xmodule/js/src/discussion/display.coffee @@ -1,4 +1,4 @@ -class @InlineDiscussion +class @InlineDiscussion extends XModule.Descriptor constructor: (element) -> @el = $(element).find('.discussion-module') @view = new DiscussionModuleView(el: @el) diff --git a/common/lib/xmodule/xmodule/js/src/raw/edit/json.coffee b/common/lib/xmodule/xmodule/js/src/raw/edit/json.coffee index 4dc88310ba..b795970b73 100644 --- a/common/lib/xmodule/xmodule/js/src/raw/edit/json.coffee +++ b/common/lib/xmodule/xmodule/js/src/raw/edit/json.coffee @@ -1,7 +1,8 @@ -class @JSONEditingDescriptor +class @JSONEditingDescriptor extends XModule.Descriptor constructor: (@element) -> @edit_box = CodeMirror.fromTextArea($(".edit-box", @element)[0], { mode: { name: "javascript", json: true } }) - save: -> JSON.parse @edit_box.getValue() + save: -> + data: JSON.parse @edit_box.getValue() diff --git a/common/lib/xmodule/xmodule/js/src/raw/edit/xml.coffee b/common/lib/xmodule/xmodule/js/src/raw/edit/xml.coffee index 286da45dc1..47c993e78d 100644 --- a/common/lib/xmodule/xmodule/js/src/raw/edit/xml.coffee +++ b/common/lib/xmodule/xmodule/js/src/raw/edit/xml.coffee @@ -1,7 +1,8 @@ -class @XMLEditingDescriptor +class @XMLEditingDescriptor extends XModule.Descriptor constructor: (@element) -> @edit_box = CodeMirror.fromTextArea($(".edit-box", @element)[0], { mode: "xml" }) - save: -> @edit_box.getValue() + save: -> + data: @edit_box.getValue() diff --git a/common/lib/xmodule/xmodule/js/src/sequence/edit.coffee b/common/lib/xmodule/xmodule/js/src/sequence/edit.coffee index cd047798a4..e46e91e11e 100644 --- a/common/lib/xmodule/xmodule/js/src/sequence/edit.coffee +++ b/common/lib/xmodule/xmodule/js/src/sequence/edit.coffee @@ -1,4 +1,4 @@ -class @SequenceDescriptor +class @SequenceDescriptor extends XModule.Descriptor constructor: (@element) -> @$tabs = $(@element).find("#sequence-list") @$tabs.sortable() diff --git a/common/lib/xmodule/xmodule/js/src/vertical/edit.coffee b/common/lib/xmodule/xmodule/js/src/vertical/edit.coffee index da4c38999a..2945af009a 100644 --- a/common/lib/xmodule/xmodule/js/src/vertical/edit.coffee +++ b/common/lib/xmodule/xmodule/js/src/vertical/edit.coffee @@ -1,4 +1,4 @@ -class @VerticalDescriptor +class @VerticalDescriptor extends XModule.Descriptor constructor: (@element) -> @$items = $(@element).find(".vert-mod") @$items.sortable() diff --git a/common/lib/xmodule/xmodule/seq_module.py b/common/lib/xmodule/xmodule/seq_module.py index 6abe0a0885..bcd2932537 100644 --- a/common/lib/xmodule/xmodule/seq_module.py +++ b/common/lib/xmodule/xmodule/seq_module.py @@ -86,6 +86,7 @@ class SequenceModule(XModule): 'progress_status': Progress.to_js_status_str(progress), 'progress_detail': Progress.to_js_detail_str(progress), 'type': child.get_icon_class(), + 'id': child.id, } if childinfo['title']=='': childinfo['title'] = child.metadata.get('display_name','') diff --git a/common/static/coffee/src/xmodule.coffee b/common/static/coffee/src/xmodule.coffee index 59925f4dac..4e3e7fec50 100644 --- a/common/static/coffee/src/xmodule.coffee +++ b/common/static/coffee/src/xmodule.coffee @@ -10,8 +10,13 @@ return try - $(element).data('module', new window[moduleType](element)) - $(document).trigger('XModule.loaded', [element]) + module = new window[moduleType](element) + if $(element).hasClass('xmodule_edit') + $(document).trigger('XModule.loaded.edit', [element, module]) + + if $(element).hasClass('xmodule_display') + $(document).trigger('XModule.loaded.display', [element, module]) + catch error console.error "Unable to load #{moduleType}: #{error.message}" if console @@ -29,3 +34,40 @@ modules = $(selector) modules.each (idx, element) -> XModule.loadModule element + +class @XModule.Descriptor + + callbacks: [] + + ### + Register a callback method to be called when the state of this + descriptor is updated. The callback will be passed the results + of calling the save method on this descriptor. + ### + onUpdate: (callback) -> + @callbacks.push(callback) + + ### + Notify registered callbacks that the state of this descriptor has changed + ### + update: => + data = @save() + callback(data) for callback in @callbacks + + ### + Bind the module to an element. This may be called multiple times, + if the element content has changed and so the module needs to be rebound + + @method: constructor + @param {html element} the .xmodule_edit section containing all of the descriptor content + ### + constructor: (@element) -> return + + ### + Return the current state of the descriptor (to be written to the module store) + + @method: save + @returns {object} An object containing children and data attributes (both optional). + The contents of the attributes will be saved to the server + ### + save: -> return {} diff --git a/lms/templates/seq_module.html b/lms/templates/seq_module.html index 8ff3e096dd..cfacfa92c8 100644 --- a/lms/templates/seq_module.html +++ b/lms/templates/seq_module.html @@ -8,7 +8,9 @@ ## implementation note: will need to figure out how to handle combining detail ## statuses of multiple modules in js.
  • - +

    ${item['title']}