From e0eec89e09c964854b5547592cdae8bff4971fe0 Mon Sep 17 00:00:00 2001 From: David Baumgold Date: Thu, 23 May 2013 17:05:22 -0400 Subject: [PATCH] Truncate AJAX error messages in notification --- cms/djangoapps/contentstore/views/course.py | 6 +- cms/static/coffee/src/main.coffee | 2 +- cms/templates/js/upload-dialog.underscore | 16 +++ cms/templates/textbooks.html | 108 +++++++++++++++++++- 4 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 cms/templates/js/upload-dialog.underscore diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index 0b5e422056..6d45d5f62a 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -421,14 +421,16 @@ def textbook_index(request, org, course, name): org, course, name: Attributes of the Location for the item to edit """ - location = get_location_and_verify_access(request, org, course, name) - course = modulestore().get_item(location, depth=3) upload_asset_callback_url = reverse('upload_asset', kwargs={ 'org': org, 'course': course, 'coursename': name }) + + location = get_location_and_verify_access(request, org, course, name) + course = modulestore().get_item(location, depth=3) return render_to_response('textbooks.html', { 'context_course': course, + 'course': course, 'upload_asset_callback_url': upload_asset_callback_url, }) diff --git a/cms/static/coffee/src/main.coffee b/cms/static/coffee/src/main.coffee index 1ce1d5d3eb..da8cd400a9 100644 --- a/cms/static/coffee/src/main.coffee +++ b/cms/static/coffee/src/main.coffee @@ -18,7 +18,7 @@ $ -> $(document).ajaxError (event, jqXHR, ajaxSettings, thrownError) -> if ajaxSettings.notifyOnError is false - return + return if jqXHR.responseText try message = JSON.parse(jqXHR.responseText).error diff --git a/cms/templates/js/upload-dialog.underscore b/cms/templates/js/upload-dialog.underscore new file mode 100644 index 0000000000..b3b39ac5ca --- /dev/null +++ b/cms/templates/js/upload-dialog.underscore @@ -0,0 +1,16 @@ +
+

<%= title %>

+

<%= message %>

+ + <% if(uploading) { %> + <% if (uploadedBytes && totalBytes) { %> + <%= uploadedBytes/totalBytes*100 %>% + <% } else { %> + + <% } %> + <% } %> +
+ disabled="disabled"<% } %> /> + +
+
diff --git a/cms/templates/textbooks.html b/cms/templates/textbooks.html index 774f9e26af..3f82716f2f 100644 --- a/cms/templates/textbooks.html +++ b/cms/templates/textbooks.html @@ -11,6 +11,9 @@ + <%block name="jsextra"> @@ -60,7 +63,7 @@ CMS.Views.TextbookEdit = Backbone.View.extend({ events: { "submit": "save", "click .action-cancel": "remove", - "click .add-chapter": "createChapter" + "click .action-add-chapter": "createChapter" }, addOne: function(chapter) { var view = new CMS.Views.ChapterEdit({model: chapter}); @@ -83,6 +86,7 @@ CMS.Views.TextbookEdit = Backbone.View.extend({ CMS.Views.ChapterEdit = Backbone.View.extend({ initialize: function() { this.template = _.template($("#new-chapter-tpl").text()); + this.listenTo(this.model, "change", this.render) }, render: function() { this.$el.html(this.template({ @@ -93,14 +97,114 @@ CMS.Views.ChapterEdit = Backbone.View.extend({ return this; }, events: { - "click .action-close": "removeChapter" + "click .action-close": "removeChapter", + "click .action-uploadasset": "openUploadDialog", + "submit": "uploadAsset" }, removeChapter: function(e) { if(e && e.preventDefault) { e.preventDefault(); } this.model.collection.remove(this.model); return this.remove(); + }, + openUploadDialog: function(e) { + if(e && e.preventDefault) { e.preventDefault(); } + var msg = new CMS.Models.FileUpload({ + title: _.str.sprintf(gettext("Upload a new asset to %s"), + section.escape('name')), + message: "[asset upload requirements]" + }) + var view = new CMS.Views.UploadDialog({model: msg, chapter: this.model}) + $(".wrapper-view").append(view.render().el) } }) +CMS.Models.FileUpload = Backbone.Model.extend({ + defaults: { + "title": "", + "message": "", + "selectFile": null, + "uploading": false, + "uploadedBytes": 0, + "totalBytes": 0, + } +}); +CMS.Views.UploadDialog = Backbone.View.extend({ + initialize: function() { + this.template = _.template($("#upload-dialog-tpl").text()); + this.listenTo(this.model, "change", this.render); + }, + render: function() { + // some browsers (like Chrome) allow you to assign to the .files attribute + // of an DOM element -- for those browsers, we can + // create a new DOM element and assign the old content to it. Other browsers + // (like Firefox) make this attribute read-only, and we have to save the + // old DOM element in order to save it's content. For compatibility purposes, + // we'll just save the old element every time. + var oldInput = this.$("input[type=file]").get(0), selectedFile; + if (oldInput && oldInput.files.length) { + selectedFile = oldInput.files[0]; + } + this.$el.html(this.template({ + url: UPLOAD_ASSET_CALLBACK_URL, + title: this.model.escape('title'), + message: this.model.escape('message'), + selectedFile: selectedFile, + uploading: this.model.get('uploading'), + uploadedBytes: this.model.get('uploadedBytes'), + totalBytes: this.model.get('totalBytes'), + })) + if (oldInput) { + this.$('input[type=file]').replaceWith(oldInput); + } + + return this; + }, + events: { + "change input[type=file]": "selectFile", + "click .action-cancel": "removeSelf", + "click .action-upload": "upload" + }, + selectFile: function(e) { + this.model.set('fileList', e.target.files) + }, + removeSelf: function(e) { + if(e && e.preventDefault) { e.preventDefault(); } + this.remove(); + }, + upload: function(e) { + this.model.set('uploading', true); + this.$("form").ajaxSubmit({ + success: _.bind(this.success, this), + error: _.bind(this.error, this), + uploadProgress: _.bind(this.progress, this), + }); + }, + progress: function(event, position, total, percentComplete) { + this.model.set({ + "uploadedBytes": position, + "totalBytes": total, + }) + }, + success: function(response, statusText, xhr, form) { + this.model.set('uploading', false); + var chapter = this.options.chapter; + if(chapter) { + var options = {} + if(!chapter.get("name")) { + options.name = response.displayname; + } + options.asset_path = response.url; + chapter.set(options); + } + this.remove(); + }, + error: function() { + this.model.set("uploading", false); + } +}) +var section = new CMS.Models.Section({ + id: "${course.id}", + name: "${course.display_name_with_default | h}" +}); $(function() { $(".new-button").click(function() { var textbook = new CMS.Models.Textbook();