From ddc986f775e5eb2cf5bb30644ae7d934140805cb Mon Sep 17 00:00:00 2001 From: David Baumgold Date: Tue, 25 Jun 2013 11:25:29 -0400 Subject: [PATCH] Call event.preventDefault() on notification action buttons But allow you to specify that the event should not be prevented --- .../coffee/spec/views/feedback_spec.coffee | 39 +++++++++++++++++++ cms/static/js/views/feedback.js | 14 ++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/cms/static/coffee/spec/views/feedback_spec.coffee b/cms/static/coffee/spec/views/feedback_spec.coffee index e5916c5ed3..adec11e2a7 100644 --- a/cms/static/coffee/spec/views/feedback_spec.coffee +++ b/cms/static/coffee/spec/views/feedback_spec.coffee @@ -17,6 +17,16 @@ beforeEach -> return text.test(trimmedText) else return trimmedText.indexOf(text) != -1; + toHaveBeenPrevented: -> + # remove this when we upgrade jasmine-jquery + eventName = @actual.eventName + selector = @actual.selector + @message = -> + [ + "Expected event #{eventName} to have been prevented on #{selector}", + "Expected event #{eventName} not to have been prevented on #{selector}" + ] + return jasmine.JQuery.events.wasPrevented(selector, eventName) describe "CMS.Views.SystemFeedback", -> beforeEach -> @@ -123,6 +133,35 @@ describe "CMS.Views.SystemFeedback click events", -> it "should apply class to secondary action", -> expect(@view.$(".action-secondary")).toHaveClass("cancel-button") + it "should preventDefault on primary action", -> + spyOnEvent(".action-primary", "click") + @view.$(".action-primary").click() + expect("click").toHaveBeenPreventedOn(".action-primary") + + it "should preventDefault on secondary action", -> + spyOnEvent(".action-secondary", "click") + @view.$(".action-secondary").click() + expect("click").toHaveBeenPreventedOn(".action-secondary") + +describe "CMS.Views.SystemFeedback not preventing events", -> + beforeEach -> + @clickSpy = jasmine.createSpy('clickSpy') + @view = new CMS.Views.Alert.Confirmation( + title: "It's all good" + message: "No reason for this alert" + actions: + primary: + text: "Whatever" + click: @clickSpy + preventDefault: false + ) + @view.show() + + it "should not preventDefault", -> + spyOnEvent(".action-primary", "click") + @view.$(".action-primary").click() + expect("click").not.toHaveBeenPreventedOn(".action-primary") + expect(@clickSpy).toHaveBeenCalled() describe "CMS.Views.SystemFeedback multiple secondary actions", -> beforeEach -> diff --git a/cms/static/js/views/feedback.js b/cms/static/js/views/feedback.js index 3f161d5b1f..3bfeeb5af2 100644 --- a/cms/static/js/views/feedback.js +++ b/cms/static/js/views/feedback.js @@ -10,8 +10,12 @@ CMS.Views.SystemFeedback = Backbone.View.extend({ minShown: 0, // length of time after this view has been shown before it can be hidden (milliseconds) maxShown: Infinity // length of time after this view has been shown before it will be automatically hidden (milliseconds) - /* could also have an "actions" hash: here is an example demonstrating - the expected structure + /* Could also have an "actions" hash: here is an example demonstrating + the expected structure. For each action, by default the framework + will call preventDefault on the click event before the function is + run; to make it not do that, just pass `preventDefault: false` in + the action object. + actions: { primary: { "text": "Save", @@ -106,6 +110,9 @@ CMS.Views.SystemFeedback = Backbone.View.extend({ if(!actions) { return; } var primary = actions.primary; if(!primary) { return; } + if(primary.preventDefault !== false) { + event.preventDefault(); + } if(primary.click) { primary.click.call(event.target, this, event); } @@ -121,6 +128,9 @@ CMS.Views.SystemFeedback = Backbone.View.extend({ i = _.indexOf(this.$(".action-secondary"), event.target); } var secondary = secondaryList[i]; + if(secondary.preventDefault !== false) { + event.preventDefault(); + } if(secondary.click) { secondary.click.call(event.target, this, event); }