Move display logic into view
Model shouldn't know about things like close buttons, visibility, and so on
This commit is contained in:
1
cms/static/coffee/fixtures/alert.underscore
Symbolic link
1
cms/static/coffee/fixtures/alert.underscore
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../templates/js/alert.underscore
|
||||
1
cms/static/coffee/fixtures/notification.underscore
Symbolic link
1
cms/static/coffee/fixtures/notification.underscore
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../templates/js/notification.underscore
|
||||
1
cms/static/coffee/fixtures/prompt.underscore
Symbolic link
1
cms/static/coffee/fixtures/prompt.underscore
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../templates/js/prompt.underscore
|
||||
@@ -1 +0,0 @@
|
||||
../../../templates/js/system-feedback.underscore
|
||||
@@ -11,18 +11,6 @@ describe "CMS.Models.SystemFeedback", ->
|
||||
it "should not have a type set by default", ->
|
||||
expect(@model.get("type")).toBeNull()
|
||||
|
||||
it "should be shown by default", ->
|
||||
expect(@model.get("shown")).toEqual(true)
|
||||
|
||||
it "should trigger a change event on calling .hide()", ->
|
||||
spy = jasmine.createSpy()
|
||||
@model.on("change", spy)
|
||||
|
||||
@model.hide()
|
||||
|
||||
expect(@model.get("shown")).toEqual(false)
|
||||
expect(spy).toHaveBeenCalled()
|
||||
|
||||
|
||||
describe "CMS.Models.WarningMessage", ->
|
||||
beforeEach ->
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
describe "CMS.Views.SystemFeedback", ->
|
||||
tpl = readFixtures('system-feedback.underscore')
|
||||
# CMS.Views.SystemFeedback looks for a template on the page when the code
|
||||
# is loaded, and even if we set that template on the page using a fixture,
|
||||
# CMS.Views.SystemFeedback has already been loaded, and so that template
|
||||
# won't be picked up. This is a dirty hack, to load that template into
|
||||
# the code after the code has been loaded already.
|
||||
CMS.Views.SystemFeedback.prototype.template = _.template(tpl)
|
||||
describe "CMS.Views.Alert as base class", ->
|
||||
tpl = readFixtures('alert.underscore')
|
||||
|
||||
beforeEach ->
|
||||
setFixtures(sandbox({id: "page-notification"}))
|
||||
setFixtures(sandbox({id: "page-alert"}))
|
||||
appendSetFixtures($("<script>", {id: "alert-tpl", type: "text/template"}).text(tpl))
|
||||
|
||||
@model = new CMS.Models.ConfirmationMessage({
|
||||
"title": "Portal"
|
||||
"message": "Welcome to the Aperture Science Computer-Aided Enrichment Center"
|
||||
close: true
|
||||
})
|
||||
# it will be interesting to see when this.render is called, so lets spy on it
|
||||
spyOn(CMS.Views.SystemFeedback.prototype, 'render').andCallThrough()
|
||||
spyOn(CMS.Views.Alert.prototype, 'render').andCallThrough()
|
||||
|
||||
it "renders on initalize", ->
|
||||
view = new CMS.Views.Notification({model: @model})
|
||||
view = new CMS.Views.Alert({model: @model})
|
||||
expect(view.render).toHaveBeenCalled()
|
||||
|
||||
it "renders the template", ->
|
||||
view = new CMS.Views.Notification({model: @model})
|
||||
view = new CMS.Views.Alert({model: @model})
|
||||
expect(view.$(".action-close")).toBeDefined()
|
||||
expect(view.$('.wrapper')).toHaveClass("is-shown")
|
||||
text = view.$el.text()
|
||||
@@ -31,26 +25,40 @@ describe "CMS.Views.SystemFeedback", ->
|
||||
expect(text).toMatch(/Aperture Science/)
|
||||
|
||||
it "close button sends a .hide() message", ->
|
||||
spyOn(CMS.Views.SystemFeedback.prototype, 'hide').andCallThrough()
|
||||
spyOn(CMS.Views.Alert.prototype, 'hide').andCallThrough()
|
||||
|
||||
view = new CMS.Views.Notification({model: @model})
|
||||
view = new CMS.Views.Alert({model: @model})
|
||||
view.$(".action-close").click()
|
||||
|
||||
expect(CMS.Views.SystemFeedback.prototype.hide).toHaveBeenCalled()
|
||||
expect(CMS.Views.Alert.prototype.hide).toHaveBeenCalled()
|
||||
expect(view.$('.wrapper')).not.toHaveClass("is-shown")
|
||||
expect(view.$('.wrapper')).toHaveClass("is-hiding")
|
||||
|
||||
describe "CMS.Views.Notification", ->
|
||||
tpl = readFixtures('notification.underscore')
|
||||
|
||||
beforeEach ->
|
||||
setFixtures(sandbox({id: "page-notification"}))
|
||||
appendSetFixtures($("<script>", {id: "notification-tpl", type: "text/template"}).text(tpl))
|
||||
|
||||
@model = new CMS.Models.ConfirmationMessage({
|
||||
"title": "Portal"
|
||||
"message": "Welcome to the Aperture Science Computer-Aided Enrichment Center"
|
||||
})
|
||||
|
||||
# for some reason, expect($("body")) blows up the test runner, so this test
|
||||
# just exercises the Prompt rather than asserting on anything. Best I can
|
||||
# do for now. :(
|
||||
it "prompt view changes class on body", ->
|
||||
it "changes class on body", ->
|
||||
# expect($("body")).not.toHaveClass("prompt-is-shown")
|
||||
view = new CMS.Views.Prompt({model: @model})
|
||||
# expect($("body")).toHaveClass("prompt-is-shown")
|
||||
@model.hide()
|
||||
view.hide()
|
||||
# expect($("body")).not.toHaveClass("prompt-is-shown")
|
||||
|
||||
describe "SystemFeedback click events", ->
|
||||
describe "CMS.Views.Alert click events", ->
|
||||
tpl = readFixtures('alert.underscore')
|
||||
|
||||
beforeEach ->
|
||||
@model = new CMS.Models.WarningMessage(
|
||||
title: "Unsaved",
|
||||
@@ -69,6 +77,7 @@ describe "SystemFeedback click events", ->
|
||||
)
|
||||
|
||||
setFixtures(sandbox({id: "page-alert"}))
|
||||
appendSetFixtures($("<script>", {id: "alert-tpl", type: "text/template"}).text(tpl))
|
||||
@view = new CMS.Views.Alert({model: @model})
|
||||
|
||||
it "should trigger the primary event on a primary click", ->
|
||||
|
||||
@@ -2,11 +2,7 @@ CMS.Models.SystemFeedback = Backbone.Model.extend({
|
||||
defaults: {
|
||||
"type": null, // "warning", "confirmation", "error", "announcement", "step-required", etc
|
||||
"title": "",
|
||||
"message": "",
|
||||
"shown": true,
|
||||
"close": false, // show a close button?
|
||||
"icon": true, // show an icon?
|
||||
"status": false // example: "saving" popup
|
||||
"message": ""
|
||||
/* could also have an "actions" hash: here is an example demonstrating
|
||||
the expected structure
|
||||
"actions": {
|
||||
@@ -31,12 +27,6 @@ CMS.Models.SystemFeedback = Backbone.Model.extend({
|
||||
]
|
||||
}
|
||||
*/
|
||||
},
|
||||
show: function() {
|
||||
this.set("shown", true);
|
||||
},
|
||||
hide: function() {
|
||||
this.set("shown", false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -25,18 +25,19 @@ CMS.Models.Section = Backbone.Model.extend({
|
||||
if(!this.msg) {
|
||||
this.msg = new CMS.Models.SystemFeedback({
|
||||
type: "saving",
|
||||
title: "Saving…",
|
||||
icon: true,
|
||||
status: true
|
||||
title: "Saving…"
|
||||
});
|
||||
}
|
||||
if(!this.msgView) {
|
||||
this.msgView = new CMS.Views.Notification({model: this.msg});
|
||||
this.msgView = new CMS.Views.Notification({
|
||||
model: this.msg,
|
||||
closeIcon: false
|
||||
});
|
||||
}
|
||||
this.msg.show();
|
||||
this.msgView.show();
|
||||
},
|
||||
hideNotification: function() {
|
||||
if(!this.msg) { return; }
|
||||
this.msg.hide();
|
||||
if(!this.msgView) { return; }
|
||||
this.msgView.hide();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
CMS.Views.SystemFeedback = Backbone.View.extend({
|
||||
CMS.Views.Alert = Backbone.View.extend({
|
||||
options: {
|
||||
type: "alert",
|
||||
shown: true, // is this view currently being shown?
|
||||
closeIcon: true // should we render a close button in the top right corner?
|
||||
},
|
||||
initialize: function() {
|
||||
this.setElement($("#page-"+this.type));
|
||||
this.template = _.template($("#"+this.options.type+"-tpl").text()),
|
||||
this.setElement($("#page-"+this.options.type));
|
||||
this.listenTo(this.model, 'change', this.render);
|
||||
return this.render();
|
||||
},
|
||||
template: _.template($("#system-feedback-tpl").text()),
|
||||
render: function() {
|
||||
var attrs = $.extend({}, this.model.attributes);
|
||||
if(attrs.type) {
|
||||
attrs.modelType = attrs.type;
|
||||
delete attrs.type;
|
||||
}
|
||||
attrs.viewType = this.type;
|
||||
var attrs = $.extend({}, this.options, this.model.attributes);
|
||||
this.$el.html(this.template(attrs));
|
||||
return this;
|
||||
},
|
||||
@@ -20,8 +20,13 @@ CMS.Views.SystemFeedback = Backbone.View.extend({
|
||||
"click .action-primary": "primaryClick",
|
||||
"click .action-secondary": "secondaryClick"
|
||||
},
|
||||
show: function() {
|
||||
this.options.shown = true;
|
||||
return this.render();
|
||||
},
|
||||
hide: function() {
|
||||
this.model.hide();
|
||||
this.options.shown = false;
|
||||
return this.render();
|
||||
},
|
||||
primaryClick: function() {
|
||||
var actions = this.model.get("actions");
|
||||
@@ -29,7 +34,7 @@ CMS.Views.SystemFeedback = Backbone.View.extend({
|
||||
var primary = actions.primary;
|
||||
if(!primary) { return; }
|
||||
if(primary.click) {
|
||||
primary.click.call(this.model);
|
||||
primary.click.call(this.model, this);
|
||||
}
|
||||
},
|
||||
secondaryClick: function(e) {
|
||||
@@ -46,19 +51,22 @@ CMS.Views.SystemFeedback = Backbone.View.extend({
|
||||
}
|
||||
var secondary = this.model.get("actions").secondary[i];
|
||||
if(secondary.click) {
|
||||
secondary.click.call(this.model);
|
||||
secondary.click.call(this.model, this);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CMS.Views.Alert = CMS.Views.SystemFeedback.extend({
|
||||
type: "alert"
|
||||
CMS.Views.Notification = CMS.Views.Alert.extend({
|
||||
options: $.extend({}, CMS.Views.Alert.prototype.options, {
|
||||
type: "notification",
|
||||
closeIcon: false
|
||||
})
|
||||
});
|
||||
CMS.Views.Notification = CMS.Views.SystemFeedback.extend({
|
||||
type: "notification"
|
||||
});
|
||||
CMS.Views.Prompt = CMS.Views.SystemFeedback.extend({
|
||||
type: "prompt",
|
||||
CMS.Views.Prompt = CMS.Views.Alert.extend({
|
||||
options: $.extend({}, CMS.Views.Alert.prototype.options, {
|
||||
type: "prompt",
|
||||
closeIcon: false
|
||||
}),
|
||||
render: function() {
|
||||
if(!window.$body) { window.$body = $(document.body); }
|
||||
if(this.model.get('shown')) {
|
||||
@@ -67,6 +75,6 @@ CMS.Views.Prompt = CMS.Views.SystemFeedback.extend({
|
||||
$body.removeClass('prompt-is-shown');
|
||||
}
|
||||
// super() in Javascript has awkward syntax :(
|
||||
return CMS.Views.SystemFeedback.prototype.render.apply(this, arguments);
|
||||
return CMS.Views.Alert.prototype.render.apply(this, arguments);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user