sync
[roojs1] / Roo / XComponent.js
index 4c5474a..bb6b7d8 100644 (file)
@@ -7,6 +7,9 @@
  * @class Roo.XComponent
  * A delayed Element creator...
  * Or a way to group chunks of interface together.
+ * technically this is a wrapper around a tree of Roo elements (which defines a 'module'),
+ *  used in conjunction with XComponent.build() it will create an instance of each element,
+ *  then call addxtype() to build the User interface.
  * 
  * Mypart.xyx = new Roo.XComponent({
 
  * It can be used to build a big heiracy, with parent etc.
  * or you can just use this to render a single compoent to a dom element
  * MYPART.render(Roo.Element | String(id) | dom_element )
+ *
+ *
+ * Usage patterns.
+ *
+ * Classic Roo
+ *
+ * Roo is designed primarily as a single page application, so the UI build for a standard interface will
+ * expect a single 'TOP' level module normally indicated by the 'parent' of the XComponent definition being defined as false.
+ *
+ * Each sub module is expected to have a parent pointing to the class name of it's parent module.
+ *
+ * When the top level is false, a 'Roo.BorderLayout' is created and the element is flagged as 'topModule'
+ * - if mulitple topModules exist, the last one is defined as the top module.
+ *
+ * Embeded Roo
+ * 
+ * When the top level or multiple modules are to embedded into a existing HTML page,
+ * the parent element can container '#id' of the element where the module will be drawn.
+ *
+ * Bootstrap Roo
+ *
+ * Unlike classic Roo, the bootstrap tends not to be used as a single page.
+ * it relies more on a include mechanism, where sub modules are included into an outer page.
+ * This is normally managed by the builder tools using Roo.apply( options, Included.Sub.Module )
+ * 
+ * Bootstrap Roo Included elements
+ *
+ * Our builder application needs the ability to preview these sub compoennts. They will normally have parent=false set,
+ * hence confusing the component builder as it thinks there are multiple top level elements. 
+ *
+ * 
  * 
  * @extends Roo.util.Observable
  * @constructor
@@ -130,21 +164,59 @@ Roo.extend(Roo.XComponent, Roo.util.Observable, {
         
         el = el || false;
         var hp = this.parent ? 1 : 0;
+        Roo.debug &&  Roo.log(this);
         
         if (!el && typeof(this.parent) == 'string' && this.parent.substring(0,1) == '#') {
             // if parent is a '#.....' string, then let's use that..
-            var ename = this.parent.substr(1)
-            this.parent = (this.parent == '#bootstrap') ? { el : true}  : false; // flags it as a top module...
-            el = Roo.get(ename);
+            var ename = this.parent.substr(1);
+            this.parent = false;
+            Roo.debug && Roo.log(ename);
+            switch (ename) {
+                case 'bootstrap-body' :
+                    if (typeof(Roo.bootstrap.Body) != 'undefined') {
+                        this.parent = { el :  new  Roo.bootstrap.Body() };
+                        Roo.debug && Roo.log("setting el to doc body");
+                         
+                    } else {
+                        throw "Container is bootstrap body, but Roo.bootstrap.Body is not defined";
+                    }
+                    break;
+                case 'bootstrap':
+                    this.parent = { el : true};
+                    // fall through
+                default:
+                    el = Roo.get(ename);
+                    break;
+            }
+                
+            
             if (!el && !this.parent) {
-                Roo.log("Warning - element can not be found :#" + ename );
+                Roo.debug && Roo.log("Warning - element can not be found :#" + ename );
                 return;
             }
         }
+        Roo.debug && Roo.log("EL:");
+        Roo.debug && Roo.log(el);
+        Roo.debug && Roo.log("this.parent.el:");
+        Roo.debug && Roo.log(this.parent.el);
         
+        var tree = this._tree ? this._tree() : this.tree();
+
+        // altertive root elements ??? - we need a better way to indicate these.
+        var is_alt = Roo.XComponent.is_alt || (typeof(Roo.bootstrap) != 'undefined' && tree.xns == Roo.bootstrap) ||
+                        (typeof(Roo.mailer) != 'undefined' && tree.xns == Roo.mailer) ;
+        
+        if (!this.parent && is_alt) {
+            //el = Roo.get(document.body);
+            this.parent = { el : true };
+        }
+            
+            
         
         if (!this.parent) {
             
+            Roo.debug && Roo.log("no parent - creating one");
+            
             el = el ? Roo.get(el) : false;     
             
             // it's a top level one..
@@ -162,34 +234,30 @@ Roo.extend(Roo.XComponent, Roo.util.Observable, {
                          minTabWidth: 140
                      }
                  })
-            }
+            };
         }
         
-               if (!this.parent.el) {
-                       // probably an old style ctor, which has been disabled.
-                       return;
-                       
-               }
+        if (!this.parent.el) {
+                // probably an old style ctor, which has been disabled.
+                return;
+
+        }
                // The 'tree' method is  '_tree now' 
             
-        var tree = this._tree ? this._tree() : this.tree();
         tree.region = tree.region || this.region;
-        
-        Roo.log('tree');
-        Roo.log(tree);
-        
+        var is_body = false;
         if (this.parent.el === true) {
             // bootstrap... - body..
             this.parent.el = Roo.factory(tree);
+            is_body = true;
         }
-        Roo.log('this.parent.el');
-        Roo.log(this.parent.el);
-        this.el = this.parent.el.addxtype(tree);
+        
+        this.el = this.parent.el.addxtype(tree, null, is_body);
         this.fireEvent('built', this);
         
         this.panel = this.el;
         this.layout = this.panel.layout;
-               this.parentLayout = this.parent.layout  || false;  
+        this.parentLayout = this.parent.layout  || false;  
          
     }
     
@@ -233,14 +301,21 @@ Roo.apply(Roo.XComponent, {
     elmodules : [],
 
      /**
+     * @property  is_alt
+     * Is an alternative Root - normally used by bootstrap or other systems,
+     *    where the top element in the tree can wrap 'body' 
+     * @type {boolean} true  (default false)
+     */
+     
+    is_alt : false,
+    /**
      * @property  build_from_html
      * Build elements from html - used by bootstrap HTML stuff 
      *    - this is cleared after build is completed
      * @type {boolean} true  (default false)
      */
      
-    elmodules : [],
-
+    build_from_html : false,
     /**
      * Register components to be built later.
      *
@@ -341,7 +416,7 @@ Roo.apply(Roo.XComponent, {
             try { 
                 obj.parent = this.toObject(opar);
             } catch(e) {
-                Roo.log("parent:toObject failed: " + e.toString());
+                Roo.debug && Roo.log("parent:toObject failed: " + e.toString());
                 return;
             }
             
@@ -360,7 +435,7 @@ Roo.apply(Roo.XComponent, {
                 return;
             }
             if (obj.parent.constructor != Roo.XComponent) {
-                Roo.log("Warning : Object Parent is not instance of XComponent:" + obj.name)
+                Roo.debug && Roo.log("Warning : Object Parent is not instance of XComponent:" + obj.name)
             }
             if (!obj.parent.modules) {
                 obj.parent.modules = new Roo.util.MixedCollection(false, 
@@ -484,6 +559,8 @@ Roo.apply(Roo.XComponent, {
                 if (!this.hideProgress && Roo.MessageBox) {
                     Roo.MessageBox.hide();
                 }
+                Roo.XComponent.build_from_html = false; // reset, so dialogs will be build from javascript
+                
                 Roo.XComponent.event.fireEvent('buildcomplete', _this.topModule);
                 
                 // THE END...