1 // ========================================================================== 2 // Project: The M-Project - Mobile HTML5 Application Framework 3 // Copyright: (c) 2010 M-Way Solutions GmbH. All rights reserved. 4 // (c) 2011 panacoda GmbH. All rights reserved. 5 // Creator: Dominik 6 // Date: 09.11.2010 7 // License: Dual licensed under the MIT or GPL Version 2 licenses. 8 // http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE 9 // http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE 10 // ========================================================================== 11 12 /** 13 * @class 14 * 15 * M.ToggleView defines the prototype of any toggle view. A toggle view accepts exactly 16 * two child views and provides an easy mechanism to toggle between these two views. An 17 * easy example would be to define two different button views that can be toggled, a more 18 * complex scenario would be to define two content views (M.ScrollView) with own child views 19 * and toggle between them. 20 * 21 * @extends M.View 22 */ 23 M.ToggleView = M.View.extend( 24 /** @scope M.ToggleView.prototype */ { 25 26 /** 27 * The type of this object. 28 * 29 * @type String 30 */ 31 type: 'M.ToggleView', 32 33 /** 34 * States whether the toggle view currently displays its first child view or its second 35 * child view. 36 * 37 * @type Boolean 38 */ 39 isInFirstState: YES, 40 41 /** 42 * Determines whether to toggle the view on click. This might be useful if the child views 43 * are e.g. buttons. 44 * 45 * @type Boolean 46 */ 47 toggleOnClick: NO, 48 49 /** 50 * Contains a reference to the currently displayed view. 51 * 52 * @type M.View 53 */ 54 currentView: null, 55 56 /** 57 * Renders a ToggleView and its child views. 58 * 59 * @private 60 * @returns {String} The toggle view's html representation. 61 */ 62 render: function() { 63 this.html += '<div id="' + this.id + '">'; 64 65 this.renderChildViews(); 66 67 this.html += '</div>'; 68 69 return this.html; 70 }, 71 72 /** 73 * This method renders one child view of the toggle view, based on the isInFirstState 74 * property: YES = first child view, NO = second child view. 75 */ 76 renderChildViews: function() { 77 if(this.childViews) { 78 var childViews = this.getChildViewsAsArray(); 79 80 if(childViews.length !== 2) { 81 M.Logger.log('M.ToggleView requires exactly 2 child views, but ' + childViews.length + ' are given (' + (this.name ? this.name + ', ' : '') + this.id + ')!', M.WARN); 82 } else { 83 for(var i in childViews) { 84 if(this[childViews[i]]) { 85 if(this.toggleOnClick) { 86 this[childViews[i]].internalEvents = { 87 tap: { 88 target: this, 89 action: 'toggleView' 90 } 91 } 92 } 93 this[childViews[i]]._name = childViews[i]; 94 this[childViews[i]].parentView = this; 95 96 this.html += '<div id="' + this.id + '_' + i + '">'; 97 this.html += this[childViews[i]].render(); 98 this.html += '</div>'; 99 } 100 } 101 this.currentView = this[childViews[0]]; 102 } 103 } 104 }, 105 106 /** 107 * This method toggles the child views by first emptying the toggle view's content 108 * and then rendering the next child view by calling renderUpdateChildViews(). 109 */ 110 toggleView: function(id, event, nextEvent) { 111 this.isInFirstState = !this.isInFirstState; 112 var currentViewIndex = this.isInFirstState ? 0 : 1; 113 $('#' + this.id + '_' + currentViewIndex).show(); 114 $('#' + this.id + '_' + (currentViewIndex > 0 ? 0 : 1)).hide(); 115 116 /* set current view */ 117 var childViews = this.getChildViewsAsArray(); 118 if(this[childViews[currentViewIndex]]) { 119 this.currentView = this[childViews[currentViewIndex]]; 120 } 121 122 /* call jqm to fix header/footer */ 123 $.mobile.fixedToolbars.show(); 124 125 if(nextEvent) { 126 M.EventDispatcher.callHandler(nextEvent, event, YES); 127 } 128 }, 129 130 /** 131 * This method can be used to set on of the toggle view's child views as the active one. Simply pass 132 * the view, its id or its name. 133 * 134 * If a view or id is passed, that does not match on of the toggle view's child views, nothing will be 135 * done. 136 * 137 * @param {Object|String} view The corresponding view. 138 */ 139 setView: function(view) { 140 if(typeof(view) === 'string') { 141 /* assume a name was given */ 142 var childViews = this.getChildViewsAsArray(); 143 if(_.indexOf(childViews, view) >= 0) { 144 view = this[view]; 145 /* assume an id was given */ 146 } else { 147 view = M.ViewManager.getViewById(view) ? M.ViewManager.getViewById(view) : view; 148 } 149 } 150 151 if(view && typeof(view) === 'object' && view.parentView === this) { 152 if(this.currentView !== view) { 153 this.toggleView(); 154 } 155 } else { 156 M.Logger.log('No valid view passed for toggle view \'' + this._name + '\'.', M.WARN); 157 } 158 }, 159 160 /** 161 * Triggers the rendering engine, jQuery mobile, to style the toggle view respectively 162 * its child views. 163 * 164 * @private 165 */ 166 theme: function() { 167 if(this.currentView) { 168 this.themeChildViews(); 169 var currentViewIndex = this.isInFirstState ? 0 : 1; 170 171 $('#' + this.id + '_' + (currentViewIndex > 0 ? 0 : 1)).hide(); 172 } 173 } 174 175 });