diff --git a/docs/templates/api_menu_version.template.html b/docs/templates/api_menu_version.template.html
index 70bf1fb81f..cd40e3756a 100644
--- a/docs/templates/api_menu_version.template.html
+++ b/docs/templates/api_menu_version.template.html
@@ -400,7 +400,7 @@
-
-
+
$ionicBackdrop
@@ -442,9 +442,21 @@
-
+
diff --git a/js/angular/directive/keyboardAttach.js b/js/angular/directive/keyboardAttach.js
new file mode 100644
index 0000000000..a9d5e42b9a
--- /dev/null
+++ b/js/angular/directive/keyboardAttach.js
@@ -0,0 +1,53 @@
+/**
+ * @ngdoc directive
+ * @name keyboardAttach
+ * @module ionic
+ * @restrict A
+ *
+ * @description
+ * keyboard-attach is an attribute directive which will cause an element to float above
+ * the keyboard when the keyboard shows. Currently only supports the [ion-footer-bar]({{ page.versionHref }}/api/directive/ionFooterBar/)
+ * directive.
+ *
+ * @usage
+ *
+ * ```html
+ *
+ * Title!
+ *
+ * ```
+ */
+
+IonicModule
+.directive('keyboardAttach', function() {
+ return function(scope, element, attrs) {
+ window.addEventListener('native.showkeyboard', onShow);
+ window.addEventListener('native.hidekeyboard', onHide);
+
+ var scrollCtrl;
+
+ function onShow(e) {
+ //for testing
+ var keyboardHeight = e.keyboardHeight || e.detail.keyboardHeight;
+ element.css('bottom', keyboardHeight);
+ scrollCtrl = element.controller('$ionicScroll');
+ if ( scrollCtrl ) {
+ scrollCtrl.scrollView.__container.style.bottom = keyboardHeight + keyboardAttachGetClientHeight(element[0]) + "px";
+ }
+ };
+
+ function onHide() {
+ element.css('bottom', '');
+ if ( scrollCtrl ) {
+ scrollCtrl.scrollView.__container.style.bottom = '';
+ }
+ };
+
+ scope.$on('$destroy', function() {
+ window.removeEventListener('native.showkeyboard', onShow);
+ window.removeEventListener('native.hidekeyboard', onHide);
+ });
+ };
+})
+
+function keyboardAttachGetClientHeight(element) { return element.clientHeight }
diff --git a/test/unit/angular/directive/keyboardAttach.unit.js b/test/unit/angular/directive/keyboardAttach.unit.js
new file mode 100644
index 0000000000..4a28e1e1f7
--- /dev/null
+++ b/test/unit/angular/directive/keyboardAttach.unit.js
@@ -0,0 +1,53 @@
+describe('keyboardAttach directive', function() {
+ beforeEach(module('ionic'));
+
+ function setup() {
+ var el, content;
+ inject(function($compile, $rootScope) {
+ el = angular.element('');
+ content = angular.element('');
+ content.append(el);
+ $compile(content)($rootScope.$new());
+ $rootScope.$apply();
+ });
+ return {el: el, content: content};
+ }
+
+ it('should move up when window fires native.showkeyboard event', function() {
+ var el = setup().el;
+ expect(el.css('bottom')).toEqual('');
+ ionic.trigger('native.showkeyboard', { target: window, keyboardHeight: 33 });
+ expect(el.css('bottom')).toEqual('33px');
+ el.scope().$destroy();
+ });
+
+ it('should move up when window fires native.showkeyboard event', function() {
+ var directives = setup();
+ var el = directives.el;
+ var content = directives.content;
+ var keyboardHeight = 33;
+ var elHeight = 50;
+
+ spyOn(window, 'keyboardAttachGetClientHeight').andReturn(elHeight);
+
+ expect(content.css('bottom')).toEqual('');
+ ionic.trigger('native.showkeyboard', { target: window, keyboardHeight: 33 });
+ expect(content.css('bottom')).toEqual(keyboardHeight + elHeight + 'px');
+ });
+
+ it('should remove listeners on destroy', function() {
+ spyOn(window, 'removeEventListener');
+ var el = setup().el;
+ el.scope().$destroy();
+ expect(window.removeEventListener).toHaveBeenCalledWith('native.showkeyboard', jasmine.any(Function));
+ expect(window.removeEventListener).toHaveBeenCalledWith('native.hidekeyboard', jasmine.any(Function));
+ });
+
+ it('should remove listeners on destroy', function() {
+ spyOn(window, 'removeEventListener');
+ var el = setup().el;
+ el.scope().$destroy();
+ expect(window.removeEventListener).toHaveBeenCalledWith('native.showkeyboard', jasmine.any(Function));
+ expect(window.removeEventListener).toHaveBeenCalledWith('native.hidekeyboard', jasmine.any(Function));
+ });
+})