Skip to content

Commit

Permalink
feat(Alert): add a dismissed action (refs #45)
Browse files Browse the repository at this point in the history
  • Loading branch information
simonihmig committed Feb 6, 2016
1 parent 8ec2892 commit 760a2db
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 135 deletions.
255 changes: 132 additions & 123 deletions addon/components/bs-alert.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import TypeClass from 'ember-bootstrap/mixins/type-class';
```hbs
{{#bs-alert type="success"}}
<strong>Well done!</strong> You successfully read this important alert message.
<strong>Well done!</strong> You successfully read this important alert message.
{{/bs-alert}}
```
Expand All @@ -20,131 +20,140 @@ import TypeClass from 'ember-bootstrap/mixins/type-class';
@uses Mixins.TypeClass
*/
export default Ember.Component.extend(TypeClass, {
classNameBindings: ['alert','fade','in'],

/**
* A dismissible alert will have a close button in the upper right corner, that the user can click to dismiss
* the alert.
*
* @property dismissible
* @type boolean
* @default true
* @public
*/
dismissible: true,

/**
* If true the alert is completely hidden. Will be set when the fade animation has finished.
*
* @property dismissed
* @type boolean
* @default false
* @readonly
* @protected
*/
dismissed: false,

/**
* This property indicates if the alert is visible. If false it might still be in the DOM until the fade animation
* has completed. Can be set to change the visibility of the alert box.
*
* @property visible
* @type boolean
* @default true
* @public
*/
visible: true,

/**
* Set to false to disable the fade out animation when hiding the alert.
*
* @property fade
* @type boolean
* @default true
* @public
*/
fade: true,

/**
* Computed property to set the alert class to the component div. Will be false when dismissed to have the component
* div (which cannot be removed form DOM by the component itself) without any markup.
*
* @property alert
* @type boolean
* @private
*/
alert: Ember.computed.not('dismissed'),
in: Ember.computed.and('visible','fade'),

/**
* @property classTypePrefix
* @type String
* @default 'alert'
* @protected
*/
classTypePrefix: 'alert',

/**
* The duration of the fade out animation
*
* @property fadeDuration
* @type integer
* @default 150
* @public
*/
fadeDuration: 150,

actions: {
dismiss: function() {
this.hide();
}
},
classNameBindings: ['alert', 'fade', 'in'],

/**
* A dismissible alert will have a close button in the upper right corner, that the user can click to dismiss
* the alert.
*
* @property dismissible
* @type boolean
* @default true
* @public
*/
dismissible: true,

/**
* If true the alert is completely hidden. Will be set when the fade animation has finished.
*
* @property dismissed
* @type boolean
* @default false
* @readonly
* @protected
*/
dismissed: false,

/**
* This property controls if the alert should be visible. If false it might still be in the DOM until the fade animation
* has completed.
*
* @property visible
* @type boolean
* @default true
* @public
*/
visible: true,

/**
* Set to false to disable the fade out animation when hiding the alert.
*
* @property fade
* @type boolean
* @default true
* @public
*/
fade: true,

/**
* Computed property to set the alert class to the component div. Will be false when dismissed to have the component
* div (which cannot be removed form DOM by the component itself) without any markup.
*
* @property alert
* @type boolean
* @private
*/
alert: Ember.computed.not('dismissed'),
in: Ember.computed.and('visible', 'fade'),

/**
* @property classTypePrefix
* @type String
* @default 'alert'
* @protected
*/
classTypePrefix: 'alert',

/**
* The duration of the fade out animation
*
* @property fadeDuration
* @type integer
* @default 150
* @public
*/
fadeDuration: 150,

/**
* The action to be sent after the alert has been dismissed (including the CSS transition).
*
* @property dismissedAction
* @type string
* @default null
* @public
*/
dismissedAction: null,

actions: {
dismiss: function () {
this.hide();
}
},

_onVisibleChange: Ember.observer('visible', function() {
if (this.get('visible')) {
this.show();
}
else {
this.hide();
}
}),

/**
* Call to make the alert visible again after it has been hidden
*
* @method show
* @public
*/
show: function() {
this.setProperties({
dismissed: false,
visible: true
});
},

/**
* Call to hide the alert. If the `fade` property is true, this will fade out the alert before being finally
* dismissed.
*
* @method hide
* @public
*/
hide: function() {
if (this.get('fade')) {
this.set('visible', false);
Ember.run.later(this,function() {
if (!this.get('isDestroyed')) {
this.set('dismissed', true);
}
},this.get('fadeDuration'));
}
else {
this.setProperties({
dismissed: true,
visible: false
});
_onVisibleChange: Ember.observer('visible', function () {
if (this.get('visible')) {
this.show();
}
else {
this.hide();
}
}),

/**
* Call to make the alert visible again after it has been hidden
*
* @method show
* @public
*/
show: function () {
this.setProperties({
dismissed: false
});
},

/**
* Call to hide the alert. If the `fade` property is true, this will fade out the alert before being finally
* dismissed.
*
* @method hide
* @public
*/
hide: function () {
if (this.get('fade')) {
Ember.run.later(this, function () {
if (!this.get('isDestroyed')) {
this.set('dismissed', true);
this.sendAction('dismissedAction');
}
}, this.get('fadeDuration'));
}
else {
this.setProperties({
dismissed: true
});
this.sendAction('dismissedAction');
}
}


});
11 changes: 11 additions & 0 deletions tests/dummy/app/controllers/alert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Ember from 'ember';

export default Ember.Controller.extend({
visible: false,

actions: {
close() {
this.set('visible', false);
}
}
});
2 changes: 1 addition & 1 deletion tests/dummy/app/templates/alert.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
<h2>Bound visibility</h2>

<label>{{input type="checkbox" checked=visible}} Show/Hide</label>
{{#bs-alert type="danger" visible=visible}}<strong>Oh snap!</strong> Change a few things up and try submitting again.{{/bs-alert}}
{{#bs-alert type="danger" visible=visible dismissedAction=(action "close")}}<strong>Oh snap!</strong> Change a few things up and try submitting again.{{/bs-alert}}

43 changes: 32 additions & 11 deletions tests/integration/components/bs-alert-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,45 @@ import hbs from 'htmlbars-inline-precompile';


moduleForComponent('bs-alert', 'Integration | Component | bs-alert', {
integration: true
integration: true
});

test('alert has correct CSS classes', function(assert) {
this.render(hbs`{{#bs-alert type="success"}}Test{{/bs-alert}}`);
test('alert has correct CSS classes', function (assert) {
this.render(hbs`{{#bs-alert type="success"}}Test{{/bs-alert}}`);

assert.equal(this.$(':first-child').hasClass('alert'),true, 'alert has alert class');
assert.equal(this.$(':first-child').hasClass('alert-success'),true, 'alert has type class');
assert.equal(this.$(':first-child').hasClass('alert'), true, 'alert has alert class');
assert.equal(this.$(':first-child').hasClass('alert-success'), true, 'alert has type class');
});

test('dismissible alert can be hidden by clicking close button', function(assert) {
this.render(hbs`{{#bs-alert type="success" fade=false}}Test{{/bs-alert}}`);
test('dismissible alert can be hidden by clicking close button', function (assert) {
this.render(hbs`{{#bs-alert type="success" fade=false}}Test{{/bs-alert}}`);

assert.equal(this.$().find('button.close').length,1, 'alert has close button');
this.$().find('button.close').click();
assert.equal(this.$().find('button.close').length, 1, 'alert has close button');
this.$().find('button.close').click();

assert.equal(this.$(':first-child').hasClass('alert'),false, 'alert has no alert class');
assert.equal(this.$(':first-child').text().trim(),'', 'alert has no content');
assert.equal(this.$(':first-child').hasClass('alert'), false, 'alert has no alert class');
assert.equal(this.$(':first-child').text().trim(), '', 'alert has no content');

});

test('alert can be hidden by setting visible property', function (assert) {
this.set('visible', true);
this.render(hbs`{{#bs-alert type="success" fade=false visible=visible}}Test{{/bs-alert}}`);

this.set('visible', false);

assert.equal(this.$(':first-child').hasClass('alert'), false, 'alert has no alert class');
assert.equal(this.$(':first-child').text().trim(), '', 'alert has no content');

});

test('dismissedAction is called after modal is closed', function (assert) {
assert.expect(1);

this.on('testAction', () => {
assert.ok(true, 'Action has been called.');
});
this.render(hbs`{{#bs-alert type="success" fade=false dismissedAction=(action "testAction")}}Test{{/bs-alert}}`);

this.$().find('button.close').click();
});

0 comments on commit 760a2db

Please sign in to comment.