From 91737f73f5cb4b0877848f9932de7ebe1a4a15a3 Mon Sep 17 00:00:00 2001 From: thriqon Date: Wed, 22 Apr 2015 10:40:35 +0200 Subject: [PATCH 1/2] Providing feedback and a place to click --- tests/dummy/app/controllers/application.js | 12 ++++++++++++ tests/dummy/app/templates/application.hbs | 5 ++++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 tests/dummy/app/controllers/application.js diff --git a/tests/dummy/app/controllers/application.js b/tests/dummy/app/controllers/application.js new file mode 100644 index 0000000..3108fe2 --- /dev/null +++ b/tests/dummy/app/controllers/application.js @@ -0,0 +1,12 @@ + +import Ember from 'ember'; + +/* global alert */ + +export default Ember.Controller.extend({ + actions: { + boom: function () { + alert('BOOM'); + } + } +}); diff --git a/tests/dummy/app/templates/application.hbs b/tests/dummy/app/templates/application.hbs index 9090c85..3b07067 100644 --- a/tests/dummy/app/templates/application.hbs +++ b/tests/dummy/app/templates/application.hbs @@ -1,3 +1,6 @@ -{{#confirm-extension questionText='really?' confirmText='yes' declineText='no'}} + +

Central Command

+ +{{#confirm-extension questionText='really?' confirmText='yes' declineText='no' confirmAction='boom'}} {{/confirm-extension}} From 0d70dbb5fc368c2212fb9cd3dabace03a26ddd9d Mon Sep 17 00:00:00 2001 From: thriqon Date: Wed, 22 Apr 2015 10:54:48 +0200 Subject: [PATCH 2/2] Clicking anywhere outside the component closes the extension An event listener on document is registered when the component opens, and closes the extension when fired. --- addon/components/confirm-extension.js | 44 ++++++++++++++++++- .../unit/components/confirm-extension-test.js | 28 +++++++++++- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/addon/components/confirm-extension.js b/addon/components/confirm-extension.js index 35ff80d..aa3b3b1 100644 --- a/addon/components/confirm-extension.js +++ b/addon/components/confirm-extension.js @@ -1,12 +1,42 @@ import Ember from 'ember'; import layout from '../templates/components/confirm-extension'; +/* global $ */ + export default Ember.Component.extend({ layout: layout, + _setupClickHandler: function () { + var closer = _clickHandlerFor(this); + this.set('_closer', closer); + $(document).on('click', closer); + }, + _teardownClickHandlerIfNeeded: function () { + var closer = this.get('_closer'); + if (closer) { + $(document).off('click', closer); + this.set('_closer', null); + } + }, + _autoCloser: Ember.observer('confirmMode', function () { + if (this.get('confirmMode')) { + this._setupClickHandler(); + } else { + this._teardownClickHandlerIfNeeded(); + } + }), + _beforeRemove: Ember.on('willDestroyElement', function () { + this._teardownClickHandlerIfNeeded(); + }), + _afterInsert: Ember.on('didInsertElement', function () { + if (this.get('confirmMode')) { + this._setupClickHandler(); + } + }), + actions: { click: function() { - this.set('confirmMode', !this.get('confirmMode')); + this.toggleProperty('confirmMode'); }, confirm: function() { this.set('confirmMode', false); @@ -17,3 +47,15 @@ export default Ember.Component.extend({ } } }); + +function _contains(ancestor, child) { + return ancestor.has(child).length !== 0; +} + +function _clickHandlerFor(self) { + return function (e) { + if (!_contains(self.$(), e.target)) { + Ember.run(self, 'set', 'confirmMode', false); + } + }; +} diff --git a/tests/unit/components/confirm-extension-test.js b/tests/unit/components/confirm-extension-test.js index dcb1e28..af3fad3 100644 --- a/tests/unit/components/confirm-extension-test.js +++ b/tests/unit/components/confirm-extension-test.js @@ -47,7 +47,7 @@ test('click on the yielded template leaves the confirm mode and hides the bubble var $component = this.render(); assert.equal($component.find('.ece-bubble').length, 1); - $component.find('span')[0].click(); + $component.find('span').click(); assert.equal(component.get('confirmMode'), false); assert.equal($component.find('.ece-bubble').length, 0); }); @@ -72,3 +72,29 @@ test('click on confirm triggers the confirmAction, leaves confirmMode and hides assert.equal(component.get('confirmMode'), false); assert.equal($component.find('.ece-bubble').length, 0); }); + +test('click on should leave confirmMode when initially open', function (assert) { + assert.expect(2); + var component = this.subject({ + confirmMode: true + }); + + var $component = this.render(); + assert.ok(component.get('confirmMode'), 'should be in confirm mode'); + $('body').click(); + assert.ok(!component.get('confirmMode'), 'should not be in confirm mode'); +}); + +test('click on should leave confirmMode when opened after render', function (assert) { + assert.expect(2); + var component = this.subject({ + confirmMode: false + }); + + var $component = this.render(); + Ember.run(component, 'set', 'confirmMode', true); + + assert.ok(component.get('confirmMode'), 'should be in confirm mode'); + $('body').click(); + assert.ok(!component.get('confirmMode'), 'should not be in confirm mode'); +});