docs/default.css
[roojs1] / roojs-bootstrap-debug.js
index c9aced8..a34e540 100644 (file)
@@ -770,10 +770,10 @@ Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component,  {
  * @class Roo.bootstrap.Column
  * @extends Roo.bootstrap.Component
  * Bootstrap Column class
- * @cfg {Number} xs colspan out of 12 for mobile-sized screens
- * @cfg {Number} sm colspan out of 12 for tablet-sized screens
- * @cfg {Number} md colspan out of 12 for computer-sized screens
- * @cfg {Number} lg colspan out of 12 for large computer-sized screens
+ * @cfg {Number} xs colspan out of 12 for mobile-sized screens or 0 for hidden
+ * @cfg {Number} sm colspan out of 12 for tablet-sized screens or 0 for hidden
+ * @cfg {Number} md colspan out of 12 for computer-sized screens or 0 for hidden
+ * @cfg {Number} lg colspan out of 12 for large computer-sized screens or 0 for hidden
  * @cfg {String} html content of column.
  * 
  * @constructor
@@ -787,10 +787,10 @@ Roo.bootstrap.Column = function(config){
 
 Roo.extend(Roo.bootstrap.Column, Roo.bootstrap.Component,  {
     
-    xs: null,
-    sm: null,
-    md: null,
-    lg: null,
+    xs: false,
+    sm: false,
+    md: false,
+    lg: false,
     html: '',
     offset: 0,
     
@@ -804,7 +804,11 @@ Roo.extend(Roo.bootstrap.Column, Roo.bootstrap.Component,  {
         
         var settings=this;
         ['xs','sm','md','lg'].map(function(size){
-            if (settings[size]) {
+            if (settings[size] !== false) {
+                if (!settings[size]) { // 0 = hidden
+                    cfg.cls += ' hidden-' + size;
+                    return;
+                }
                 cfg.cls += ' col-' + size + '-' + settings[size];
             }
         });
@@ -1157,7 +1161,7 @@ Roo.extend(Roo.bootstrap.Link, Roo.bootstrap.Component,  {
     
     initEvents: function() {
         
-        if(!this.href){
+        if(!this.href || this.preventDefault){
             this.el.on('click', this.onClick, this);
         }
     },
@@ -2999,6 +3003,8 @@ Roo.extend(Roo.bootstrap.NavSimplebar, Roo.bootstrap.Navbar,  {
  * @cfg {String} brand what is brand
  * @cfg {String} position (fixed-top|fixed-bottom|static-top) position
  * @cfg {String} brand_href href of the brand
+ * @cfg {Boolean} srButton generate the sr-only button (true | false) default true
+ * @cfg {Boolean} autohide a top nav bar header that hides on scroll.
  * 
  * @constructor
  * Create a new Sidebar
@@ -3015,22 +3021,24 @@ Roo.extend(Roo.bootstrap.NavHeaderbar, Roo.bootstrap.NavSimplebar,  {
     position: '',
     brand: '',
     brand_href: false,
-    
+    srButton : true,
+    autohide : false,
     
     getAutoCreate : function(){
         
-        
-        
         var   cfg = {
             tag: this.nav || 'nav',
             cls: 'navbar',
             role: 'navigation',
-            cn: [
-                {
-                    tag: 'div',
-                    cls: 'navbar-header',
-                    cn: [
-                        {
+            cn: []
+        };
+        
+        if(this.srButton){
+            cfg.cn.push({
+                tag: 'div',
+                cls: 'navbar-header',
+                cn: [
+                    {
                         tag: 'button',
                         type: 'button',
                         cls: 'navbar-toggle',
@@ -3054,15 +3062,16 @@ Roo.extend(Roo.bootstrap.NavHeaderbar, Roo.bootstrap.NavSimplebar,  {
                                 cls: 'icon-bar'
                             }
                         ]
-                        }
-                    ]
-                },
-                {
-                tag: 'div',
-                cls: 'collapse navbar-collapse'
-                }
-            ]
-        };
+                    }
+                ]
+            });
+        }
+        
+        cfg.cn.push({
+            tag: 'div',
+            cls: 'collapse navbar-collapse',
+            cn : []
+        });
         
         cfg.cls += this.inverse ? ' navbar-inverse' : ' navbar-default';
         
@@ -3093,8 +3102,35 @@ Roo.extend(Roo.bootstrap.NavHeaderbar, Roo.bootstrap.NavSimplebar,  {
         return cfg;
 
         
-    }
-    
+    },
+    initEvents : function()
+    {
+        Roo.bootstrap.NavHeaderbar.superclass.initEvents.call(this);
+        
+        if (this.autohide) {
+            
+            var prevScroll = 0;
+            var ft = this.el;
+            
+            Roo.get(document).on('scroll',function(e) {
+                var ns = Roo.get(document).getScroll().top;
+                var os = prevScroll;
+                prevScroll = ns;
+                
+                if(ns > os){
+                    ft.removeClass('slideDown');
+                    ft.addClass('slideUp');
+                    return;
+                }
+                ft.removeClass('slideUp');
+                ft.addClass('slideDown');
+                 
+              
+          },this);
+        }
+    }    
+          
+      
     
     
 });
@@ -3173,6 +3209,7 @@ Roo.extend(Roo.bootstrap.NavSidebar, Roo.bootstrap.Navbar,  {
 Roo.bootstrap.NavGroup = function(config){
     Roo.bootstrap.NavGroup.superclass.constructor.call(this, config);
     this.navItems = [];
+   
     Roo.bootstrap.NavGroup.register(this);
      this.addEvents({
         /**
@@ -3196,7 +3233,7 @@ Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component,  {
     navId : '',
     // private
     
-    navItems : false,
+    navItems : false, 
     
     getAutoCreate : function()
     {
@@ -3250,7 +3287,10 @@ Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component,  {
         
         return cfg;
     },
-    
+    /**
+    * sets the active Navigation item
+    * @param {Roo.bootstrap.NavItem} the new current navitem
+    */
     setActiveItem : function(item)
     {
         var prev = false;
@@ -3271,7 +3311,43 @@ Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component,  {
         
         
     },
+    /**
+    * gets the active Navigation item
+    * @return {Roo.bootstrap.NavItem} the current navitem
+    */
+    getActive : function()
+    {
+        
+        var prev = false;
+        Roo.each(this.navItems, function(v){
+            
+            if (v.isActive()) {
+                prev = v;
+                
+            }
+            
+        });
+        return prev;
+    },
     
+    indexOfNav : function()
+    {
+        
+        var prev = false;
+        Roo.each(this.navItems, function(v,i){
+            
+            if (v.isActive()) {
+                prev = i;
+                
+            }
+            
+        });
+        return prev;
+    },
+    /**
+    * adds a Navigation item
+    * @param {Roo.bootstrap.NavItem} the navitem to add
+    */
     addItem : function(cfg)
     {
         var cn = new Roo.bootstrap.NavItem(cfg);
@@ -3280,13 +3356,18 @@ Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component,  {
         cn.onRender(this.el, null);
         return cn;
     },
-    
+    /**
+    * register a Navigation item
+    * @param {Roo.bootstrap.NavItem} the navitem to add
+    */
     register : function(item)
     {
         this.navItems.push( item);
         item.navId = this.navId;
     
     },
+  
+    
     getNavItem: function(tabId)
     {
         var ret = false;
@@ -3299,9 +3380,47 @@ Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component,  {
             
         });
         return ret;
-    }
-    
+    },
     
+    setActiveNext : function()
+    {
+        var i = this.indexOfNav(this.getActive());
+        if (i > this.navItems.length) {
+            return;
+        }
+        this.setActiveItem(this.navItems[i+1]);
+    },
+    setActivePrev : function()
+    {
+        var i = this.indexOfNav(this.getActive());
+        if (i  < 1) {
+            return;
+        }
+        this.setActiveItem(this.navItems[i-1]);
+    },
+    clearWasActive : function(except) {
+        Roo.each(this.navItems, function(e) {
+            if (e.tabId != except.tabId && e.was_active) {
+               e.was_active = false;
+               return false;
+            }
+            return true;
+            
+        });
+    },
+    getWasActive : function ()
+    {
+        var r = false;
+        Roo.each(this.navItems, function(e) {
+            if (e.was_active) {
+               r = e;
+               return false;
+            }
+            return true;
+            
+        });
+        return r;
+    }
     
     
 });
@@ -3310,14 +3429,26 @@ Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component,  {
 Roo.apply(Roo.bootstrap.NavGroup, {
     
     groups: {},
-    
+     /**
+    * register a Navigation Group
+    * @param {Roo.bootstrap.NavGroup} the navgroup to add
+    */
     register : function(navgrp)
     {
-       this.groups[navgrp.navId] = navgrp;
+        this.groups[navgrp.navId] = navgrp;
        
     },
+    /**
+    * fetch a Navigation Group based on the navigation ID
+    * @param {string} the navgroup to add
+    * @returns {Roo.bootstrap.NavGroup} the navgroup 
+    */
     get: function(navId) {
-        return this.groups[navId];
+        if (typeof(this.groups[navId]) == 'undefined') {
+            return false;
+            //this.register(new Roo.bootstrap.NavGroup({ navId : navId }));
+        }
+        return this.groups[navId] ;
     }
     
     
@@ -3387,50 +3518,53 @@ Roo.extend(Roo.bootstrap.NavItem, Roo.bootstrap.Component,  {
     tagtype : 'a',
     disabled : false,
     
+    was_active : false,
+    
     getAutoCreate : function(){
          
         var cfg = {
             tag: 'li',
-            cls: 'nav-item',
-            cn : [
+            cls: 'nav-item'
+            
+        }
+        if (this.active) {
+            cfg.cls = typeof(cfg.cls) == 'undefined' ? 'active' : cfg.cls + ' active';
+        }
+        if (this.disabled) {
+            cfg.cls += ' disabled';
+        }
+        
+        if (this.href || this.html || this.glyphicon || this.icon) {
+            cfg.cn = [
                 {
                     tag: this.tagtype,
                     href : this.href || "#",
                     html: this.html || ''
                 }
-            ]
-        }
-            
-        if (this.active) {
-            cfg.cls = typeof(cfg.cls) == 'undefined' ? 'active' : cfg.cls + ' active';
-        }
+            ];
             
-        // glyphicon and icon go before content..
-        if (this.glyphicon || this.icon) {
-             if (this.icon) {
+            if (this.icon) {
                 cfg.cn[0].html = '<i class="'+this.icon+'"></i> <span>' + cfg.cn[0].html + '</span>'
-            } else {
+            }
+
+            if(this.glyphicon) {
                 cfg.cn[0].html = '<span class="glyphicon glyphicon-' + this.glyphicon + '"></span> '  + cfg.cn[0].html;
             }
-        }
-        
-        
-        
-        if (this.menu) {
             
-            cfg.cn[0].html += " <span class='caret'></span>";
-         
-        }
-        
-        if (this.badge !== '') {
+            if (this.menu) {
+                
+                cfg.cn[0].html += " <span class='caret'></span>";
              
-            cfg.cn[0].html += ' <span class="badge">' + this.badge + '</span>';
-        }
-        if (this.disabled) {
-            cfg.cls += ' disabled';
+            }
+            
+            if (this.badge !== '') {
+                 
+                cfg.cn[0].html += ' <span class="badge">' + this.badge + '</span>';
+            }
         }
         
         
+        
         return cfg;
     },
     initEvents: function() {
@@ -3457,6 +3591,13 @@ Roo.extend(Roo.bootstrap.NavItem, Roo.bootstrap.Component,  {
         if (this.disabled) {
             return;
         }
+        
+        var tg = Roo.bootstrap.TabGroup.get(this.navId);
+        if (tg && tg.transition) {
+            Roo.log("waiting for the transitionend");
+            return;
+        }
+        
         Roo.log("fire event clicked");
         if(this.fireEvent('click', this, e) === false){
             return;
@@ -3466,18 +3607,24 @@ Roo.extend(Roo.bootstrap.NavItem, Roo.bootstrap.Component,  {
             if (typeof(this.parent().setActiveItem) !== 'undefined') {
                 this.parent().setActiveItem(this);
             }
-           
-           
-           
         } 
     },
     
     isActive: function () {
         return this.active
     },
-    setActive : function(state, fire)
+    setActive : function(state, fire, is_was_active)
     {
+        if (this.active && !state & this.navId) {
+            this.was_active = true;
+            var nv = Roo.bootstrap.NavGroup.get(this.navId);
+            if (nv) {
+                nv.clearWasActive(this);
+            }
+            
+        }
         this.active = state;
+        
         if (!state ) {
             this.el.removeClass('active');
         } else if (!this.el.hasClass('active')) {
@@ -3486,7 +3633,34 @@ Roo.extend(Roo.bootstrap.NavItem, Roo.bootstrap.Component,  {
         if (fire) {
             this.fireEvent('changed', this, state);
         }
-       
+        
+        // show a panel if it's registered and related..
+        
+        if (!this.navId || !this.tabId || !state || is_was_active) {
+            return;
+        }
+        
+        var tg = Roo.bootstrap.TabGroup.get(this.navId);
+        if (!tg) {
+            return;
+        }
+        var pan = tg.getPanelByName(this.tabId);
+        if (!pan) {
+            return;
+        }
+        // if we can not flip to new panel - go back to old nav highlight..
+        if (false == tg.showPanel(pan)) {
+            var nv = Roo.bootstrap.NavGroup.get(this.navId);
+            if (nv) {
+                var onav = nv.getWasActive();
+                if (onav) {
+                    onav.setActive(true, false, true);
+                }
+            }
+            
+        }
+        
+        
        
     },
      // this should not be here...
@@ -4018,7 +4192,8 @@ Roo.extend(Roo.grid.ColumnModel, Roo.util.Observable, {
     /**
      * @cfg {Function} renderer (Optional) A function used to generate HTML markup for a cell
      * given the cell's data value. See {@link #setRenderer}. If not specified, the
-     * default renderer uses the raw data value.
+     * default renderer uses the raw data value. If an object is returned (bootstrap only)
+     * then it is treated as a Roo Component object instance, and it is rendered after the initial row is rendered
      */
        /**
      * @cfg {Roo.grid.GridEditor} editor (Optional) For grid editors - returns the grid editor 
@@ -4614,6 +4789,26 @@ Roo.bootstrap.Table = function(config){
          * @param {Roo.EventObject} e
          */
         "rowdblclick" : true,
+        /**
+         * @event mouseover
+         * Fires when a mouseover occur
+         * @param {Roo.bootstrap.Table} this
+         * @param {Roo.Element} el
+         * @param {Number} rowIndex
+         * @param {Number} columnIndex
+         * @param {Roo.EventObject} e
+         */
+        "mouseover" : true,
+        /**
+         * @event mouseout
+         * Fires when a mouseout occur
+         * @param {Roo.bootstrap.Table} this
+         * @param {Roo.Element} el
+         * @param {Number} rowIndex
+         * @param {Number} columnIndex
+         * @param {Roo.EventObject} e
+         */
+        "mouseout" : true,
         /**
          * @event rowclass
          * Fires when a row is rendered, so you can change add a style to it.
@@ -4653,6 +4848,8 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
     CellSelection : false,
     layout : false,
     
+    // Roo.Element - the tbody
+    mainBody: false, 
     
     getAutoCreate : function(){
         var cfg = Roo.apply({}, Roo.bootstrap.Table.superclass.getAutoCreate.call(this));
@@ -4743,7 +4940,10 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
             return;
         }
         
-        Roo.log('initEvents with ds!!!!');
+        //Roo.log('initEvents with ds!!!!');
+        
+        this.mainBody = this.el.select('tbody', true).first();
+        
         
         var _this = this;
         
@@ -4764,15 +4964,66 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
         
         this.store.on('load', this.onLoad, this);
         this.store.on('beforeload', this.onBeforeLoad, this);
+        this.store.on('update', this.onUpdate, this);
+        
+    },
+    
+    onMouseover : function(e, el)
+    {
+        var cell = Roo.get(el);
+        
+        if(!cell){
+            return;
+        }
+        
+        if(e.getTarget().nodeName.toLowerCase() != 'td'){
+            cell = cell.findParent('td', false, true);
+        }
+        
+        var row = cell.findParent('tr', false, true);
+        var cellIndex = cell.dom.cellIndex;
+        var rowIndex = row.dom.rowIndex - 1; // start from 0
+        
+        this.fireEvent('mouseover', this, cell, rowIndex, cellIndex, e);
+        
+    },
+    
+    onMouseout : function(e, el)
+    {
+        var cell = Roo.get(el);
+        
+        if(!cell){
+            return;
+        }
+        
+        if(e.getTarget().nodeName.toLowerCase() != 'td'){
+            cell = cell.findParent('td', false, true);
+        }
+        
+        var row = cell.findParent('tr', false, true);
+        var cellIndex = cell.dom.cellIndex;
+        var rowIndex = row.dom.rowIndex - 1; // start from 0
+        
+        this.fireEvent('mouseout', this, cell, rowIndex, cellIndex, e);
         
     },
     
     onClick : function(e, el)
     {
         var cell = Roo.get(el);
+        
+        if(!cell || (!this.CellSelection && !this.RowSelection)){
+            return;
+        }
+        
+        
+        if(e.getTarget().nodeName.toLowerCase() != 'td'){
+            cell = cell.findParent('td', false, true);
+        }
+        
         var row = cell.findParent('tr', false, true);
         var cellIndex = cell.dom.cellIndex;
-        var rowIndex = row.dom.rowIndex;
+        var rowIndex = row.dom.rowIndex - 1;
         
         if(this.CellSelection){
             this.fireEvent('cellclick', this, cell, rowIndex, cellIndex, e);
@@ -4787,10 +5038,19 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
     
     onDblClick : function(e,el)
     {
-        var cell = Roo.get(el);;
+        var cell = Roo.get(el);
+        
+        if(!cell || (!this.CellSelection && !this.RowSelection)){
+            return;
+        }
+        
+        if(e.getTarget().nodeName.toLowerCase() != 'td'){
+            cell = cell.findParent('td', false, true);
+        }
+        
         var row = cell.findParent('tr', false, true);
         var cellIndex = cell.dom.cellIndex;
-        var rowIndex = row.dom.rowIndex;
+        var rowIndex = row.dom.rowIndex - 1;
         
         if(this.CellSelection){
             this.fireEvent('celldblclick', this, cell, rowIndex, cellIndex, e);
@@ -4839,10 +5099,6 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
         for(var i = 0, len = cm.getColumnCount(); i < len; i++){
             
             var config = cm.config[i];
-            
-            if(typeof(config.hidden) != 'undefined' && config.hidden){
-                continue;
-            }
                     
             var c = {
                 tag: 'th',
@@ -4850,6 +5106,10 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
                 html: cm.getColumnHeader(i)
             };
             
+            if(typeof(config.hidden) != 'undefined' && config.hidden){
+                c.style += ' display:none;';
+            }
+            
             if(typeof(config.dataIndex) != 'undefined'){
                 c.sort = config.dataIndex;
             }
@@ -4858,9 +5118,9 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
                 c.cls = 'sortable';
             }
             
-//            if(typeof(config.align) != 'undefined' && config.align.length){
-//                c.style += ' text-align:' + config.align + ';';
-//            }
+            if(typeof(config.align) != 'undefined' && config.align.length){
+                c.style += ' text-align:' + config.align + ';';
+            }
             
             if(typeof(config.width) != 'undefined'){
                 c.style += ' width:' + config.width + 'px;';
@@ -4912,6 +5172,8 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
         return footer;
     },
     
+    
+    
     onLoad : function()
     {
         Roo.log('ds onload');
@@ -4919,6 +5181,7 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
         
         var _this = this;
         var cm = this.cm;
+        var ds = this.store;
         
         Roo.each(this.el.select('thead th.sortable', true).elements, function(e){
             e.removeClass(['glyphicon', 'glyphicon-arrow-up', 'glyphicon-arrow-down']);
@@ -4932,87 +5195,189 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
             }
         });
         
-        var tbody = this.el.select('tbody', true).first();
-        
-        var renders = [];
-                    
-        if(this.store.getCount() > 0){
-            this.store.data.each(function(d,rowIndex){
-                var row = {
-                    tag : 'tr',
-                    cn : []
-                };
-                
-                for(var i = 0, len = cm.getColumnCount(); i < len; i++){
-                    var config = cm.config[i];
-                    
-                    if(typeof(config.hidden) != 'undefined' && config.hidden){
-                        continue;
-                    }
-                    
-                    var renderer = cm.getRenderer(i);
-                    var value = '';
-                    var id = Roo.id();
-                    
-                    if(typeof(renderer) !== 'undefined'){
-                        value = renderer(d.data[cm.getDataIndex(i)], false, d);
-                    }
-                    
-                    if(typeof(value) === 'object'){
-                        renders.push({
-                            id : id,
-                            cfg : value 
-                        })
-                    }
-                    
-                    var rowcfg = {
-                        record: d,
-                        rowIndex : rowIndex,
-                        colIndex : i,
-                        rowClass : ''
-                    }
-
-                    _this.fireEvent('rowclass', this, rowcfg);
-                    
-                    var td = {
-                        tag: 'td',
-                        id: id,
-                        cls : rowcfg.rowClass,
-                        style: '',
-                        html: (typeof(value) === 'object') ? '' : value
-                    };
-                    
-                    if(typeof(config.align) != 'undefined' && config.align.length){
-                        td.style += ' text-align:' + config.align + ';';
-                    }
-                    
-                    if(typeof(config.width) != 'undefined'){
-                        td.style += ' width:' +  config.width + 'px;';
-                    }
-                    
-                    
-                    row.cn.push(td);
-                   
-                }
+        var tbody =  this.mainBody;
+              
+        if(ds.getCount() > 0){
+            ds.data.each(function(d,rowIndex){
+                var row =  this.renderRow(cm, ds, rowIndex);
                 
                 tbody.createChild(row);
                 
-            });
+                var _this = this;
+                
+                if(row.cellObjects.length){
+                    Roo.each(row.cellObjects, function(r){
+                        _this.renderCellObject(r);
+                    })
+                }
+                
+            }, this);
         }
         
+        Roo.each(this.el.select('tbody td', true).elements, function(e){
+            e.on('mouseover', _this.onMouseover, _this);
+        });
         
-        if(renders.length){
-            var _this = this;
-            Roo.each(renders, function(r){
-                _this.renderColumn(r);
-            })
-        }
+        Roo.each(this.el.select('tbody td', true).elements, function(e){
+            e.on('mouseout', _this.onMouseout, _this);
+        });
 
         //if(this.loadMask){
         //    this.maskEl.hide();
         //}
     },
     
+    
+    onUpdate : function(ds,record)
+    {
+        this.refreshRow(record);
+    },
+    onRemove : function(ds, record, index, isUpdate){
+        if(isUpdate !== true){
+            this.fireEvent("beforerowremoved", this, index, record);
+        }
+        var bt = this.mainBody.dom;
+        if(bt.rows[index]){
+            bt.removeChild(bt.rows[index]);
+        }
+        
+        if(isUpdate !== true){
+            //this.stripeRows(index);
+            //this.syncRowHeights(index, index);
+            //this.layout();
+            this.fireEvent("rowremoved", this, index, record);
+        }
+    },
+    
+    
+    refreshRow : function(record){
+        var ds = this.store, index;
+        if(typeof record == 'number'){
+            index = record;
+            record = ds.getAt(index);
+        }else{
+            index = ds.indexOf(record);
+        }
+        this.insertRow(ds, index, true);
+        this.onRemove(ds, record, index+1, true);
+        //this.syncRowHeights(index, index);
+        //this.layout();
+        this.fireEvent("rowupdated", this, index, record);
+    },
+    
+    insertRow : function(dm, rowIndex, isUpdate){
+        
+        if(!isUpdate){
+            this.fireEvent("beforerowsinserted", this, rowIndex);
+        }
+            //var s = this.getScrollState();
+        var row = this.renderRow(this.cm, this.store, rowIndex);
+        // insert before rowIndex..
+        var e = this.mainBody.createChild(row,this.getRowDom(rowIndex));
+        
+        var _this = this;
+                
+        if(row.cellObjects.length){
+            Roo.each(row.cellObjects, function(r){
+                _this.renderCellObject(r);
+            })
+        }
+            
+        if(!isUpdate){
+            this.fireEvent("rowsinserted", this, rowIndex);
+            //this.syncRowHeights(firstRow, lastRow);
+            //this.stripeRows(firstRow);
+            //this.layout();
+        }
+        
+    },
+    
+    
+    getRowDom : function(rowIndex)
+    {
+        // not sure if I need to check this.. but let's do it anyway..
+        return (this.mainBody.dom.rows && (rowIndex-1) < this.mainBody.dom.rows.length ) ?
+                this.mainBody.dom.rows[rowIndex] : false
+    },
+    // returns the object tree for a tr..
+  
+    
+    renderRow : function(cm, ds, rowIndex) {
+        
+        var d = ds.getAt(rowIndex);
+        
+        var row = {
+            tag : 'tr',
+            cn : []
+        };
+            
+        var cellObjects = [];
+        
+        for(var i = 0, len = cm.getColumnCount(); i < len; i++){
+            var config = cm.config[i];
+            
+            var renderer = cm.getRenderer(i);
+            var value = '';
+            var id = false;
+            
+            if(typeof(renderer) !== 'undefined'){
+                value = renderer(d.data[cm.getDataIndex(i)], false, d);
+            }
+            // if object are returned, then they are expected to be Roo.bootstrap.Component instances
+            // and are rendered into the cells after the row is rendered - using the id for the element.
+            
+            if(typeof(value) === 'object'){
+                id = Roo.id();
+                cellObjects.push({
+                    container : id,
+                    cfg : value 
+                })
+            }
+            
+            var rowcfg = {
+                record: d,
+                rowIndex : rowIndex,
+                colIndex : i,
+                rowClass : ''
+            }
+
+            this.fireEvent('rowclass', this, rowcfg);
+            
+            var td = {
+                tag: 'td',
+                cls : rowcfg.rowClass,
+                style: '',
+                html: (typeof(value) === 'object') ? '' : value
+            };
+            
+            if (id) {
+                td.id = id;
+            }
+            
+            if(typeof(config.hidden) != 'undefined' && config.hidden){
+                td.style += ' display:none;';
+            }
+            
+            if(typeof(config.align) != 'undefined' && config.align.length){
+                td.style += ' text-align:' + config.align + ';';
+            }
+            
+            if(typeof(config.width) != 'undefined'){
+                td.style += ' width:' +  config.width + 'px;';
+            }
+             
+            row.cn.push(td);
+           
+        }
+        
+        row.cellObjects = cellObjects;
+        
+        return row;
+          
+    },
+    
+    
+    
     onBeforeLoad : function()
     {
         //Roo.log('ds onBeforeLoad');
@@ -5035,19 +5400,22 @@ Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
         }
         return this.selModel;
     },
-    
-    renderColumn : function(r)
+    /*
+     * Render the Roo.bootstrap object from renderder
+     */
+    renderCellObject : function(r)
     {
         var _this = this;
-        r.cfg.render(Roo.get(r.id));
+        
+        var t = r.cfg.render(r.container);
         
         if(r.cfg.cn){
             Roo.each(r.cfg.cn, function(c){
                 var child = {
-                    id: r.id,
+                    container: t.getChildContainer(),
                     cfg: c
                 }
-                _this.renderColumn(child);
+                _this.renderCellObject(child);
             })
         }
     }
@@ -5807,10 +6175,20 @@ Roo.extend(Roo.bootstrap.Form, Roo.bootstrap.Component,  {
     initEvents : function()
     {
         this.el.on('submit', this.onSubmit, this);
+        // this was added as random key presses on the form where triggering form submit.
         this.el.on('keypress', function(e) {
             if (e.getCharCode() != 13) {
                 return true;
             }
+            // we might need to allow it for textareas.. and some other items.
+            // check e.getTarget().
+            
+            if(e.getTarget().nodeName.toLowerCase() === 'textarea'){
+                return true;
+            }
+        
+            Roo.log("keypress blocked");
+            
             e.preventDefault();
             return false;
         });
@@ -6490,6 +6868,7 @@ Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
     labelAlign : false,
     readOnly : false,
     align : false,
+    formatedValue : false,
     
     parentLabelAlign : function()
     {
@@ -6851,7 +7230,10 @@ Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
      * @return {Mixed} value The field value
      */
     getValue : function(){
-        return this.inputEl().getValue();
+        
+        var v = this.inputEl().getValue();
+        
+        return v;
     },
     /**
      * Returns the raw data value which may or may not be a valid, defined value.  To return a normalized value see {@link #getValue}.
@@ -7312,8 +7694,6 @@ Roo.extend(Roo.bootstrap.TriggerField, Roo.bootstrap.Input,  {
     
     getAutoCreate : function(){
        
-        var parent = this.parent();
-        
         var align = this.labelAlign || this.parentLabelAlign();
         
         var id = Roo.id();
@@ -7414,16 +7794,16 @@ Roo.extend(Roo.bootstrap.TriggerField, Roo.bootstrap.Input,  {
         var combobox = {
             cls: 'select2-container input-group',
             cn: [
-                box,
-                {
-                    tag: 'ul',
-                    cls: 'typeahead typeahead-long dropdown-menu',
-                    style: 'display:none'
-                }
+                box
+//                {
+//                    tag: 'ul',
+//                    cls: 'typeahead typeahead-long dropdown-menu',
+//                    style: 'display:none'
+//                }
             ]
         };
         
-        if(!this.multiple){
+        if(!this.multiple && this.showToggleBtn){
             combobox.cn.push({
                 tag :'span',
                 cls : 'input-group-addon btn dropdown-toggle',
@@ -7538,6 +7918,8 @@ Roo.extend(Roo.bootstrap.TriggerField, Roo.bootstrap.Input,  {
     // private
     initEvents : function(){
         
+        this.createList();
+        
         Roo.bootstrap.TriggerField.superclass.initEvents.call(this);
         //this.wrap = this.el.wrap({cls: "x-form-field-wrap"});
         if(!this.multiple){
@@ -7559,6 +7941,18 @@ Roo.extend(Roo.bootstrap.TriggerField, Roo.bootstrap.Input,  {
         //    this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
         //}
     },
+    
+    createList : function()
+    {
+        this.list = Roo.get(document.body).createChild({
+            tag: 'ul',
+            cls: 'typeahead typeahead-long dropdown-menu',
+            style: 'display:none'
+        });
+        
+        this.list.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';;
+        
+    },
 
     // private
     initTrigger : function(){
@@ -9719,6 +10113,10 @@ Roo.extend(Roo.data.ArrayReader, Roo.data.JsonReader, {
  * A combobox control with support for autocomplete, remote-loading, paging and many other features.
  * @cfg {Boolean} append (true|false) default false
  * @cfg {Boolean} autoFocus (true|false) auto focus the first item, default true
+ * @cfg {Boolean} tickable ComboBox with tickable selections (true|false), default false
+ * @cfg {Boolean} triggerList trigger show the list or not (true|false) default true
+ * @cfg {Boolean} show toggle button or not (true|false) default true
+ * @cfg {String} btnPosition set the position of the trigger button (left | right) default right
  * @constructor
  * Create a new ComboBox.
  * @param {Object} config Configuration options
@@ -9787,6 +10185,8 @@ Roo.bootstrap.ComboBox = function(config){
         
     });
     
+    this.item = [];
+    this.tickItems = [];
     
     this.selectedIndex = -1;
     if(this.mode == 'local'){
@@ -9974,96 +10374,256 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
     append: false,
     loadNext: false,
     autoFocus : true,
-    item: [],
-    
+    tickable : false,
+    btnPosition : 'right',
+    triggerList : true,
+    showToggleBtn : true,
     // element that contains real text value.. (when hidden is used..)
-     
-    // private
-    initEvents: function(){
+    
+    getAutoCreate : function()
+    {
+        var cfg = false;
         
-        if (!this.store) {
-            throw "can not find store for combo";
+        /*
+         *  Normal ComboBox
+         */
+        if(!this.tickable){
+            cfg = Roo.bootstrap.ComboBox.superclass.getAutoCreate.call(this);
+            return cfg;
         }
-        this.store = Roo.factory(this.store, Roo.data);
-        
-        
-        
-        Roo.bootstrap.ComboBox.superclass.initEvents.call(this);
-        
         
-        if(this.hiddenName){
-            
-            this.hiddenField = this.el.select('input.form-hidden-field',true).first();
-            
-            this.hiddenField.dom.value =
-                this.hiddenValue !== undefined ? this.hiddenValue :
-                this.value !== undefined ? this.value : '';
-
-            // prevent input submission
-            this.el.dom.removeAttribute('name');
-            this.hiddenField.dom.setAttribute('name', this.hiddenName);
-             
+        /*
+         *  ComboBox with tickable selections
+         */
              
-        }
-        //if(Roo.isGecko){
-        //    this.el.dom.setAttribute('autocomplete', 'off');
-        //}
-
-        var cls = 'x-combo-list';
-        this.list = this.el.select('ul.dropdown-menu',true).first();
-
-        //this.list = new Roo.Layer({
-        //    shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false
-        //});
+        var align = this.labelAlign || this.parentLabelAlign();
         
-        var lw = this.listWidth || Math.max(this.inputEl().getWidth(), this.minListWidth);
-        this.list.setWidth(lw);
+        cfg = {
+            cls : 'form-group roo-combobox-tickable' //input-group
+        };
         
-        this.list.on('mouseover', this.onViewOver, this);
-        this.list.on('mousemove', this.onViewMove, this);
         
-        this.list.on('scroll', this.onViewScroll, this);
+        var buttons = {
+            tag : 'div',
+            cls : 'tickable-buttons',
+            cn : [
+                {
+                    tag : 'button',
+                    type : 'button',
+                    cls : 'btn btn-link btn-edit pull-' + this.btnPosition,
+                    html : 'Edit'
+                },
+                {
+                    tag : 'button',
+                    type : 'button',
+                    name : 'ok',
+                    cls : 'btn btn-link btn-ok pull-' + this.btnPosition,
+                    html : 'Done'
+                },
+                {
+                    tag : 'button',
+                    type : 'button',
+                    name : 'cancel',
+                    cls : 'btn btn-link btn-cancel pull-' + this.btnPosition,
+                    html : 'Cancel'
+                }
+            ]
+        };
         
-        /*
-        this.list.swallowEvent('mousewheel');
-        this.assetHeight = 0;
-
-        if(this.title){
-            this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
-            this.assetHeight += this.header.getHeight();
-        }
+        var _this = this;
+        Roo.each(buttons.cn, function(c){
+            if (_this.size) {
+                c.cls += ' btn-' + _this.size;
+            }
 
-        this.innerList = this.list.createChild({cls:cls+'-inner'});
-        this.innerList.on('mouseover', this.onViewOver, this);
-        this.innerList.on('mousemove', this.onViewMove, this);
-        this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
-        
-        if(this.allowBlank && !this.pageSize && !this.disableClear){
-            this.footer = this.list.createChild({cls:cls+'-ft'});
-            this.pageTb = new Roo.Toolbar(this.footer);
-           
-        }
-        if(this.pageSize){
-            this.footer = this.list.createChild({cls:cls+'-ft'});
-            this.pageTb = new Roo.PagingToolbar(this.footer, this.store,
-                    {pageSize: this.pageSize});
-            
-        }
+            if (_this.disabled) {
+                c.disabled = true;
+            }
+        });
         
-        if (this.pageTb && this.allowBlank && !this.disableClear) {
-            var _this = this;
-            this.pageTb.add(new Roo.Toolbar.Fill(), {
-                cls: 'x-btn-icon x-btn-clear',
-                text: '&#160;',
-                handler: function()
+        var box = {
+            tag: 'div',
+            cn: [
                 {
-                    _this.collapse();
-                    _this.clearValue();
-                    _this.onSelect(false, -1);
+                    tag: 'input',
+                    type : 'hidden',
+                    cls: 'form-hidden-field'
+                },
+                {
+                    tag: 'ul',
+                    cls: 'select2-choices',
+                    cn:[
+                        {
+                            tag: 'li',
+                            cls: 'select2-search-field',
+                            cn: [
+
+                                buttons
+                            ]
+                        }
+                    ]
                 }
-            });
+            ]
         }
-        if (this.footer) {
+        
+        var combobox = {
+            cls: 'select2-container input-group select2-container-multi',
+            cn: [
+                box
+//                {
+//                    tag: 'ul',
+//                    cls: 'typeahead typeahead-long dropdown-menu',
+//                    style: 'display:none; max-height:' + this.maxHeight + 'px;'
+//                }
+            ]
+        };
+        
+        if (align ==='left' && this.fieldLabel.length) {
+            
+                Roo.log("left and has label");
+                cfg.cn = [
+                    
+                    {
+                        tag: 'label',
+                        'for' :  id,
+                        cls : 'control-label col-sm-' + this.labelWidth,
+                        html : this.fieldLabel
+                        
+                    },
+                    {
+                        cls : "col-sm-" + (12 - this.labelWidth), 
+                        cn: [
+                            combobox
+                        ]
+                    }
+                    
+                ];
+        } else if ( this.fieldLabel.length) {
+                Roo.log(" label");
+                 cfg.cn = [
+                   
+                    {
+                        tag: 'label',
+                        //cls : 'input-group-addon',
+                        html : this.fieldLabel
+                        
+                    },
+                    
+                    combobox
+                    
+                ];
+
+        } else {
+            
+                Roo.log(" no label && no align");
+                cfg = combobox
+                     
+                
+        }
+         
+        var settings=this;
+        ['xs','sm','md','lg'].map(function(size){
+            if (settings[size]) {
+                cfg.cls += ' col-' + size + '-' + settings[size];
+            }
+        });
+        
+        return cfg;
+        
+    },
+    
+    // private
+    initEvents: function()
+    {
+        
+        if (!this.store) {
+            throw "can not find store for combo";
+        }
+        this.store = Roo.factory(this.store, Roo.data);
+        
+        if(this.tickable){
+            this.initTickableEvents();
+            return;
+        }
+        
+        Roo.bootstrap.ComboBox.superclass.initEvents.call(this);
+        
+        if(this.hiddenName){
+            
+            this.hiddenField = this.el.select('input.form-hidden-field',true).first();
+            
+            this.hiddenField.dom.value =
+                this.hiddenValue !== undefined ? this.hiddenValue :
+                this.value !== undefined ? this.value : '';
+
+            // prevent input submission
+            this.el.dom.removeAttribute('name');
+            this.hiddenField.dom.setAttribute('name', this.hiddenName);
+             
+             
+        }
+        //if(Roo.isGecko){
+        //    this.el.dom.setAttribute('autocomplete', 'off');
+        //}
+        
+        var cls = 'x-combo-list';
+        
+        //this.list = new Roo.Layer({
+        //    shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false
+        //});
+        
+        var _this = this;
+        
+        (function(){
+            var lw = _this.listWidth || Math.max(_this.inputEl().getWidth(), _this.minListWidth);
+            _this.list.setWidth(lw);
+        }).defer(100);
+        
+        this.list.on('mouseover', this.onViewOver, this);
+        this.list.on('mousemove', this.onViewMove, this);
+        
+        this.list.on('scroll', this.onViewScroll, this);
+        
+        /*
+        this.list.swallowEvent('mousewheel');
+        this.assetHeight = 0;
+
+        if(this.title){
+            this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
+            this.assetHeight += this.header.getHeight();
+        }
+
+        this.innerList = this.list.createChild({cls:cls+'-inner'});
+        this.innerList.on('mouseover', this.onViewOver, this);
+        this.innerList.on('mousemove', this.onViewMove, this);
+        this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
+        
+        if(this.allowBlank && !this.pageSize && !this.disableClear){
+            this.footer = this.list.createChild({cls:cls+'-ft'});
+            this.pageTb = new Roo.Toolbar(this.footer);
+           
+        }
+        if(this.pageSize){
+            this.footer = this.list.createChild({cls:cls+'-ft'});
+            this.pageTb = new Roo.PagingToolbar(this.footer, this.store,
+                    {pageSize: this.pageSize});
+            
+        }
+        
+        if (this.pageTb && this.allowBlank && !this.disableClear) {
+            var _this = this;
+            this.pageTb.add(new Roo.Toolbar.Fill(), {
+                cls: 'x-btn-icon x-btn-clear',
+                text: '&#160;',
+                handler: function()
+                {
+                    _this.collapse();
+                    _this.clearValue();
+                    _this.onSelect(false, -1);
+                }
+            });
+        }
+        if (this.footer) {
             this.assetHeight += this.footer.getHeight();
         }
         */
@@ -10072,7 +10632,7 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
             this.tpl = '<li><a href="#">{' + this.displayField + '}</a></li>';
         }
 
-        this.view = new Roo.View(this.el.select('ul.dropdown-menu',true).first(), this.tpl, {
+        this.view = new Roo.View(this.list, this.tpl, {
             singleSelect:true, store: this.store, selectedClass: this.selectedClass
         });
         //this.view.wrapEl.setDisplayed(false);
@@ -10204,6 +10764,143 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
             this.searchField = this.el.select('ul li.select2-search-field', true).first();
         }
     },
+    
+    initTickableEvents: function()
+    {   
+        this.createList();
+        
+        if(this.hiddenName){
+            
+            this.hiddenField = this.el.select('input.form-hidden-field',true).first();
+            
+            this.hiddenField.dom.value =
+                this.hiddenValue !== undefined ? this.hiddenValue :
+                this.value !== undefined ? this.value : '';
+
+            // prevent input submission
+            this.el.dom.removeAttribute('name');
+            this.hiddenField.dom.setAttribute('name', this.hiddenName);
+             
+             
+        }
+        
+//        this.list = this.el.select('ul.dropdown-menu',true).first();
+        
+        this.choices = this.el.select('ul.select2-choices', true).first();
+        this.searchField = this.el.select('ul li.select2-search-field', true).first();
+        if(this.triggerList){
+            this.searchField.on("click", this.onSearchFieldClick, this, {preventDefault:true});
+        }
+         
+        this.trigger = this.el.select('.tickable-buttons > .btn-edit', true).first();
+        this.trigger.on("click", this.onTickableTriggerClick, this, {preventDefault:true});
+        
+        this.okBtn = this.el.select('.tickable-buttons > .btn-ok', true).first();
+        this.cancelBtn = this.el.select('.tickable-buttons > .btn-cancel', true).first();
+        
+        this.okBtn.on('click', this.onTickableFooterButtonClick, this, this.okBtn);
+        this.cancelBtn.on('click', this.onTickableFooterButtonClick, this, this.cancelBtn);
+        
+        this.trigger.setVisibilityMode(Roo.Element.DISPLAY);
+        this.okBtn.setVisibilityMode(Roo.Element.DISPLAY);
+        this.cancelBtn.setVisibilityMode(Roo.Element.DISPLAY);
+        
+        this.okBtn.hide();
+        this.cancelBtn.hide();
+        
+        var _this = this;
+        
+        (function(){
+            var lw = _this.listWidth || Math.max(_this.inputEl().getWidth(), _this.minListWidth);
+            _this.list.setWidth(lw);
+        }).defer(100);
+        
+        this.list.on('mouseover', this.onViewOver, this);
+        this.list.on('mousemove', this.onViewMove, this);
+        
+        this.list.on('scroll', this.onViewScroll, this);
+        
+        if(!this.tpl){
+            this.tpl = '<li class="select2-result"><div class="checkbox"><input id="{roo-id}" type="checkbox" {roo-data-checked}><label for="{roo-id}"><b>{' + this.displayField + '}</b></label></li>';
+        }
+
+        this.view = new Roo.View(this.list, this.tpl, {
+            singleSelect:true, tickable:true, parent:this, store: this.store, selectedClass: this.selectedClass
+        });
+        
+        //this.view.wrapEl.setDisplayed(false);
+        this.view.on('click', this.onViewClick, this);
+        
+        
+        
+        this.store.on('beforeload', this.onBeforeLoad, this);
+        this.store.on('load', this.onLoad, this);
+        this.store.on('loadexception', this.onLoadException, this);
+        
+//        this.keyNav = new Roo.KeyNav(this.inputEl(), {
+//            "up" : function(e){
+//                this.inKeyMode = true;
+//                this.selectPrev();
+//            },
+//
+//            "down" : function(e){
+//                if(!this.isExpanded()){
+//                    this.onTriggerClick();
+//                }else{
+//                    this.inKeyMode = true;
+//                    this.selectNext();
+//                }
+//            },
+//
+//            "enter" : function(e){
+////                this.onViewClick();
+//                //return true;
+//                this.collapse();
+//                
+//                if(this.fireEvent("specialkey", this, e)){
+//                    this.onViewClick(false);
+//                }
+//                
+//                return true;
+//            },
+//
+//            "esc" : function(e){
+//                this.collapse();
+//            },
+//
+//            "tab" : function(e){
+//                this.collapse();
+//                
+//                if(this.fireEvent("specialkey", this, e)){
+//                    this.onViewClick(false);
+//                }
+//                
+//                return true;
+//            },
+//
+//            scope : this,
+//
+//            doRelay : function(foo, bar, hname){
+//                if(hname == 'down' || this.scope.isExpanded()){
+//                   return Roo.KeyNav.prototype.doRelay.apply(this, arguments);
+//                }
+//                return true;
+//            },
+//
+//            forceKeyDown: true
+//        });
+        
+        
+        this.queryDelay = Math.max(this.queryDelay || 10,
+                this.mode == 'local' ? 10 : 250);
+        
+        
+        this.dqTask = new Roo.util.DelayedTask(this.initQuery, this);
+        
+        if(this.typeAhead){
+            this.taTask = new Roo.util.DelayedTask(this.onTypeAhead, this);
+        }
+    },
 
     onDestroy : function(){
         if(this.view){
@@ -10215,6 +10912,7 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
         if(this.list){
             this.list.dom.innerHTML  = '';
         }
+        
         if(this.store){
             this.store.un('beforeload', this.onBeforeLoad, this);
             this.store.un('load', this.onLoad, this);
@@ -10287,7 +10985,7 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
          if (!opts.add) {
             this.list.dom.innerHTML = '<li class="loading-indicator">'+(this.loadingText||'loading')+'</li>' ;
          }
-        this.restrictHeight();
+//        this.restrictHeight();
         this.selectedIndex = -1;
     },
 
@@ -10306,9 +11004,9 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
         
         if(this.store.getCount() > 0){
             this.expand();
-            this.restrictHeight();
+//            this.restrictHeight();
             if(this.lastQuery == this.allQuery){
-                if(this.editable){
+                if(this.editable && !this.tickable){
                     this.inputEl().dom.select();
                 }
                 if(!this.selectByValue(this.value, true) && this.autoFocus){
@@ -10444,6 +11142,12 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
     setFromData : function(o){
         
         if(this.multiple){
+            if(typeof o.display_name !== 'string'){
+                for(var i=0;i<o.display_name.length;i++){
+                    this.addItem({'id':o.id[i],'display_name':o.display_name[i]});
+                }
+                return;
+            }
             this.addItem(o);
             return;
         }
@@ -10521,6 +11225,7 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
             return;
         }
         var item = this.view.findItemFromChild(t);
+        
         if(item){
             var index = this.view.indexOf(item);
             this.select(index, false);
@@ -10528,10 +11233,38 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
     },
 
     // private
-    onViewClick : function(doFocus)
+    onViewClick : function(view, doFocus, el, e)
     {
         var index = this.view.getSelectedIndexes()[0];
+        
         var r = this.store.getAt(index);
+        
+        if(this.tickable){
+            
+            if(e.getTarget().nodeName.toLowerCase() != 'input'){
+                return;
+            }
+            
+            var rm = false;
+            var _this = this;
+            
+            Roo.each(this.tickItems, function(v,k){
+                
+                if(typeof(v) != 'undefined' && v[_this.valueField] == r.data[_this.valueField]){
+                    _this.tickItems.splice(k, 1);
+                    rm = true;
+                    return;
+                }
+            })
+            
+            if(rm){
+                return;
+            }
+            
+            this.tickItems.push(r.data);
+            return;
+        }
+        
         if(r){
             this.onSelect(r, index);
         }
@@ -10549,6 +11282,7 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
         //this.list.beginUpdate();
         //this.list.setHeight(this.innerList.getHeight()+this.list.getFrameWidth('tb')+(this.resizable?this.handleHeight:0)+this.assetHeight);
         this.list.alignTo(this.inputEl(), this.listAlign);
+        this.list.alignTo(this.inputEl(), this.listAlign);
         //this.list.endUpdate();
     },
 
@@ -10595,9 +11329,8 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
         this.view.select(index);
         if(scrollIntoView !== false){
             var el = this.view.getNode(index);
-            if(el){
-                //this.innerList.scrollChildIntoView(el, false);
-                
+            if(el && !this.multiple && !this.tickable){
+                this.list.scrollChildIntoView(el, false);
             }
         }
     },
@@ -10739,7 +11472,16 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
             return;
         }
         
+        this.hasFocus = false;
+        
         this.list.hide();
+        
+        if(this.tickable){
+            this.okBtn.hide();
+            this.cancelBtn.hide();
+            this.trigger.show();
+        }
+        
         Roo.get(document).un('mousedown', this.collapseIf, this);
         Roo.get(document).un('mousewheel', this.collapseIf, this);
         if (!this.editable) {
@@ -10752,11 +11494,16 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
     collapseIf : function(e){
         var in_combo  = e.within(this.el);
         var in_list =  e.within(this.list);
+        var is_list = (Roo.get(e.getTarget()).id == this.list.id) ? true : false;
         
-        if (in_combo || in_list) {
+        if (in_combo || in_list || is_list) {
             //e.stopPropagation();
             return;
         }
+        
+        if(this.tickable){
+            this.onTickableFooterButtonClick(e, false, false);
+        }
 
         this.collapse();
         
@@ -10771,8 +11518,21 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
             return;
         }
          Roo.log('expand');
-        this.list.alignTo(this.inputEl(), this.listAlign);
+        
         this.list.show();
+        
+        this.restrictHeight();
+        
+        if(this.tickable){
+            
+            this.tickItems = Roo.apply([], this.item);
+            
+            this.okBtn.show();
+            this.cancelBtn.show();
+            this.trigger.hide();
+            
+        }
+        
         Roo.get(document).on('mousedown', this.collapseIf, this);
         Roo.get(document).on('mousewheel', this.collapseIf, this);
         if (!this.editable) {
@@ -10784,11 +11544,11 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
 
     // private
     // Implements the default empty TriggerField.onTriggerClick function
-    onTriggerClick : function()
+    onTriggerClick : function(e)
     {
         Roo.log('trigger click');
         
-        if(this.disabled){
+        if(this.disabled || !this.triggerList){
             return;
         }
         
@@ -10813,7 +11573,42 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
             }
         }
     },
-    listKeyPress : function(e)
+    
+    onTickableTriggerClick : function(e)
+    {
+        if(this.disabled){
+            return;
+        }
+        
+        this.page = 0;
+        this.loadNext = false;
+        this.hasFocus = true;
+        
+        if(this.triggerAction == 'all') {
+            this.doQuery(this.allQuery, true);
+        } else {
+            this.doQuery(this.getRawValue());
+        }
+    },
+    
+    onSearchFieldClick : function(e)
+    {
+        if(this.hasFocus || this.disabled || e.getTarget().nodeName.toLowerCase() == 'button'){
+            return;
+        }
+        
+        this.page = 0;
+        this.loadNext = false;
+        this.hasFocus = true;
+        
+        if(this.triggerAction == 'all') {
+            this.doQuery(this.allQuery, true);
+        } else {
+            this.doQuery(this.getRawValue());
+        }
+    },
+    
+    listKeyPress : function(e)
     {
         //Roo.log('listkeypress');
         // scroll to first matching element based on key pres..
@@ -10933,6 +11728,7 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
         close.on('click', this.onRemoveItem, this, { item : choice, data : o} );
         
         this.item.push(o);
+        
         this.lastData = o;
         
         this.syncValue();
@@ -10998,6 +11794,37 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
         });
         
         this.syncValue();
+    },
+    
+    inputEl: function ()
+    {
+        if(this.tickable){
+            return this.searchField;
+        }
+        return this.el.select('input.form-control',true).first();
+    },
+    
+    
+    onTickableFooterButtonClick : function(e, btn, el)
+    {
+        e.preventDefault();
+        
+        if(btn && btn.name == 'cancel'){
+            this.tickItems = Roo.apply([], this.item);
+            this.collapse();
+            return;
+        }
+        
+        this.clearItem();
+        
+        var _this = this;
+        
+        Roo.each(this.tickItems, function(o){
+            _this.addItem(o);
+        });
+        
+        this.collapse();
+        
     }
     
     
@@ -11070,6 +11897,8 @@ Roo.extend(Roo.bootstrap.ComboBox, Roo.bootstrap.TriggerField, {
  */
 Roo.View = function(config, depreciated_tpl, depreciated_config){
     
+    this.parent = false;
+    
     if (typeof(depreciated_tpl) == 'undefined') {
         // new way.. - universal constructor.
         Roo.apply(this, config);
@@ -11093,10 +11922,7 @@ Roo.View = function(config, depreciated_tpl, depreciated_config){
     
     
     this.tpl.compile();
-   
-  
     
-     
     /** @private */
     this.addEvents({
         /**
@@ -11247,6 +12073,11 @@ Roo.extend(Roo.View, Roo.util.Observable, {
      */
     toggleSelect : false,
     
+    /**
+     * @cfg {Boolean} tickable - selecting 
+     */
+    tickable : false,
+    
     /**
      * Returns the element this view is bound to.
      * @return {Roo.Element}
@@ -11295,10 +12126,26 @@ Roo.extend(Roo.View, Roo.util.Observable, {
         for(var i = 0, len = records.length; i < len; i++){
             var data = this.prepareData(records[i].data, i, records[i]);
             this.fireEvent("preparedata", this, data, i, records[i]);
+            
+            var d = Roo.apply({}, data);
+            
+            if(this.tickable){
+                Roo.apply(d, {'roo-id' : Roo.id()});
+                
+                var _this = this;
+            
+                Roo.each(this.parent.item, function(item){
+                    if(item[_this.parent.valueField] != data[_this.parent.valueField]){
+                        return;
+                    }
+                    Roo.apply(d, {'roo-data-checked' : 'checked'});
+                });
+            }
+            
             html[html.length] = Roo.util.Format.trim(
                 this.dataName ?
-                    t.applySubtemplate(this.dataName, data, this.store.meta) :
-                    t.apply(data)
+                    t.applySubtemplate(this.dataName, d, this.store.meta) :
+                    t.apply(d)
             );
         }
         
@@ -11505,7 +12352,11 @@ Roo.extend(Roo.View, Roo.util.Observable, {
                 this.select(item, this.multiSelect && e.ctrlKey);
                 this.lastSelection = item;
             }
-            e.preventDefault();
+            
+            if(!this.tickable){
+                e.preventDefault();
+            }
+            
         }
         return true;
     },
@@ -12984,6 +13835,216 @@ Roo.extend(Roo.bootstrap.ProgressBar, Roo.bootstrap.Component,  {
 
  
 
+ /*
+ * - LGPL
+ *
+ * column
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.TabGroup
+ * @extends Roo.bootstrap.Column
+ * Bootstrap Column class
+ * @cfg {String} navId the navigation id (for use with navbars) - will be auto generated if it does not exist..
+ * @cfg {Boolean} carousel true to make the group behave like a carousel
+ * 
+ * @constructor
+ * Create a new TabGroup
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.TabGroup = function(config){
+    Roo.bootstrap.TabGroup.superclass.constructor.call(this, config);
+    if (!this.navId) {
+        this.navId = Roo.id();
+    }
+    this.tabs = [];
+    Roo.bootstrap.TabGroup.register(this);
+    
+};
+
+Roo.extend(Roo.bootstrap.TabGroup, Roo.bootstrap.Column,  {
+    
+    carousel : false,
+    transition : false,
+     
+    getAutoCreate : function()
+    {
+        var cfg = Roo.apply({}, Roo.bootstrap.TabGroup.superclass.getAutoCreate.call(this));
+        
+        cfg.cls += ' tab-content';
+        
+        if (this.carousel) {
+            cfg.cls += ' carousel slide';
+            cfg.cn = [{
+               cls : 'carousel-inner'
+            }]
+        }
+        
+        
+        return cfg;
+    },
+    getChildContainer : function()
+    {
+        return this.carousel ? this.el.select('.carousel-inner', true).first() : this.el;
+    },
+    
+    /**
+    * register a Navigation item
+    * @param {Roo.bootstrap.NavItem} the navitem to add
+    */
+    register : function(item)
+    {
+        this.tabs.push( item);
+        item.navId = this.navId; // not really needed..
+    
+    },
+    
+    getActivePanel : function()
+    {
+        var r = false;
+        Roo.each(this.tabs, function(t) {
+            if (t.active) {
+                r = t;
+                return false;
+            }
+            return null;
+        });
+        return r;
+        
+    },
+    getPanelByName : function(n)
+    {
+        var r = false;
+        Roo.each(this.tabs, function(t) {
+            if (t.tabId == n) {
+                r = t;
+                return false;
+            }
+            return null;
+        });
+        return r;
+    },
+    indexOfPanel : function(p)
+    {
+        var r = false;
+        Roo.each(this.tabs, function(t,i) {
+            if (t.tabId == p.tabId) {
+                r = i;
+                return false;
+            }
+            return null;
+        });
+        return r;
+    },
+    /**
+     * show a specific panel
+     * @param {Roo.bootstrap.TabPanel|number|string} panel to change to (use the tabId to specify a specific one)
+     * @return {boolean} false if panel was not shown (invalid entry or beforedeactivate fails.)
+     */
+    showPanel : function (pan)
+    {
+        
+        if (typeof(pan) == 'number') {
+            pan = this.tabs[pan];
+        }
+        if (typeof(pan) == 'string') {
+            pan = this.getPanelByName(pan);
+        }
+        if (pan.tabId == this.getActivePanel().tabId) {
+            return true;
+        }
+        var cur = this.getActivePanel();
+        
+        if (false === cur.fireEvent('beforedeactivate')) {
+            return false;
+        }
+        
+        if (this.carousel) {
+            this.transition = true;
+            var dir = this.indexOfPanel(pan) > this.indexOfPanel(cur)  ? 'next' : 'prev';
+            var lr = dir == 'next' ? 'left' : 'right';
+            pan.el.addClass(dir); // or prev
+            pan.el.dom.offsetWidth; // find the offset with - causing a reflow?
+            cur.el.addClass(lr); // or right
+            pan.el.addClass(lr);
+            
+            var _this = this;
+            cur.el.on('transitionend', function() {
+                Roo.log("trans end?");
+                
+                pan.el.removeClass([lr,dir]);
+                pan.setActive(true);
+                
+                cur.el.removeClass([lr]);
+                cur.setActive(false);
+                
+                _this.transition = false;
+                
+            }, this, { single:  true } );
+            return true;
+        }
+        
+        cur.setActive(false);
+        pan.setActive(true);
+        return true;
+        
+    },
+    showPanelNext : function()
+    {
+        var i = this.indexOfPanel(this.getActivePanel());
+        if (i > this.tabs.length) {
+            return;
+        }
+        this.showPanel(this.tabs[i+1]);
+    },
+    showPanelPrev : function()
+    {
+        var i = this.indexOfPanel(this.getActivePanel());
+        if (i  < 1) {
+            return;
+        }
+        this.showPanel(this.tabs[i-1]);
+    }
+    
+    
+  
+});
+
+
+Roo.apply(Roo.bootstrap.TabGroup, {
+    
+    groups: {},
+     /**
+    * register a Navigation Group
+    * @param {Roo.bootstrap.NavGroup} the navgroup to add
+    */
+    register : function(navgrp)
+    {
+        this.groups[navgrp.navId] = navgrp;
+       
+    },
+    /**
+    * fetch a Navigation Group based on the navigation ID
+    * if one does not exist , it will get created.
+    * @param {string} the navgroup to add
+    * @returns {Roo.bootstrap.NavGroup} the navgroup 
+    */
+    get: function(navId) {
+        if (typeof(this.groups[navId]) == 'undefined') {
+            this.register(new Roo.bootstrap.TabGroup({ navId : navId }));
+        }
+        return this.groups[navId] ;
+    }
+    
+    
+    
+});
+
  /*
  * - LGPL
  *
@@ -12997,8 +14058,8 @@ Roo.extend(Roo.bootstrap.ProgressBar, Roo.bootstrap.Component,  {
  * Bootstrap TabPanel class
  * @cfg {Boolean} active panel active
  * @cfg {String} html panel content
- * @cfg {String} tabId tab relate id
- * @cfg {String} navId The navbar which triggers show hide
+ * @cfg {String} tabId  unique tab ID (will be autogenerated if not set. - used to match TabItem to Panel)
+ * @cfg {String} navId The Roo.bootstrap.NavGroup which triggers show hide ()
  * 
  * 
  * @constructor
@@ -13008,7 +14069,7 @@ Roo.extend(Roo.bootstrap.ProgressBar, Roo.bootstrap.Component,  {
 
 Roo.bootstrap.TabPanel = function(config){
     Roo.bootstrap.TabPanel.superclass.constructor.call(this, config);
-     this.addEvents({
+    this.addEvents({
         /**
             * @event changed
             * Fires when the active status changes
@@ -13016,8 +14077,19 @@ Roo.bootstrap.TabPanel = function(config){
             * @param {Boolean} state the new state
            
          */
-        'changed': true
+        'changed': true,
+        /**
+            * @event beforedeactivate
+            * Fires before a tab is de-activated - can be used to do validation on a form.
+            * @param {Roo.bootstrap.TabPanel} this
+            * @return {Boolean} false if there is an error
+           
+         */
+        'beforedeactivate': true
      });
+    
+    this.tabId = this.tabId || Roo.id();
+  
 };
 
 Roo.extend(Roo.bootstrap.TabPanel, Roo.bootstrap.Component,  {
@@ -13030,7 +14102,8 @@ Roo.extend(Roo.bootstrap.TabPanel, Roo.bootstrap.Component,  {
     getAutoCreate : function(){
         var cfg = {
             tag: 'div',
-            cls: 'tab-pane',
+            // item is needed for carousel - not sure if it has any effect otherwise
+            cls: 'tab-pane item',
             html: this.html || ''
         };
         
@@ -13042,26 +14115,38 @@ Roo.extend(Roo.bootstrap.TabPanel, Roo.bootstrap.Component,  {
             cfg.tabId = this.tabId;
         }
         
+        
         return cfg;
     },
+    
+    initEvents:  function()
+    {
+        Roo.log('-------- init events on tab panel ---------');
+        
+        var p = this.parent();
+        this.navId = this.navId || p.navId;
+        
+        if (typeof(this.navId) != 'undefined') {
+            // not really needed.. but just in case.. parent should be a NavGroup.
+            var tg = Roo.bootstrap.TabGroup.get(this.navId);
+            Roo.log(['register', tg, this]);
+            tg.register(this);
+        }
+    },
+    
+    
     onRender : function(ct, position)
     {
        // Roo.log("Call onRender: " + this.xtype);
         
         Roo.bootstrap.TabPanel.superclass.onRender.call(this, ct, position);
         
-        if (this.navId && this.tabId) {
-            var item = Roo.bootstrap.NavGroup.get(this.navId).getNavItem(this.tabId);
-            if (!item) {
-                Roo.log("could not find navID:"  + this.navId + ", tabId: " + this.tabId);
-            } else {
-                item.on('changed', function(item, state) {
-                    this.setActive(state);
-                }, this);
-            }
-        }
+        
+        
+        
         
     },
+    
     setActive: function(state)
     {
         Roo.log("panel - set active " + this.tabId + "=" + state);
@@ -13348,7 +14433,8 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
         
     },
     
-    update: function(){
+    update: function()
+    {
         
         this.date = (typeof(this.date) === 'undefined') ? this.UTCToday() : (typeof(this.date) === 'string') ? this.parseDate(this.date) : this.date;
         
@@ -13363,7 +14449,8 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
         this.fill();
     },
     
-    fill: function() {
+    fill: function() 
+    {
         var d = new Date(this.viewDate),
                 year = d.getUTCFullYear(),
                 month = d.getUTCMonth(),
@@ -13504,7 +14591,8 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
         }
     },
     
-    showMode: function(dir) {
+    showMode: function(dir) 
+    {
         if (dir) {
             this.viewMode = Math.max(this.minViewMode, Math.min(2, this.viewMode + dir));
         }
@@ -13538,7 +14626,8 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
         this.picker().setTop(this.inputEl().getHeight()).setLeft(this.inputEl().getLeft() - this.el.getLeft());
     },
     
-    parseDate : function(value){
+    parseDate : function(value)
+    {
         if(!value || value instanceof Date){
             return value;
         }
@@ -13557,7 +14646,8 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
         return v;
     },
     
-    formatDate : function(date, fmt){
+    formatDate : function(date, fmt)
+    {
         return (!date || !(date instanceof Date)) ?
         date : date.dateFormat(fmt || this.format);
     },
@@ -13571,6 +14661,13 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
     onBlur : function()
     {
         Roo.bootstrap.DateField.superclass.onBlur.call(this);
+        
+        var d = this.inputEl().getValue();
+        
+        if(d && d.length){
+            this.setValue(d);
+        }
+                
         this.hide();
     },
     
@@ -13594,33 +14691,53 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
         
     },
     
-    onMousedown: function(e){
+    onMousedown: function(e)
+    {
         e.stopPropagation();
         e.preventDefault();
     },
     
-    keyup: function(e){
+    keyup: function(e)
+    {
         Roo.bootstrap.DateField.superclass.keyup.call(this);
         this.update();
-        
     },
 
-    setValue: function(v){
+    setValue: function(v)
+    {
         Roo.bootstrap.DateField.superclass.setValue.call(this, v);
         
+        var d = new Date(v);
+        
+        if(isNaN(d.getTime())){
+            return;
+        }
+        
+        this.date = new Date(d.getTime() - d.getTimezoneOffset()*60000);
+
+        this.update();
+
         this.fireEvent('select', this, this.date);
         
     },
     
-    fireKey: function(e){
+    getValue: function()
+    {
+        return this.formatDate(this.date);
+    },
+    
+    fireKey: function(e)
+    {
         if (!this.picker().isVisible()){
             if (e.keyCode == 27) // allow escape to hide and re-show picker
                 this.show();
             return;
         }
+        
         var dateChanged = false,
         dir, day, month,
         newDate, newViewDate;
+        
         switch(e.keyCode){
             case 27: // escape
                 this.hide();
@@ -13647,7 +14764,7 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
                     this.date = newDate;
                     this.viewDate = newViewDate;
                     this.setValue(this.formatDate(this.date));
-                    this.update();
+//                    this.update();
                     e.preventDefault();
                     dateChanged = true;
                 }
@@ -13672,7 +14789,7 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
                     this.date = newDate;
                     this.viewDate = newViewDate;
                     this.setValue(this.formatDate(this.date));
-                    this.update();
+//                    this.update();
                     e.preventDefault();
                     dateChanged = true;
                 }
@@ -13686,11 +14803,19 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
                 this.setValue(this.formatDate(this.date));
                 this.hide();
                 break;
+            case 16: // shift
+            case 17: // ctrl
+            case 18: // alt
+                break;
+            default :
+                this.hide();
+                
         }
     },
     
     
-    onClick: function(e) {
+    onClick: function(e) 
+    {
         e.stopPropagation();
         e.preventDefault();
         
@@ -13727,8 +14852,9 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
                     case 'today':
                         var date = new Date();
                         this.date = this.UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
-                        this.fill()
+//                        this.fill()
                         this.setValue(this.formatDate(this.date));
+                        
                         this.hide();
                         break;
                 }
@@ -13771,7 +14897,7 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
                     }
                     this.date = this.UTCDate(year, month, day,0,0,0,0);
                     this.viewDate = this.UTCDate(year, month, Math.min(28, day),0,0,0,0);
-                    this.fill();
+//                    this.fill();
                     this.setValue(this.formatDate(this.date));
                     this.hide();
                 }
@@ -13779,7 +14905,8 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
         }
     },
     
-    setStartDate: function(startDate){
+    setStartDate: function(startDate)
+    {
         this.startDate = startDate || -Infinity;
         if (this.startDate !== -Infinity) {
             this.startDate = this.parseDate(this.startDate);
@@ -13788,7 +14915,8 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
         this.updateNavArrows();
     },
 
-    setEndDate: function(endDate){
+    setEndDate: function(endDate)
+    {
         this.endDate = endDate || Infinity;
         if (this.endDate !== Infinity) {
             this.endDate = this.parseDate(this.endDate);
@@ -13797,7 +14925,8 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
         this.updateNavArrows();
     },
     
-    setDaysOfWeekDisabled: function(daysOfWeekDisabled){
+    setDaysOfWeekDisabled: function(daysOfWeekDisabled)
+    {
         this.daysOfWeekDisabled = daysOfWeekDisabled || [];
         if (typeof(this.daysOfWeekDisabled) !== 'object') {
             this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\s*/);
@@ -13809,7 +14938,8 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
         this.updateNavArrows();
     },
     
-    updateNavArrows: function() {
+    updateNavArrows: function() 
+    {
         var d = new Date(this.viewDate),
         year = d.getUTCFullYear(),
         month = d.getUTCMonth();
@@ -13851,7 +14981,8 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
         })
     },
     
-    moveMonth: function(date, dir){
+    moveMonth: function(date, dir)
+    {
         if (!dir) return date;
         var new_date = new Date(date.valueOf()),
         day = new_date.getUTCDate(),
@@ -13897,16 +15028,19 @@ Roo.extend(Roo.bootstrap.DateField, Roo.bootstrap.Input,  {
         return new_date;
     },
 
-    moveYear: function(date, dir){
+    moveYear: function(date, dir)
+    {
         return this.moveMonth(date, dir*12);
     },
 
-    dateWithinRange: function(date){
+    dateWithinRange: function(date)
+    {
         return date >= this.startDate && date <= this.endDate;
     },
 
     
-    remove: function() {
+    remove: function() 
+    {
         this.picker().remove();
     }
    
@@ -15398,11 +16532,18 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
             this.doc = iframe.contentWindow.document;
             this.win = iframe.contentWindow;
         } else {
-            if (!Roo.get(this.frameId)) {
+//            if (!Roo.get(this.frameId)) {
+//                return;
+//            }
+//            this.doc = (iframe.contentDocument || Roo.get(this.frameId).dom.document);
+//            this.win = Roo.get(this.frameId).dom.contentWindow;
+            
+            if (!Roo.get(this.frameId) && !iframe.contentDocument) {
                 return;
             }
+            
             this.doc = (iframe.contentDocument || Roo.get(this.frameId).dom.document);
-            this.win = Roo.get(this.frameId).dom.contentWindow;
+            this.win = (iframe.contentWindow || Roo.get(this.frameId).dom.contentWindow);
         }
     },
     
@@ -16736,7 +17877,7 @@ Roo.extend(Roo.bootstrap.HtmlEditor, Roo.bootstrap.TextArea,  {
 //            Roo.log('in');
 //            Roo.log(this.syncValue());
             this.syncValue();
-            this.inputEl().removeClass('hide');
+            this.inputEl().removeClass(['hide', 'x-hidden']);
             this.inputEl().dom.removeAttribute('tabIndex');
             this.inputEl().focus();
         }else{
@@ -16745,7 +17886,7 @@ Roo.extend(Roo.bootstrap.HtmlEditor, Roo.bootstrap.TextArea,  {
 //            Roo.log(this.pushValue()); 
             this.pushValue();
             
-            this.inputEl().addClass('hide');
+            this.inputEl().addClass(['hide', 'x-hidden']);
             this.inputEl().dom.setAttribute('tabIndex', -1);
             //this.deferFocus();
         }
@@ -18189,12 +19330,7 @@ Roo.extend(Roo.bootstrap.Graph, Roo.bootstrap.Component,  {
         g_gutter: '20%'
 
     },
-    title : {
-        text : '',
-        x : 150,
-        y : 50,
-        attr : { font: "20px 'Fontin Sans', Fontin-Sans, sans-serif" }
-    },
+    title : false,
 
     getAutoCreate : function(){
         
@@ -18210,7 +19346,7 @@ Roo.extend(Roo.bootstrap.Graph, Roo.bootstrap.Component,  {
     onRender : function(ct,position){
         Roo.bootstrap.Graph.superclass.onRender.call(this,ct,position);
         this.raphael = Raphael(this.el.dom);
-
+        
                     // data1 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
                     // data2 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
                     // data3 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
@@ -18258,29 +19394,47 @@ Roo.extend(Roo.bootstrap.Graph, Roo.bootstrap.Component,  {
             },
             fout = function () {
                 this.flag.animate({opacity: 0}, 300, function () {this.remove();});
+            },
+            pfin = function() {
+                this.sector.stop();
+                this.sector.scale(1.1, 1.1, this.cx, this.cy);
+
+                if (this.label) {
+                    this.label[0].stop();
+                    this.label[0].attr({ r: 7.5 });
+                    this.label[1].attr({ "font-weight": 800 });
+                }
+            },
+            pfout = function() {
+                this.sector.animate({ transform: 's1 1 ' + this.cx + ' ' + this.cy }, 500, "bounce");
+
+                if (this.label) {
+                    this.label[0].animate({ r: 5 }, 500, "bounce");
+                    this.label[1].attr({ "font-weight": 400 });
+                }
             };
 
         switch(graphtype){
             case 'bar':
                 this.raphael.barchart(this.g_x,this.g_y,this.g_width,this.g_height,xdata,opts).hover(fin,fout);
-                this.title.text = this.title.text || 'This is Vertical Barchart';
                 break;
             case 'hbar':
                 this.raphael.hbarchart(this.g_x,this.g_y,this.g_width,this.g_height,xdata,opts).hover(fin,fout);
-                this.title.text = this.title.text || 'This is Horizontal Barchart';
                 break;
             case 'pie':
-                opts = { legend: ["%% - Enterprise Users", "% - ddd","Chrome Users"], legendpos: "west", 
-                href: ["http://raphaeljs.com", "http://g.raphaeljs.com"]};
-            
-                this.raphael.piechart(this.g_x,this.g_y,this.g_r,xdata,opts);
+//                opts = { legend: ["%% - Enterprise Users", "% - ddd","Chrome Users"], legendpos: "west", 
+//                href: ["http://raphaeljs.com", "http://g.raphaeljs.com"]};
+//            
+                this.raphael.piechart(this.g_x,this.g_y,this.g_r,xdata,opts).hover(pfin, pfout);
                 
-                this.title.text = this.title.text || 'This is Piechart';
                 break;
 
         }
         
-        this.raphael.text(this.title.x, this.title.y, this.title.text).attr(this.title.attr);
+        if(this.title){
+            this.raphael.text(this.title.x, this.title.y, this.title.text).attr(this.title.attr);
+        }
+        
     },
     
     setTitle: function(o)
@@ -18322,7 +19476,6 @@ Roo.bootstrap.dash = Roo.bootstrap.dash || {};
  * @cfg {String} icon Box icon
  * @cfg {String} footer Footer text
  * @cfg {String} fhref Footer href
- * @cfg {String} ficon Footer icon
  * 
  * @constructor
  * Create a new NumberBox
@@ -18388,17 +19541,9 @@ Roo.extend(Roo.bootstrap.dash.NumberBox, Roo.bootstrap.Component,  {
                 tag : 'a',
                 cls : 'small-box-footer',
                 href : this.fhref || '#',
-                html : this.footer,
-                cn : []
+                html : this.footer
             };
             
-            if(this.ficon){
-                footer.cn.push({
-                    tag : 'i',
-                    cls : 'fa ' + this.ficon
-                });
-            }
-            
             cfg.cn.push(footer);
             
         }
@@ -18414,25 +19559,665 @@ Roo.extend(Roo.bootstrap.dash.NumberBox, Roo.bootstrap.Component,  {
                 
     },
 
-    setHeadline: function ()
+    setHeadline: function (value)
     {
         this.el.select('.roo-headline',true).first().dom.innerHTML = value;
     },
+    
+    setFooter: function (value, href)
+    {
+        this.el.select('a.small-box-footer',true).first().dom.innerHTML = value;
+        
+        if(href){
+            this.el.select('a.small-box-footer',true).first().attr('href', href);
+        }
+        
+    },
 
+    setContent: function (value)
+    {
+        this.el.select('.roo-content',true).first().dom.innerHTML = value;
+    },
 
-    initEvents: function() {
+    initEvents: function() 
+    {   
         
-        if(!this.href){
-            this.el.on('click', this.onClick, this);
+    }
+    
+});
+
+/*
+ * - LGPL
+ *
+ * TabBox
+ * 
+ */
+Roo.bootstrap.dash = Roo.bootstrap.dash || {};
+
+/**
+ * @class Roo.bootstrap.dash.TabBox
+ * @extends Roo.bootstrap.Component
+ * Bootstrap TabBox class
+ * @cfg {String} title Title of the TabBox
+ * @cfg {String} icon Icon of the TabBox
+ * @cfg {Boolean} showtabs (true|false) show the tabs default true
+ * 
+ * @constructor
+ * Create a new TabBox
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.dash.TabBox = function(config){
+    Roo.bootstrap.dash.TabBox.superclass.constructor.call(this, config);
+    this.addEvents({
+        // raw events
+        /**
+         * @event addpane
+         * When a pane is added
+         * @param {Roo.bootstrap.dash.TabPane} pane
+         */
+        "addpane" : true
+         
+    });
+};
+
+Roo.extend(Roo.bootstrap.dash.TabBox, Roo.bootstrap.Component,  {
+
+    title : '',
+    icon : false,
+    showtabs : true,
+    
+    getChildContainer : function()
+    {
+        return this.el.select('.tab-content', true).first();
+    },
+    
+    getAutoCreate : function(){
+        
+        var header = {
+            tag: 'li',
+            cls: 'pull-left header',
+            html: this.title,
+            cn : []
+        };
+        
+        if(this.icon){
+            header.cn.push({
+                tag: 'i',
+                cls: 'fa ' + this.icon
+            });
+        }
+        
+        
+        var cfg = {
+            tag: 'div',
+            cls: 'nav-tabs-custom',
+            cn: [
+                {
+                    tag: 'ul',
+                    cls: 'nav nav-tabs pull-right',
+                    cn: [
+                        header
+                    ]
+                },
+                {
+                    tag: 'div',
+                    cls: 'tab-content no-padding',
+                    cn: []
+                }
+            ]
+        }
+
+        return  cfg;
+    },
+    initEvents : function()
+    {
+        //Roo.log('add add pane handler');
+        this.on('addpane', this.onAddPane, this);
+    },
+     /**
+     * Updates the box title
+     * @param {String} html to set the title to.
+     */
+    setTitle : function(value)
+    {
+        this.el.select('.nav-tabs .header', true).first().dom.innerHTML = value;
+    },
+    onAddPane : function(pane)
+    {
+        //Roo.log('addpane');
+        //Roo.log(pane);
+        // tabs are rendere left to right..
+        if(!this.showtabs){
+            return;
+        }
+        
+        var ctr = this.el.select('.nav-tabs', true).first();
+         
+         
+        var existing = ctr.select('.nav-tab',true);
+        var qty = existing.getCount();;
+        
+        
+        var tab = ctr.createChild({
+            tag : 'li',
+            cls : 'nav-tab' + (qty ? '' : ' active'),
+            cn : [
+                {
+                    tag : 'a',
+                    href:'#',
+                    html : pane.title
+                }
+            ]
+        }, qty ? existing.first().dom : ctr.select('.header', true).first().dom );
+        pane.tab = tab;
+        
+        tab.on('click', this.onTabClick.createDelegate(this, [pane], true));
+        if (!qty) {
+            pane.el.addClass('active');
+        }
+        
+                
+    },
+    onTabClick : function(ev,un,ob,pane)
+    {
+        //Roo.log('tab - prev default');
+        ev.preventDefault();
+        
+        
+        this.el.select('.nav-tabs li.nav-tab', true).removeClass('active');
+        pane.tab.addClass('active');
+        //Roo.log(pane.title);
+        this.getChildContainer().select('.tab-pane',true).removeClass('active');
+        // technically we should have a deactivate event.. but maybe add later.
+        // and it should not de-activate the selected tab...
+        
+        pane.el.addClass('active');
+        pane.fireEvent('activate');
+        
+        
+    }
+    
+    
+});
+
+/*
+ * - LGPL
+ *
+ * Tab pane
+ * 
+ */
+Roo.bootstrap.dash = Roo.bootstrap.dash || {};
+/**
+ * @class Roo.bootstrap.TabPane
+ * @extends Roo.bootstrap.Component
+ * Bootstrap TabPane class
+ * @cfg {Boolean} active (false | true) Default false
+ * @cfg {String} title title of panel
+
+ * 
+ * @constructor
+ * Create a new TabPane
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.dash.TabPane = function(config){
+    Roo.bootstrap.dash.TabPane.superclass.constructor.call(this, config);
+    
+};
+
+Roo.extend(Roo.bootstrap.dash.TabPane, Roo.bootstrap.Component,  {
+    
+    active : false,
+    title : '',
+    
+    // the tabBox that this is attached to.
+    tab : false,
+     
+    getAutoCreate : function() 
+    {
+        var cfg = {
+            tag: 'div',
+            cls: 'tab-pane'
+        }
+        
+        if(this.active){
+            cfg.cls += ' active';
+        }
+        
+        return cfg;
+    },
+    initEvents  : function()
+    {
+        //Roo.log('trigger add pane handler');
+        this.parent().fireEvent('addpane', this)
+    },
+    
+     /**
+     * Updates the tab title 
+     * @param {String} html to set the title to.
+     */
+    setTitle: function(str)
+    {
+        if (!this.tab) {
+            return;
+        }
+        this.title = str;
+        this.tab.select('a', true).first().dom.innerHTML = str;
+        
+    }
+    
+    
+    
+});
+
+
+
+ /*
+ * - LGPL
+ *
+ * menu
+ * 
+ */
+Roo.bootstrap.menu = Roo.bootstrap.menu || {};
+
+/**
+ * @class Roo.bootstrap.menu.Menu
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Menu class - container for Menu
+ * @cfg {String} html Text of the menu
+ * @cfg {String} weight (default | primary | success | info | warning | danger | inverse)
+ * @cfg {String} icon Font awesome icon
+ * @cfg {String} pos Menu align to (top | bottom) default bottom
+ * 
+ * 
+ * @constructor
+ * Create a new Menu
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.menu.Menu = function(config){
+    Roo.bootstrap.menu.Menu.superclass.constructor.call(this, config);
+    
+    this.addEvents({
+        /**
+         * @event beforeshow
+         * Fires before this menu is displayed
+         * @param {Roo.bootstrap.menu.Menu} this
+         */
+        beforeshow : true,
+        /**
+         * @event beforehide
+         * Fires before this menu is hidden
+         * @param {Roo.bootstrap.menu.Menu} this
+         */
+        beforehide : true,
+        /**
+         * @event show
+         * Fires after this menu is displayed
+         * @param {Roo.bootstrap.menu.Menu} this
+         */
+        show : true,
+        /**
+         * @event hide
+         * Fires after this menu is hidden
+         * @param {Roo.bootstrap.menu.Menu} this
+         */
+        hide : true,
+        /**
+         * @event click
+         * Fires when this menu is clicked (or when the enter key is pressed while it is active)
+         * @param {Roo.bootstrap.menu.Menu} this
+         * @param {Roo.EventObject} e
+         */
+        click : true
+    });
+    
+};
+
+Roo.extend(Roo.bootstrap.menu.Menu, Roo.bootstrap.Component,  {
+    
+    submenu : false,
+    html : '',
+    weight : 'default',
+    icon : false,
+    pos : 'bottom',
+    
+    
+    getChildContainer : function() {
+        if(this.isSubMenu){
+            return this.el;
+        }
+        
+        return this.el.select('ul.dropdown-menu', true).first();  
+    },
+    
+    getAutoCreate : function()
+    {
+        var text = [
+            {
+                tag : 'span',
+                cls : 'roo-menu-text',
+                html : this.html
+            }
+        ];
+        
+        if(this.icon){
+            text.unshift({
+                tag : 'i',
+                cls : 'fa ' + this.icon
+            })
+        }
+        
+        
+        var cfg = {
+            tag : 'div',
+            cls : 'btn-group',
+            cn : [
+                {
+                    tag : 'button',
+                    cls : 'dropdown-button btn btn-' + this.weight,
+                    cn : text
+                },
+                {
+                    tag : 'button',
+                    cls : 'dropdown-toggle btn btn-' + this.weight,
+                    cn : [
+                        {
+                            tag : 'span',
+                            cls : 'caret'
+                        }
+                    ]
+                },
+                {
+                    tag : 'ul',
+                    cls : 'dropdown-menu'
+                }
+            ]
+            
+        };
+        
+        if(this.pos == 'top'){
+            cfg.cls += ' dropup';
+        }
+        
+        if(this.isSubMenu){
+            cfg = {
+                tag : 'ul',
+                cls : 'dropdown-menu'
+            }
+        }
+       
+        return cfg;
+    },
+    
+    onRender : function(ct, position)
+    {
+        this.isSubMenu = ct.hasClass('dropdown-submenu');
+        
+        Roo.bootstrap.menu.Menu.superclass.onRender.call(this, ct, position);
+    },
+    
+    initEvents : function() 
+    {
+        if(this.isSubMenu){
+            return;
         }
+        
+        this.hidden = true;
+        
+        this.triggerEl = this.el.select('button.dropdown-toggle', true).first();
+        this.triggerEl.on('click', this.onTriggerPress, this);
+        
+        this.buttonEl = this.el.select('button.dropdown-button', true).first();
+        this.buttonEl.on('click', this.onClick, this);
+        
+    },
+    
+    list : function()
+    {
+        if(this.isSubMenu){
+            return this.el;
+        }
+        
+        return this.el.select('ul.dropdown-menu', true).first();
     },
     
     onClick : function(e)
     {
-        Roo.log('img onclick');
-        this.fireEvent('click', this, e);
+        this.fireEvent("click", this, e);
+    },
+    
+    onTriggerPress  : function(e)
+    {   
+        if (this.isVisible()) {
+            this.hide();
+        } else {
+            this.show();
+        }
+    },
+    
+    isVisible : function(){
+        return !this.hidden;
+    },
+    
+    show : function()
+    {
+        this.fireEvent("beforeshow", this);
+        
+        this.hidden = false;
+        this.el.addClass('open');
+        
+        Roo.get(document).on("mouseup", this.onMouseUp, this);
+        
+        this.fireEvent("show", this);
+        
+        
+    },
+    
+    hide : function()
+    {
+        this.fireEvent("beforehide", this);
+        
+        this.hidden = true;
+        this.el.removeClass('open');
+        
+        Roo.get(document).un("mouseup", this.onMouseUp);
+        
+        this.fireEvent("hide", this);
+    },
+    
+    onMouseUp : function()
+    {
+        this.hide();
+    }
+    
+});
+
+ /*
+ * - LGPL
+ *
+ * menu item
+ * 
+ */
+Roo.bootstrap.menu = Roo.bootstrap.menu || {};
+
+/**
+ * @class Roo.bootstrap.menu.Item
+ * @extends Roo.bootstrap.Component
+ * Bootstrap MenuItem class
+ * @cfg {Boolean} submenu (true | false) default false
+ * @cfg {String} html text of the item
+ * @cfg {String} href the link
+ * @cfg {Boolean} disable (true | false) default false
+ * @cfg {Boolean} preventDefault (true | false) default true
+ * @cfg {String} icon Font awesome icon
+ * @cfg {String} pos Submenu align to (left | right) default right 
+ * 
+ * 
+ * @constructor
+ * Create a new Item
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.menu.Item = function(config){
+    Roo.bootstrap.menu.Item.superclass.constructor.call(this, config);
+    this.addEvents({
+        /**
+         * @event mouseover
+         * Fires when the mouse is hovering over this menu
+         * @param {Roo.bootstrap.menu.Item} this
+         * @param {Roo.EventObject} e
+         */
+        mouseover : true,
+        /**
+         * @event mouseout
+         * Fires when the mouse exits this menu
+         * @param {Roo.bootstrap.menu.Item} this
+         * @param {Roo.EventObject} e
+         */
+        mouseout : true,
+        // raw events
+        /**
+         * @event click
+         * The raw click event for the entire grid.
+         * @param {Roo.EventObject} e
+         */
+        click : true
+    });
+};
+
+Roo.extend(Roo.bootstrap.menu.Item, Roo.bootstrap.Component,  {
+    
+    submenu : false,
+    href : '',
+    html : '',
+    preventDefault: true,
+    disable : false,
+    icon : false,
+    pos : 'right',
+    
+    getAutoCreate : function()
+    {
+        var text = [
+            {
+                tag : 'span',
+                cls : 'roo-menu-item-text',
+                html : this.html
+            }
+        ];
+        
+        if(this.icon){
+            text.unshift({
+                tag : 'i',
+                cls : 'fa ' + this.icon
+            })
+        }
+        
+        var cfg = {
+            tag : 'li',
+            cn : [
+                {
+                    tag : 'a',
+                    href : this.href || '#',
+                    cn : text
+                }
+            ]
+        };
+        
+        if(this.disable){
+            cfg.cls = (typeof(cfg.cls) == 'undefined') ? 'disabled' : (cfg.cls + ' disabled');
+        }
+        
+        if(this.submenu){
+            cfg.cls = (typeof(cfg.cls) == 'undefined') ? 'dropdown-submenu' : (cfg.cls + ' dropdown-submenu');
+            
+            if(this.pos == 'left'){
+                cfg.cls = (typeof(cfg.cls) == 'undefined') ? 'pull-left' : (cfg.cls + ' pull-left');
+            }
+        }
+        
+        return cfg;
+    },
+    
+    initEvents : function() 
+    {
+        this.el.on('mouseover', this.onMouseOver, this);
+        this.el.on('mouseout', this.onMouseOut, this);
+        
+        this.el.select('a', true).first().on('click', this.onClick, this);
+        
+    },
+    
+    onClick : function(e)
+    {
+        if(this.preventDefault){
+            e.preventDefault();
+        }
+        
+        this.fireEvent("click", this, e);
+    },
+    
+    onMouseOver : function(e)
+    {
+        if(this.submenu && this.pos == 'left'){
+            this.el.select('ul.dropdown-menu', true).first().setLeft(this.el.select('ul.dropdown-menu', true).first().getWidth() * -1);
+        }
+        
+        this.fireEvent("mouseover", this, e);
+    },
+    
+    onMouseOut : function(e)
+    {
+        this.fireEvent("mouseout", this, e);
+    }
+});
+
+
+ /*
+ * - LGPL
+ *
+ * menu separator
+ * 
+ */
+Roo.bootstrap.menu = Roo.bootstrap.menu || {};
+
+/**
+ * @class Roo.bootstrap.menu.Separator
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Separator class
+ * 
+ * @constructor
+ * Create a new Separator
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.menu.Separator = function(config){
+    Roo.bootstrap.menu.Separator.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.menu.Separator, Roo.bootstrap.Component,  {
+    
+    getAutoCreate : function(){
+        var cfg = {
+            tag : 'li',
+            cls: 'divider'
+        };
+        
+        return cfg;
     }
    
 });
 
  
+
\ No newline at end of file