From e4aa4e546c8906b918faa98a093c8cda9976d449 Mon Sep 17 00:00:00 2001 From: Rufus Pollock Date: Thu, 26 Apr 2012 22:45:28 +0100 Subject: [PATCH] [#82,flash/notify,refactor][m]: convert notify / flash messages to use events rather than call to a central function. --- src/view-grid.js | 18 ++++-- src/view-map.js | 5 +- src/view-transform-dialog.js | 6 +- src/view.js | 104 +++++++++++++++++++---------------- 4 files changed, 76 insertions(+), 57 deletions(-) diff --git a/src/view-grid.js b/src/view-grid.js index 8660fb5a..30e81a33 100644 --- a/src/view-grid.js +++ b/src/view-grid.js @@ -74,6 +74,7 @@ my.Grid = Backbone.View.extend({ hideColumn: function() { self.hideColumn(); }, showColumn: function() { self.showColumn(e); }, deleteRow: function() { + var self = this; var doc = _.find(self.model.currentDocuments.models, function(doc) { // important this is == as the currentRow will be string (as comes // from DOM) while id may be int @@ -81,9 +82,9 @@ my.Grid = Backbone.View.extend({ }); doc.destroy().then(function() { self.model.currentDocuments.remove(doc); - my.notify("Row deleted successfully"); + self.trigger('recline:flash', {message: "Row deleted successfully"}); }).fail(function(err) { - my.notify("Errorz! " + err); + self.trigger('recline:flash', {message: "Errorz! " + err}); }); } }; @@ -91,9 +92,14 @@ my.Grid = Backbone.View.extend({ }, showTransformColumnDialog: function() { + var self = this; var view = new my.ColumnTransform({ model: this.model }); + // pass the flash message up the chain + view.bind('recline:flash', function(flash) { + self.trigger('recline:flash', flash); + }); view.state = this.tempState; view.render(); this.el.append(view.el); @@ -286,6 +292,7 @@ my.GridRow = Backbone.View.extend({ }, onEditorOK: function(e) { + var self = this; var cell = $(e.target); var rowId = cell.parents('tr').attr('data-id'); var field = cell.parents('td').attr('data-field'); @@ -293,12 +300,13 @@ my.GridRow = Backbone.View.extend({ var newData = {}; newData[field] = newValue; this.model.set(newData); - my.notify("Updating row...", {loader: true}); + this.trigger('recline:flash', {message: "Updating row...", loader: true}); this.model.save().then(function(response) { - my.notify("Row updated successfully", {category: 'success'}); + this.trigger('recline:flash', {message: "Row updated successfully", category: 'success'}); }) .fail(function() { - my.notify('Error saving row', { + this.trigger('recline:flash', { + message: 'Error saving row', category: 'error', persist: true }); diff --git a/src/view-map.js b/src/view-map.js index 97d49499..5b2f3433 100644 --- a/src/view-map.js +++ b/src/view-map.js @@ -281,7 +281,6 @@ my.Map = Backbone.View.extend({ // Each feature will have a popup associated with all the document fields. // _add: function(docs){ - var self = this; if (!(docs instanceof Array)) docs = [docs]; @@ -316,13 +315,13 @@ my.Map = Backbone.View.extend({ var msg = 'Wrong geometry value'; if (except.message) msg += ' (' + except.message + ')'; if (wrongSoFar <= 10) { - my.notify(msg,{category:'error'}); + self.trigger('recline:flash', {message: msg, category:'error'}); } } } else { wrongSoFar += 1 if (wrongSoFar <= 10) { - my.notify('Wrong geometry value',{category:'error'}); + self.trigger('recline:flash', {message: 'Wrong geometry value', category:'error'}); } } return true; diff --git a/src/view-transform-dialog.js b/src/view-transform-dialog.js index 83ab53a8..6c69766b 100644 --- a/src/view-transform-dialog.js +++ b/src/view-transform-dialog.js @@ -93,11 +93,11 @@ my.ColumnTransform = Backbone.View.extend({ var funcText = this.el.find('.expression-preview-code').val(); var editFunc = costco.evalFunction(funcText); if (editFunc.errorMessage) { - my.notify("Error with function! " + editFunc.errorMessage); + this.trigger('recline:flash', {message: "Error with function! " + editFunc.errorMessage}); return; } this.el.modal('hide'); - my.notify("Updating all visible docs. This could take a while...", {persist: true, loader: true}); + this.trigger('recline:flash', {message: "Updating all visible docs. This could take a while...", persist: true, loader: true}); var docs = self.model.currentDocuments.map(function(doc) { return doc.toJSON(); }); @@ -107,7 +107,7 @@ my.ColumnTransform = Backbone.View.extend({ function onCompletedUpdate() { totalToUpdate += -1; if (totalToUpdate === 0) { - my.notify(toUpdate.length + " documents updated successfully"); + self.trigger('recline:flash', {message: toUpdate.length + " documents updated successfully"}); alert('WARNING: We have only updated the docs in this view. (Updating of all docs not yet implemented!)'); self.remove(); } diff --git a/src/view.js b/src/view.js index ee6a5135..ac4a2f28 100644 --- a/src/view.js +++ b/src/view.js @@ -209,6 +209,7 @@ my.DataExplorer = Backbone.View.extend({ // these must be called after pageViews are created this.render(); this._bindStateChanges(); + this._bindFlashNotifications(); // now do updates based on state (need to come after render) if (this.state.get('readOnly')) { this.setReadOnly(); @@ -220,15 +221,15 @@ my.DataExplorer = Backbone.View.extend({ } this.model.bind('query:start', function() { - my.notify('Loading data', {loader: true}); + self.notify({message: 'Loading data', loader: true}); }); this.model.bind('query:done', function() { - my.clearNotifications(); + self.clearNotifications(); self.el.find('.doc-count').text(self.model.docCount || 'Unknown'); - my.notify('Data loaded', {category: 'success'}); + self.notify({message: 'Data loaded', category: 'success'}); }); this.model.bind('query:fail', function(error) { - my.clearNotifications(); + self.clearNotifications(); var msg = ''; if (typeof(error) == 'string') { msg = error; @@ -242,7 +243,7 @@ my.DataExplorer = Backbone.View.extend({ } else { msg = 'There was an error querying the backend'; } - my.notify(msg, {category: 'error', persist: true}); + self.notify({message: msg, category: 'error', persist: true}); }); // retrieve basic data like fields etc @@ -252,7 +253,7 @@ my.DataExplorer = Backbone.View.extend({ self.model.query(self.state.get('query')); }) .fail(function(error) { - my.notify(error.message, {category: 'error', persist: true}); + self.notify({message: error.message, category: 'error', persist: true}); }); }, @@ -368,6 +369,57 @@ my.DataExplorer = Backbone.View.extend({ }); } }); + }, + + _bindFlashNotifications: function() { + var self = this; + _.each(this.pageViews, function(pageView) { + pageView.view.bind('recline:flash', function(flash) { + self.notify(flash); + }); + }); + }, + + // ### notify + // + // Create a notification (a div.alert in div.alert-messsages) using provided + // flash object. Flash attributes (all are optional): + // + // * message: message to show. + // * category: warning (default), success, error + // * persist: if true alert is persistent, o/w hidden after 3s (default = false) + // * loader: if true show loading spinner + notify: function(flash) { + var tmplData = _.extend({ + message: '', + category: 'warning' + }, + flash + ); + var _template = ' \ +
× \ + {{message}} \ + {{#loader}} \ +   \ + {{/loader}} \ +
'; + var _templated = $.mustache(_template, tmplData); + _templated = $(_templated).appendTo($('.recline-data-explorer .alert-messages')); + if (!flash.persist) { + setTimeout(function() { + $(_templated).fadeOut(1000, function() { + $(this).remove(); + }); + }, 1000); + } + }, + + // ### clearNotifications + // + // Clear all existing notifications + clearNotifications: function() { + var $notifications = $('.recline-data-explorer .alert-messages .alert'); + $notifications.remove(); } }); @@ -609,45 +661,5 @@ my.FacetViewer = Backbone.View.extend({ }); -// ## notify -// -// Create a notification (a div.alert in div.alert-messsages) using provide messages and options. Options are: -// -// * category: warning (default), success, error -// * persist: if true alert is persistent, o/w hidden after 3s (default = false) -// * loader: if true show loading spinner -my.notify = function(message, options) { - if (!options) options = {}; - var tmplData = _.extend({ - msg: message, - category: 'warning' - }, - options); - var _template = ' \ -
× \ - {{msg}} \ - {{#loader}} \ -   \ - {{/loader}} \ -
'; - var _templated = $.mustache(_template, tmplData); - _templated = $(_templated).appendTo($('.recline-data-explorer .alert-messages')); - if (!options.persist) { - setTimeout(function() { - $(_templated).fadeOut(1000, function() { - $(this).remove(); - }); - }, 1000); - } -}; - -// ## clearNotifications -// -// Clear all existing notifications -my.clearNotifications = function() { - var $notifications = $('.recline-data-explorer .alert-messages .alert'); - $notifications.remove(); -}; - })(jQuery, recline.View);