From edf6e3e772ca04b556a9c9d73205113fab501436 Mon Sep 17 00:00:00 2001 From: Daryl Hedley Date: Thu, 16 Apr 2015 14:09:45 +0100 Subject: [PATCH 1/8] With error with updates being called when they should create new documents --- .../core/scaffold/views/scaffoldAssetView.js | 68 +++++++------------ 1 file changed, 23 insertions(+), 45 deletions(-) diff --git a/frontend/src/core/scaffold/views/scaffoldAssetView.js b/frontend/src/core/scaffold/views/scaffoldAssetView.js index 1842c6355d..7e02d9716a 100644 --- a/frontend/src/core/scaffold/views/scaffoldAssetView.js +++ b/frontend/src/core/scaffold/views/scaffoldAssetView.js @@ -156,51 +156,29 @@ define(function(require) { }, createCourseAsset: function (courseAssetObject, callback, context) { - // Has this field been set already? - var update = this.findAsset(courseAssetObject.contentTypeId, courseAssetObject.contentType, courseAssetObject.fieldname); - - // Update should only happen if the assetId is different - if (update && update.get('_assetId') != courseAssetObject.assetId) { - // If so, update it ... - update.save({ _assetId: courseAssetObject.assetId },{ - error: function() { - alert('An error occurred doing the save'); - }, - success: function() { - Origin.editor.data.courseAssets.fetch({ - reset:true, - success: function() { - callback.apply(context); - } - }); - } - }); - } else if (!update) { - var courseAsset = new EditorCourseAssetModel(); - // ... otherwise, create it - courseAsset.save({ - _courseId : Origin.editor.data.course.get('_id'), - _contentType : courseAssetObject.contentType, - _contentTypeId : courseAssetObject.contentTypeId, - _fieldName : courseAssetObject.fieldname, - _assetId : courseAssetObject.assetId, - _contentTypeParentId: courseAssetObject.contentTypeParentId - },{ - error: function(error) { - alert('An error occurred doing the save'); - }, - success: function() { - Origin.editor.data.courseAssets.fetch({ - reset:true, - success: function() { - callback.apply(context); - } - }); - } - }); - } else { - callback.apply(context); - } + + var courseAsset = new EditorCourseAssetModel(); + courseAsset.save({ + _courseId : Origin.editor.data.course.get('_id'), + _contentType : courseAssetObject.contentType, + _contentTypeId : courseAssetObject.contentTypeId, + _fieldName : courseAssetObject.fieldname, + _assetId : courseAssetObject.assetId, + _contentTypeParentId: courseAssetObject.contentTypeParentId + },{ + error: function(error) { + alert('An error occurred doing the save'); + }, + success: function() { + Origin.editor.data.courseAssets.fetch({ + reset:true, + success: function() { + callback.apply(context); + } + }); + } + }); + }, removeCourseAsset: function (contentTypeId, contentType, fieldname) { From b0e7eed60621a4b897f4c968885ef4b63424ab0b Mon Sep 17 00:00:00 2001 From: Daryl Hedley Date: Thu, 16 Apr 2015 15:54:15 +0100 Subject: [PATCH 2/8] Few more additions to the assetView --- .../src/core/scaffold/templates/scaffoldAsset.hbs | 8 +++++++- .../src/core/scaffold/views/scaffoldAssetView.js | 12 ++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/frontend/src/core/scaffold/templates/scaffoldAsset.hbs b/frontend/src/core/scaffold/templates/scaffoldAsset.hbs index 0f5734a696..7d624ff8d1 100644 --- a/frontend/src/core/scaffold/templates/scaffoldAsset.hbs +++ b/frontend/src/core/scaffold/templates/scaffoldAsset.hbs @@ -1 +1,7 @@ - \ No newline at end of file + +{{console this}} +{{#if value}} + +{{else}} + +{{/if}} \ No newline at end of file diff --git a/frontend/src/core/scaffold/views/scaffoldAssetView.js b/frontend/src/core/scaffold/views/scaffoldAssetView.js index 7e02d9716a..832647c5e0 100644 --- a/frontend/src/core/scaffold/views/scaffoldAssetView.js +++ b/frontend/src/core/scaffold/views/scaffoldAssetView.js @@ -44,7 +44,7 @@ define(function(require) { }, render: function() { - this.$el.append(Handlebars.templates[this.constructor.template]()); + this.$el.html(Handlebars.templates[this.constructor.template]({value: this.value})); this.setValue(this.value); // Should see if the field contains anything on render // if so disable it @@ -127,8 +127,8 @@ define(function(require) { this.createCourseAsset(courseAssetObject, function() { - this.setValue(data.assetLink); - this.toggleFieldAvailibility(); + this.value = data.assetLink; + this.render(); }, this); } @@ -141,8 +141,8 @@ define(function(require) { onClearButtonClicked: function(event) { event.preventDefault(); - this.setValue(''); - this.toggleFieldAvailibility(); + this.value = ''; + this.render(); this.checkValueHasChanged(); }, @@ -178,7 +178,7 @@ define(function(require) { }); } }); - + }, removeCourseAsset: function (contentTypeId, contentType, fieldname) { From 9f34ffe0ae8cd39f91fdcbdf75eab0b3d2bedbcb Mon Sep 17 00:00:00 2001 From: Daryl Hedley Date: Thu, 16 Apr 2015 17:23:12 +0100 Subject: [PATCH 3/8] Enhancements to backbone forms asset selection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Adds validate:false override as we don’t use backbone.model.validate - Fixes getting and setting of assets - Adds Origin.scaffold.getCurrentForm for all your form goodiness --- frontend/src/core/scaffold/scaffold.js | 6 ++ .../src/core/scaffold/scaffoldOverrides.js | 56 +++++++++++++++++++ .../core/scaffold/views/scaffoldAssetView.js | 51 ++++++++++++++--- 3 files changed, 104 insertions(+), 9 deletions(-) diff --git a/frontend/src/core/scaffold/scaffold.js b/frontend/src/core/scaffold/scaffold.js index bd078e465a..e39d5fa9d2 100644 --- a/frontend/src/core/scaffold/scaffold.js +++ b/frontend/src/core/scaffold/scaffold.js @@ -21,6 +21,7 @@ define(function(require) { var Scaffold = {}; // Used to pass model data around the current form var currentModel; + var currentForm; // Used to store already build schemas var builtSchemas = {}; @@ -286,6 +287,7 @@ define(function(require) { options.fieldsets = buildFieldsets(schema, options); currentModel = options.model; var form = new Backbone.Form(options).render(); + currentForm = form; return form; } @@ -333,6 +335,10 @@ define(function(require) { return currentModel; } + Scaffold.getCurrentForm = function() { + return currentForm; + } + // Listen to modal views Origin.on('scaffold:increaseActiveModals', function() { ActiveItemsModal++; diff --git a/frontend/src/core/scaffold/scaffoldOverrides.js b/frontend/src/core/scaffold/scaffoldOverrides.js index 9c65e369f4..05fb6910a4 100644 --- a/frontend/src/core/scaffold/scaffoldOverrides.js +++ b/frontend/src/core/scaffold/scaffoldOverrides.js @@ -92,4 +92,60 @@ define(function(require) { return this.editor.getData(); } + Backbone.Form.prototype.validate = function(options) { + var self = this, + fields = this.fields, + model = this.model, + errors = {}; + + options = options || {}; + + //Collect errors from schema validation + // !!!OVERRIDE Passing in validate:false will stop the validation of the backbone forms validators + if (!options.skipModelValidate) { + _.each(fields, function(field) { + var error = field.validate(); + if (error) { + errors[field.key] = error; + } + }); + } + + //Get errors from default Backbone model validator + if (!options.skipModelValidate && model && model.validate) { + var modelErrors = model.validate(this.getValue()); + + if (modelErrors) { + var isDictionary = _.isObject(modelErrors) && !_.isArray(modelErrors); + + //If errors are not in object form then just store on the error object + if (!isDictionary) { + errors._others = errors._others || []; + errors._others.push(modelErrors); + } + + //Merge programmatic errors (requires model.validate() to return an object e.g. { fieldKey: 'error' }) + if (isDictionary) { + _.each(modelErrors, function(val, key) { + //Set error on field if there isn't one already + if (fields[key] && !errors[key]) { + fields[key].setError(val); + errors[key] = val; + } + + else { + //Otherwise add to '_others' key + errors._others = errors._others || []; + var tmpErr = {}; + tmpErr[key] = val; + errors._others.push(tmpErr); + } + }); + } + } + } + + return _.isEmpty(errors) ? null : errors; + } + }); \ No newline at end of file diff --git a/frontend/src/core/scaffold/views/scaffoldAssetView.js b/frontend/src/core/scaffold/views/scaffoldAssetView.js index 832647c5e0..0beb0764ed 100644 --- a/frontend/src/core/scaffold/views/scaffoldAssetView.js +++ b/frontend/src/core/scaffold/views/scaffoldAssetView.js @@ -54,10 +54,12 @@ define(function(require) { }, getValue: function() { + return this.value || ''; return this.$('input').val(); }, setValue: function(value) { + this.value = value; this.$('input').val(value); }, @@ -124,10 +126,9 @@ define(function(require) { assetId: assetId } - + this.value = data.assetLink; this.createCourseAsset(courseAssetObject, function() { - this.value = data.assetLink; this.render(); }, this); @@ -141,9 +142,9 @@ define(function(require) { onClearButtonClicked: function(event) { event.preventDefault(); - this.value = ''; - this.render(); this.checkValueHasChanged(); + this.value = ''; + //this.render(); }, findAsset: function (contentTypeId, contentType, fieldname) { @@ -156,6 +157,7 @@ define(function(require) { }, createCourseAsset: function (courseAssetObject, callback, context) { + var self = this; var courseAsset = new EditorCourseAssetModel(); courseAsset.save({ @@ -170,23 +172,54 @@ define(function(require) { alert('An error occurred doing the save'); }, success: function() { - Origin.editor.data.courseAssets.fetch({ - reset:true, + var currentModel = Origin.scaffold.getCurrentModel(); + var currentForm = Origin.scaffold.getCurrentForm(); + var errors = currentForm.commit({validate: false}); + + currentModel.pruneAttributes(); + + currentModel.save(null, { + error: function() { + alert('An error occurred doing the save'); + }, success: function() { - callback.apply(context); + + Origin.editor.data.courseAssets.fetch({ + reset:true, + success: function() { + callback.apply(context); + } + }); + } - }); + }) } }); }, removeCourseAsset: function (contentTypeId, contentType, fieldname) { + var that = this; var courseAsset = this.findAsset(contentTypeId, contentType, fieldname); if (courseAsset) { courseAsset.destroy({ success: function(success) { - Origin.editor.data.courseAssets.fetch({reset:true}); + var currentModel = Origin.scaffold.getCurrentModel(); + var currentForm = Origin.scaffold.getCurrentForm(); + var errors = currentForm.commit({validate: false}); + + currentModel.pruneAttributes(); + + currentModel.save(null, { + error: function() { + alert('An error occurred doing the save'); + }, + success: function() { + that.render(); + Origin.editor.data.courseAssets.fetch({reset:true}); + + } + }) }, error: function(error) { console.log('error', error); From 19a41d40cfc95d5c180ad80c190c0304cae6c8a0 Mon Sep 17 00:00:00 2001 From: Daryl Hedley Date: Wed, 29 Apr 2015 10:47:10 +0100 Subject: [PATCH 4/8] Adds ability to autofill the graphic component images --- .../assetManagementModalAutofill.hbs | 1 + .../views/assetManagementModalAutofillView.js | 46 +++++++++++++++++++ .../views/assetManagementModalView.js | 8 ++++ frontend/src/core/modal/templates/modal.hbs | 22 +++++---- frontend/src/core/scaffold/scaffold.js | 1 - .../core/scaffold/views/scaffoldAssetView.js | 15 +++++- 6 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 frontend/src/core/assetManagement/templates/assetManagementModalAutofill.hbs create mode 100644 frontend/src/core/assetManagement/views/assetManagementModalAutofillView.js diff --git a/frontend/src/core/assetManagement/templates/assetManagementModalAutofill.hbs b/frontend/src/core/assetManagement/templates/assetManagementModalAutofill.hbs new file mode 100644 index 0000000000..74c682d94d --- /dev/null +++ b/frontend/src/core/assetManagement/templates/assetManagementModalAutofill.hbs @@ -0,0 +1 @@ +Autofill \ No newline at end of file diff --git a/frontend/src/core/assetManagement/views/assetManagementModalAutofillView.js b/frontend/src/core/assetManagement/views/assetManagementModalAutofillView.js new file mode 100644 index 0000000000..74fc2e011b --- /dev/null +++ b/frontend/src/core/assetManagement/views/assetManagementModalAutofillView.js @@ -0,0 +1,46 @@ +// LICENCE https://github.com/adaptlearning/adapt_authoring/blob/master/LICENSE +define(function(require) { + + var Origin = require('coreJS/app/origin'); + var Backbone = require('backbone'); + + var AssetManagementModalAutofillView = Backbone.View.extend({ + + className: 'asset-management-modal-autofill', + + tagName: 'button', + + events: { + 'click': 'onAutofillClicked' + }, + + initialize: function(options) { + this.options = options; + this.listenTo(Origin, 'modal:closed', this.remove); + this.listenTo(Origin, 'remove:views', this.remove); + this.render(); + }, + + render: function() { + var data = this.options; + var template = Handlebars.templates['assetManagementModalAutofill']; + this.$el.html(template(data)).prependTo('.model-popup-toolbar-buttons'); + _.defer(_.bind(this.postRender, this)); + + return this; + }, + + postRender: function() { + }, + + onAutofillClicked: function(event) { + event.preventDefault(); + this.options.modalView.data._shouldAutofill = true; + Origin.trigger('modal:onUpdate'); + } + + }); + + return AssetManagementModalAutofillView; + +}); diff --git a/frontend/src/core/assetManagement/views/assetManagementModalView.js b/frontend/src/core/assetManagement/views/assetManagementModalView.js index 60fb9dcd0e..95425ffbb5 100644 --- a/frontend/src/core/assetManagement/views/assetManagementModalView.js +++ b/frontend/src/core/assetManagement/views/assetManagementModalView.js @@ -8,6 +8,7 @@ define(function(require) { var AssetManagementPreviewView = require('coreJS/assetManagement/views/assetManagementPreviewView'); var AssetManagementView = require('coreJS/assetManagement/views/assetManagementView'); var AssetManagementModalFiltersView = require('coreJS/assetManagement/views/assetManagementModalFiltersView'); + var AssetManagementModelAutofillView = require('coreJS/assetManagement/views/assetManagementModalAutofillView'); var AssetManagementModalView = AssetManagementView.extend({ @@ -19,6 +20,9 @@ define(function(require) { postRender: function() { this.setupSubViews(); this.setupFilterAndSearchView(); + if (this.options.assetType === "Asset:image" && Origin.scaffold.getCurrentModel().get('_component') === 'graphic') { + this.setupImageAutofillButton(); + } this.resizeAssetPanels(); }, @@ -35,6 +39,10 @@ define(function(require) { new AssetManagementModalFiltersView(this.options); }, + setupImageAutofillButton: function() { + new AssetManagementModelAutofillView({modalView: this}); + }, + resizeAssetPanels: function() { var navigationHeight = $('.navigation').outerHeight(); var windowHeight = $(window).height(); diff --git a/frontend/src/core/modal/templates/modal.hbs b/frontend/src/core/modal/templates/modal.hbs index c92b3a2c83..13133726d6 100644 --- a/frontend/src/core/modal/templates/modal.hbs +++ b/frontend/src/core/modal/templates/modal.hbs @@ -5,16 +5,18 @@ {{/if}} - {{#if _shouldShowDoneButton}} - - {{/if}} - {{#if _shouldShowCancelButton}} - - {{/if}} +
+ {{#if _shouldShowDoneButton}} + + {{/if}} + {{#if _shouldShowCancelButton}} + + {{/if}} +