From 0f5ce5b76e969aab74e0de00b9c04e9bc8e30445 Mon Sep 17 00:00:00 2001 From: Max Lynch Date: Mon, 16 Sep 2013 21:56:22 -0500 Subject: [PATCH] Basic NavController working with demo --- hacking/Button.js | 7 +++ hacking/NavBar.js | 36 ++++++++++++- hacking/NavController.js | 45 +++++++++++++++- hacking/NavController.unit.js | 42 +++++++++------ hacking/nav.html | 96 +++++++++++++++++++++++++++++++++++ 5 files changed, 208 insertions(+), 18 deletions(-) create mode 100644 hacking/Button.js create mode 100644 hacking/nav.html diff --git a/hacking/Button.js b/hacking/Button.js new file mode 100644 index 0000000000..33b46f20da --- /dev/null +++ b/hacking/Button.js @@ -0,0 +1,7 @@ +(function(window, document, ionic) { + ionic.Button = function(opts) { + this.el = opts.el; + }; + ionic.Button.prototype = { + } +})(this, document, ionic = this.ionic || {}); diff --git a/hacking/NavBar.js b/hacking/NavBar.js index f82ff447f2..2ca62e26a6 100644 --- a/hacking/NavBar.js +++ b/hacking/NavBar.js @@ -1,9 +1,43 @@ (function(window, document, ionic) { - NavBar = function() { + NavBar = function(opts) { + this.el = opts.el; + + this._titleEl = this.el.querySelector('.title'); }; NavBar.prototype = { + shouldGoBack: function() {}, + + setTitle: function(title) { + if(!this._titleEl) { + return; + } + this._titleEl.innerHTML = title; + }, + + showBackButton: function(shouldShow) { + var _this = this; + + if(!this._currentBackButton) { + var back = document.createElement('a'); + back.className = 'button back'; + back.innerHTML = 'Back'; + + this._currentBackButton = back; + this._currentBackButton.onclick = function(event) { + _this.shouldGoBack && _this.shouldGoBack(); + } + } + + if(shouldShow && !this._currentBackButton.parentNode) { + // Prepend the back button + this.el.insertBefore(this._currentBackButton, this.el.firstChild); + } else if(!shouldShow && this._currentBackButton.parentNode) { + // Remove the back button if it's there + this._currentBackButton.parentNode.removeChild(this._currentBackButton); + } + } }; })(this, document, ion = this.ionic || {}); diff --git a/hacking/NavController.js b/hacking/NavController.js index a0d005177c..e5cd730500 100644 --- a/hacking/NavController.js +++ b/hacking/NavController.js @@ -1,7 +1,16 @@ (function(window, document, ionic) { NavController = function(opts) { + var _this = this; + this.navBar = opts.navBar; + this.content = opts.content; this.controllers = opts.controllers || []; + + + // TODO: Is this the best way? + this.navBar.shouldGoBack = function() { + _this.pop(); + } }; NavController.prototype = { @@ -12,6 +21,8 @@ return this.topController; }, push: function(controller) { + var last = this.topController; + this.controllers.push(controller); // Indicate we are switching controllers @@ -23,27 +34,57 @@ // Actually switch the active controllers + // Remove the old one + last && last.detach(); + // Grab the top controller on the stack var next = this.controllers[this.controllers.length - 1]; + + this.content.el.appendChild(next.el); + // Switch to it (TODO: Animate or such things here) this.topController = next; + this._updateNavBar(); + return controller; }, - pop: function() { var next, last; + // Make sure we keep one on the stack at all times + if(this.controllers.length < 2) { + return; + } + // Grab the controller behind the top one on the stack last = this.controllers.pop(); + + // Remove the old one + last && last.detach(); next = this.controllers[this.controllers.length - 1]; + this.content.el.appendChild(next.el); + // Switch to it (TODO: Animate or such things here) this.topController = next; + this._updateNavBar(); + return last; - } + }, + + _updateNavBar: function() { + this.navBar.setTitle(this.topController.title); + + if(this.controllers.length > 1) { + this.navBar.showBackButton(true); + } else { + this.navBar.showBackButton(false); + } + }, + }; })(this, document, this.ionic || {}); diff --git a/hacking/NavController.unit.js b/hacking/NavController.unit.js index 6373c96fb0..0f8fdd2fb0 100644 --- a/hacking/NavController.unit.js +++ b/hacking/NavController.unit.js @@ -1,27 +1,41 @@ describe('NavController', function() { - var ctrl; + var ctrl, navBarEl, contentEl; + + var content = function(title) { + return { + el: document.createElement('div'), + title: title, + detach: function() { + this.el.parentNode && this.el.parentNode.removeChild(this.el); + }, + attach: function() { + } + } + } beforeEach(function() { + navBarEl = document.createElement('div'); + contentEl = document.createElement('div'); + ctrl = new NavController({ - navBar: new NavBar() + navBar: new NavBar({el: navBarEl }), + content: { el: contentEl } }); }); it('Should load controllers', function() { ctrl = new NavController({ + navBar: new NavBar({el: navBarEl }), + content: { el: contentEl }, controllers: [{}] }); expect(ctrl.getControllers().length).toEqual(1); }); it('Should push controller', function() { - ctrl.push({ - title: 'Page 1' - }); + ctrl.push(content('Page 1')); expect(ctrl.getControllers().length).toEqual(1); - ctrl.push({ - title: 'Page 2' - }); + ctrl.push(content('Page 2')); expect(ctrl.getControllers().length).toEqual(2); var last = ctrl.pop(); expect(ctrl.getControllers().length).toEqual(1); @@ -30,19 +44,17 @@ describe('NavController', function() { it('Should change top view controller', function() { expect(ctrl.getTopController()).toBe(undefined); - var c1 = { - title: 'Page 1' - }; - var c2 = { - title: 'Page 2' - }; + var c1 = content('Page 1'); + var c2 = content('Page 2'); ctrl.push(c1); expect(ctrl.getTopController()).toEqual(c1); ctrl.push(c2); expect(ctrl.getTopController()).toEqual(c2); ctrl.pop(); expect(ctrl.getTopController()).toEqual(c1); + + // Make sure we can't pop the first one off ctrl.pop(); - expect(ctrl.getTopController()).toEqual(undefined); + expect(ctrl.getTopController()).toEqual(c1); }); }); diff --git a/hacking/nav.html b/hacking/nav.html new file mode 100644 index 0000000000..a3dd32736d --- /dev/null +++ b/hacking/nav.html @@ -0,0 +1,96 @@ + + + + Nav Bars + + + + + + + + +
+ + + +
+
+
+ + + + + + + + +