roojs-bootstrap.js
authorAlan Knowles <alan@roojs.com>
Fri, 7 Feb 2014 07:27:49 +0000 (15:27 +0800)
committerAlan Knowles <alan@roojs.com>
Fri, 7 Feb 2014 07:27:49 +0000 (15:27 +0800)
roojs-bootstrap-debug.js

roojs-bootstrap-debug.js
roojs-bootstrap.js

index 7fe517e..9c82015 100644 (file)
@@ -688,66 +688,6 @@ Roo.extend(Roo.bootstrap.Container, Roo.bootstrap.Component,  {
 });
 
  /*
- * - LGPL
- *
- * form
- * 
- */
-
-/**
- * @class Roo.bootstrap.Form
- * @extends Roo.bootstrap.Component
- * Bootstrap Form class
- * @cfg {String} method  GET | POST (default POST)
- * @cfg {String} labelAlign top | left (default top)
- * 
- * @constructor
- * Create a new Form
- * @param {Object} config The config object
- */
-
-
-Roo.bootstrap.Form = function(config){
-    Roo.bootstrap.Form.superclass.constructor.call(this, config);
-    this.addEvents({
-        /**
-         * @event clientvalidation
-         * If the monitorValid config option is true, this event fires repetitively to notify of valid state
-         * @param {Form} this
-         * @param {Boolean} valid true if the form has passed client-side validation
-         */
-        clientvalidation: true,
-        /**
-         * @event rendered
-         * Fires when the form is rendered
-         * @param {Roo.form.Form} form
-         */
-        rendered : true
-    });
-};
-
-Roo.extend(Roo.bootstrap.Form, Roo.bootstrap.Component,  {
-      
-    
-     getAutoCreate : function(){
-        
-        var cfg = {
-            tag: 'form',
-            method : this.method || 'POST',
-            id : this.id || Roo.id(),
-            cls : ''
-        }
-        
-        if (this.labelAlign == 'left' ) {
-            cfg.cls += ' form-horizontal';
-        }
-        return cfg;
-    }
-    
-});
-
-/*
  * - LGPL
  *
  * image
@@ -807,675 +747,581 @@ Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component,  {
  /*
  * - LGPL
  *
- * Input
+ * header
  * 
  */
 
 /**
- * @class Roo.bootstrap.Input
+ * @class Roo.bootstrap.Header
  * @extends Roo.bootstrap.Component
- * Bootstrap Input class
- * @cfg {Boolean} disabled is it disabled
- * @cfg {String} fieldLabel - the label associated
- * @cfg {String} inputType button | checkbox | email | file | hidden | image | number | password | radio | range | reset | search | submit | text
- * @cfg {String} name name of the input
- * @cfg {string} fieldLabel - the label associated
- * @cfg {string}  inputType - input / file submit ...
- * @cfg {string} placeholder - placeholder to put in text.
- * @cfg {string}  before - input group add on before
- * @cfg {string} after - input group add on after
- * 
+ * Bootstrap Header class
+ * @cfg {String} html content of header
+ * @cfg {Number} level (1|2|3|4|5|6) default 1
  * 
  * @constructor
- * Create a new Input
+ * Create a new Header
  * @param {Object} config The config object
  */
 
-Roo.bootstrap.Input = function(config){
-    Roo.bootstrap.Input.superclass.constructor.call(this, config);
-   
-        this.addEvents({
-            /**
-             * @event focus
-             * Fires when this field receives input focus.
-             * @param {Roo.form.Field} this
-             */
-            focus : true,
-            /**
-             * @event blur
-             * Fires when this field loses input focus.
-             * @param {Roo.form.Field} this
-             */
-            blur : true,
-            /**
-             * @event specialkey
-             * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed.  You can check
-             * {@link Roo.EventObject#getKey} to determine which key was pressed.
-             * @param {Roo.form.Field} this
-             * @param {Roo.EventObject} e The event object
-             */
-            specialkey : true,
-            /**
-             * @event change
-             * Fires just before the field blurs if the field value has changed.
-             * @param {Roo.form.Field} this
-             * @param {Mixed} newValue The new value
-             * @param {Mixed} oldValue The original value
-             */
-            change : true,
-            /**
-             * @event invalid
-             * Fires after the field has been marked as invalid.
-             * @param {Roo.form.Field} this
-             * @param {String} msg The validation message
-             */
-            invalid : true,
-            /**
-             * @event valid
-             * Fires after the field has been validated with no errors.
-             * @param {Roo.form.Field} this
-             */
-            valid : true,
-             /**
-             * @event keyup
-             * Fires after the key up
-             * @param {Roo.form.Field} this
-             * @param {Roo.EventObject}  e The event Object
-             */
-            keyup : true
-        });
+
+Roo.bootstrap.Header  = function(config){
+    Roo.bootstrap.Header.superclass.constructor.call(this, config);
 };
 
-Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
-     /**
-     * @cfg {String/Boolean} validationEvent The event that should initiate field validation. Set to false to disable
-      automatic validation (defaults to "keyup").
-     */
-    validationEvent : "keyup",
-     /**
-     * @cfg {Boolean} validateOnBlur Whether the field should validate when it loses focus (defaults to true).
-     */
-    validateOnBlur : true,
-    /**
-     * @cfg {Number} validationDelay The length of time in milliseconds after user input begins until validation is initiated (defaults to 250)
-     */
-    validationDelay : 250,
-     /**
-     * @cfg {String} focusClass The CSS class to use when the field receives focus (defaults to "x-form-focus")
-     */
-    focusClass : "x-form-focus",  // not needed???
-    
-       
-    /**
-     * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to "x-form-invalid")
-     */
-    invalidClass : "has-error",
-    
-    /**
-     * @cfg {Boolean} selectOnFocus True to automatically select any existing field text when the field receives input focus (defaults to false)
-     */
-    selectOnFocus : false,
-    
-     /**
-     * @cfg {String} maskRe An input mask regular expression that will be used to filter keystrokes that don't match (defaults to null)
-     */
-    maskRe : null,
-       /**
-     * @cfg {String} vtype A validation type name as defined in {@link Roo.form.VTypes} (defaults to null)
-     */
-    vtype : null,
-    
-      /**
-     * @cfg {Boolean} disableKeyFilter True to disable input keystroke filtering (defaults to false)
-     */
-    disableKeyFilter : false,
-    
-       /**
-     * @cfg {Boolean} disabled True to disable the field (defaults to false).
-     */
-    disabled : false,
-     /**
-     * @cfg {Boolean} allowBlank False to validate that the value length > 0 (defaults to true)
-     */
-    allowBlank : true,
-    /**
-     * @cfg {String} blankText Error text to display if the allow blank validation fails (defaults to "This field is required")
-     */
-    blankText : "This field is required",
-    
-     /**
-     * @cfg {Number} minLength Minimum input field length required (defaults to 0)
-     */
-    minLength : 0,
-    /**
-     * @cfg {Number} maxLength Maximum input field length allowed (defaults to Number.MAX_VALUE)
-     */
-    maxLength : Number.MAX_VALUE,
-    /**
-     * @cfg {String} minLengthText Error text to display if the minimum length validation fails (defaults to "The minimum length for this field is {minLength}")
-     */
-    minLengthText : "The minimum length for this field is {0}",
-    /**
-     * @cfg {String} maxLengthText Error text to display if the maximum length validation fails (defaults to "The maximum length for this field is {maxLength}")
-     */
-    maxLengthText : "The maximum length for this field is {0}",
-  
-    
-    /**
-     * @cfg {Function} validator A custom validation function to be called during field validation (defaults to null).
-     * If available, this function will be called only after the basic validators all return true, and will be passed the
-     * current field value and expected to return boolean true if the value is valid or a string error message if invalid.
-     */
-    validator : null,
-    /**
-     * @cfg {RegExp} regex A JavaScript RegExp object to be tested against the field value during validation (defaults to null).
-     * If available, this regex will be evaluated only after the basic validators all return true, and will be passed the
-     * current field value.  If the test fails, the field will be marked invalid using {@link #regexText}.
-     */
-    regex : null,
-    /**
-     * @cfg {String} regexText The error text to display if {@link #regex} is used and the test fails during validation (defaults to "")
-     */
-    regexText : "",
-    
-    
+Roo.extend(Roo.bootstrap.Header, Roo.bootstrap.Component,  {
     
-    fieldLabel : '',
-    inputType : 'text',
+    //href : false,
+    html : false,
+    level : 1,
     
-    name : false,
-    placeholder: false,
-    before : false,
-    after : false,
     
-    // private
-    hasFocus : false,
-    preventMark: false,
     
     getAutoCreate : function(){
         
-        var parent = this.parent();
-        
-        var align = parent.labelAlign;
-        
-        var id = Roo.id();
-        
         var cfg = {
-            cls: 'form-group' //input-group
-        };
+            tag: 'h' + (1 *this.level),
+            html: this.html || 'fill in html'
+        } ;
         
-        var input =  {
-            tag: 'input',
-            id : id,
-            type : this.inputType,
-            cls : 'form-control',
-            placeholder : this.placeholder || '' 
-            
-        };
-        if (this.name) {
-            input.name = name;
-        }
-        
-        var inputblock = input;
-        
-        if (this.before || this.after) {
-            
-            inputblock = {
-                cls : 'input-group',
-                cn :  [] 
-            };
-            if (this.before) {
-                inputblock.cn.push({
-                    tag :'span',
-                    cls : 'input-group-addon',
-                    html : this.before
-                });
-            }
-            inputblock.cn.push(input);
-            if (this.after) {
-                inputblock.cn.push({
-                    tag :'span',
-                    cls : 'input-group-addon',
-                    html : this.after
-                });
-            }
-            
-        }
-        
-        Roo.log(align);
-        Roo.log(this.fieldLabel.length);
-        
-        if (align ==='left' && this.fieldLabel.length) {
-                Roo.log("left and has label");
-                cfg.cn = [
-                    
-                    {
-                        tag: 'label',
-                        'for' :  id,
-                        cls : 'col-sm-2 control-label',
-                        html : this.fieldLabel
-                        
-                    },
-                    {
-                        cls : "col-sm-10", 
-                        cn: [
-                            inputblock
-                        ]
-                    }
-                    
-                ];
-        } else if ( this.fieldLabel.length) {
-                Roo.log(" label");
-                 cfg.cn = [
-                   
-                    {
-                        tag: 'label',
-                        //cls : 'input-group-addon',
-                        html : this.fieldLabel
-                        
-                    },
-                    
-                    inputblock
-                    
-                ];
+        return cfg;
+    }
+   
+});
 
-        } else {
-            
-                   Roo.log(" no label && no align");
-                cfg.cn = [
-                    
-                        inputblock
-                    
-                ];
-                
-                
-        }
-         
-        
-        
-        
-        if (this.disabled) {
-            input.disabled=true;
-        }
+
+ /*
+ * - LGPL
+ *
+ * menu
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.Menu
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Menu class - container for MenuItems
+ * @cfg {String} type type of menu
+ * 
+ * @constructor
+ * Create a new Menu
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.Menu = function(config){
+    Roo.bootstrap.Menu.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
+    
+   /// html : false,
+    //align : '',
+    triggerEl : false,
+    type: false,
+    
+    
+    getChildContainer : function() {
+        return this.el;  
+    },
+    
+    getAutoCreate : function(){
+        
+       //if (['right'].indexOf(this.align)!==-1) {
+       //    cfg.cn[1].cls += ' pull-right'
+       //}
+       var cfg = {
+           tag : 'ul',
+           cls : 'dropdown-menu' 
+           
+       }
+       
+       if (this.type==='submenu') {
+           cfg.cls='submenu active'
+       }
+       
         return cfg;
-        
     },
-    /**
-     * return the real input element.
-     */
-    inputEl: function ()
-    {
-        return this.el.select('input.form-control',true).first();
+    initEvents : function() {
+       // Roo.log("ADD event");
+       // Roo.log(this.triggerEl.dom);
+        this.triggerEl.on('click', this.toggle, this);
+        this.triggerEl.addClass('dropdown-toggle');
+        
     },
-    setDisabled : function(v)
+    toggle  : function(e)
     {
-        var i  = this.inputEl().dom;
-        if (v) {
-            i.removeAttribute('disabled');
+        //Roo.log(e.getTarget());
+       // Roo.log(this.triggerEl.dom);
+        if (Roo.get(e.getTarget()).findParent('.dropdown-menu')) {
             return;
-            
         }
-        i.setAttribute('disabled','true');
-    },
-    initEvents : function()
-    {
+        var isActive = this.triggerEl.hasClass('open');
+        // if disabled.. ingore
+        this.clearMenus(e);
+        //if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
+         // if mobile we use a backdrop because click events don't delegate
+        // $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
+        // }
+       //var relatedTarget = { relatedTarget: this }
+       //$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
+       //if (e.isDefaultPrevented()) return;
         
-        this.inputEl().on("keydown" , this.fireKey,  this);
-        this.inputEl().on("focus", this.onFocus,  this);
-        this.inputEl().on("blur", this.onBlur,  this);
-        this.inputEl().relayEvent('keyup', this);
-
-        // reference to original value for reset
-        this.originalValue = this.getValue();
-        //Roo.form.TextField.superclass.initEvents.call(this);
-        if(this.validationEvent == 'keyup'){
-            this.validationTask = new Roo.util.DelayedTask(this.validate, this);
-            this.inputEl().on('keyup', this.filterValidation, this);
-        }
-        else if(this.validationEvent !== false){
-            this.inputEl().on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
-        }
+       this.triggerEl[isActive ? 'removeClass' : 'addClass']('open');
+       
+       //  .trigger('shown.bs.dropdown', relatedTarget)
+       this.triggerEl.focus();
+       Roo.log(e);
+       e.preventDefault(); 
         
-        if(this.selectOnFocus){
-            this.on("focus", this.preFocus, this);
-            
-        }
-        if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Roo.form.VTypes[this.vtype+'Mask']))){
-            this.inputEl().on("keypress", this.filterKeys, this);
-        }
-       /* if(this.grow){
-            this.el.on("keyup", this.onKeyUp,  this, {buffer:50});
-            this.el.on("click", this.autoSize,  this);
-        }
-        */
-        if(this.inputEl().is('input[type=password]') && Roo.isSafari){
-            this.inputEl().on('keydown', this.SafariOnKeyDown, this);
-        }
         
     },
-    filterValidation : function(e){
-        if(!e.isNavKeyPress()){
-            this.validationTask.delay(this.validationDelay);
-        }
-    },
-     /**
-     * Validates the field value
-     * @return {Boolean} True if the value is valid, else false
-     */
-    validate : function(){
-        //if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
-        if(this.disabled || this.validateValue(this.getRawValue())){
-            this.clearInvalid();
-            return true;
-        }
-        return false;
-    },
-    
+    clearMenus : function()
+    {
+        //$(backdrop).remove()
+        Roo.select('.dropdown-toggle',true).each(function(aa) {
+            if (!aa.hasClass('open')) {
+                return;
+            }
+            // triger close...
+            aa.removeClass('open');
+          //var parent = getParent($(this))
+          //var relatedTarget = { relatedTarget: this }
+          
+           //$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
+          //if (e.isDefaultPrevented()) return
+           //$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
+        })
+    }
     
-    /**
-     * Validates a value according to the field's validation rules and marks the field as invalid
-     * if the validation fails
-     * @param {Mixed} value The value to validate
-     * @return {Boolean} True if the value is valid, else false
-     */
-    validateValue : function(value){
-        if(value.length < 1)  { // if it's blank
-             if(this.allowBlank){
-                this.clearInvalid();
-                return true;
-             }else{
-                this.markInvalid(this.blankText);
-                return false;
-             }
-        }
-        if(value.length < this.minLength){
-            this.markInvalid(String.format(this.minLengthText, this.minLength));
-            return false;
-        }
-        if(value.length > this.maxLength){
-            this.markInvalid(String.format(this.maxLengthText, this.maxLength));
-            return false;
-        }
-        if(this.vtype){
-            var vt = Roo.form.VTypes;
-            if(!vt[this.vtype](value, this)){
-                this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
-                return false;
-            }
-        }
-        if(typeof this.validator == "function"){
-            var msg = this.validator(value);
-            if(msg !== true){
-                this.markInvalid(msg);
-                return false;
-            }
-        }
-        if(this.regex && !this.regex.test(value)){
-            this.markInvalid(this.regexText);
-            return false;
-        }
-        return true;
-    },
+   
+});
+
+
+ /*
+ * - LGPL
+ *
+ * menu item
+ * 
+ */
+
+
+/**
+ * @class Roo.bootstrap.MenuItem
+ * @extends Roo.bootstrap.Component
+ * Bootstrap MenuItem class
+ * @cfg {String} html the menu label
+ * @cfg {String} href the link
+ * 
+ * 
+ * @constructor
+ * Create a new MenuItem
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.MenuItem = function(config){
+    Roo.bootstrap.MenuItem.superclass.constructor.call(this, config);
+};
 
+Roo.extend(Roo.bootstrap.MenuItem, Roo.bootstrap.Component,  {
     
+    href : false,
+    html : false,
     
-     // private
-    fireKey : function(e){
-        //Roo.log('field ' + e.getKey());
-        if(e.isNavKeyPress()){
-            this.fireEvent("specialkey", this, e);
-        }
-    },
-    onFocus : function(){
-        if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
-           // this.el.addClass(this.focusClass);
-        }
-        if(!this.hasFocus){
-            this.hasFocus = true;
-            this.startValue = this.getValue();
-            this.fireEvent("focus", this);
-        }
-    },
+    getAutoCreate : function(){
+        var cfg= {
+           tag: 'li',
+           cn: [
+               {
+                   tag : 'a',
+                   href : '#',
+                   html : 'Link'
+               }
+           ]
+        };
+       
+        cfg.cn[0].href = this.href || cfg.cn[0].href ;
+        cfg.cn[0].html = this.html || cfg.cn[0].html ;
+        return cfg;
+    }
+   
+});
+
+
+ /*
+ * - LGPL
+ *
+ * menu separator
+ * 
+ */
+
+
+/**
+ * @class Roo.bootstrap.MenuSeparator
+ * @extends Roo.bootstrap.Component
+ * Bootstrap MenuSeparator class
+ * 
+ * @constructor
+ * Create a new MenuItem
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.MenuSeparator = function(config){
+    Roo.bootstrap.MenuSeparator.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.MenuSeparator, Roo.bootstrap.Component,  {
     
-    beforeBlur : Roo.emptyFn,
+    getAutoCreate : function(){
+        var cfg = {
+            cls: 'divider',
+            tag : 'li'
+        };
+        
+        return cfg;
+    }
+   
+});
+
+
+/*
+<div class="modal fade">
+  <div class="modal-dialog">
+    <div class="modal-content">
+      <div class="modal-header">
+        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+        <h4 class="modal-title">Modal title</h4>
+      </div>
+      <div class="modal-body">
+        <p>One fine body&hellip;</p>
+      </div>
+      <div class="modal-footer">
+        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+        <button type="button" class="btn btn-primary">Save changes</button>
+      </div>
+    </div><!-- /.modal-content -->
+  </div><!-- /.modal-dialog -->
+</div><!-- /.modal -->
+*/
+/*
+ * - LGPL
+ *
+ * page contgainer.
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.Modal
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Modal class
+ * @cfg {String} title Title of dialog
+ * @cfg {Array} buttons Array of buttons
+ * 
+ * @constructor
+ * Create a new Modal Dialog
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.Modal = function(config){
+    Roo.bootstrap.Modal.superclass.constructor.call(this, config);
+};
 
+Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component,  {
     
-    // private
-    onBlur : function(){
-        this.beforeBlur();
-        if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
-            //this.el.removeClass(this.focusClass);
-        }
-        this.hasFocus = false;
-        if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
-            this.validate();
+    title : 'test dialog',
+   
+    buttons : false,
+
+    onRender : function(ct, position)
+    {
+        Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
+        if(!this.el){
+            var cfg = Roo.apply({},  this.getAutoCreate());
+            cfg.id = Roo.id();
+            //if(!cfg.name){
+            //    cfg.name = typeof(this.name) == 'undefined' ? this.id : this.name;
+            //}
+            //if (!cfg.name.length) {
+            //    delete cfg.name;
+           // }
+            if (this.cls) {
+                cfg.cls += ' ' + this.cls;
+            }
+            if (this.style) {
+                cfg.style = this.style;
+            }
+            this.el = Roo.get(document.body).createChild(cfg, position);
         }
-        var v = this.getValue();
-        if(String(v) !== String(this.startValue)){
-            this.fireEvent('change', this, v, this.startValue);
+        //var type = this.el.dom.type;
+         
+        if(this.tabIndex !== undefined){
+            this.el.dom.setAttribute('tabIndex', this.tabIndex);
         }
-        this.fireEvent("blur", this);
-    },
-     /**
-     * Returns the normalized data value (undefined or emptyText will be returned as '').  To return the raw value see {@link #getRawValue}.
-     * @return {Mixed} value The field value
-     */
-    getValue : function(){
-        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}.
-     * @return {Mixed} value The field value
-     */
-    getRawValue : function(){
-        var v = this.inputEl().getValue();
+        this.initEvents();
+        //this.el.addClass([this.fieldClass, this.cls]);
         
-        return v;
     },
-    /**
-     * Sets a data value into the field and validates it.  To set the value directly without validation see {@link #setRawValue}.
-     * @param {Mixed} value The value to set
-     */
-    setValue : function(v){
-        this.value = v;
-        if(this.rendered){
-            this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
-            this.validate();
-        }
-    },
-    
-    /*
-    processValue : function(value){
-        if(this.stripCharsRe){
-            var newValue = value.replace(this.stripCharsRe, '');
-            if(newValue !== value){
-                this.setRawValue(newValue);
-                return newValue;
-            }
-        }
-        return value;
-    },
-  */
-    preFocus : function(){
-        
-        if(this.selectOnFocus){
-            this.inputEl().dom.select();
-        }
-    },
-    filterKeys : function(e){
-        var k = e.getKey();
-        if(!Roo.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
-            return;
-        }
-        var c = e.getCharCode(), cc = String.fromCharCode(c);
-        if(Roo.isIE && (e.isSpecialKey() || !cc)){
-            return;
-        }
-        if(!this.maskRe.test(cc)){
-            e.stopEvent();
-        }
-    },
-     /**
-     * Clear any invalid styles/messages for this field
-     */
-    clearInvalid : function(){
+    getAutoCreate : function(){
         
-        if(!this.el || this.preventMark){ // not rendered
-            return;
-        }
-        this.el.removeClass(this.invalidClass);
-        /*
-        switch(this.msgTarget){
-            case 'qtip':
-                this.el.dom.qtip = '';
-                break;
-            case 'title':
-                this.el.dom.title = '';
-                break;
-            case 'under':
-                if(this.errorEl){
-                    Roo.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
-                }
-                break;
-            case 'side':
-                if(this.errorIcon){
-                    this.errorIcon.dom.qtip = '';
-                    this.errorIcon.hide();
-                    this.un('resize', this.alignErrorIcon, this);
-                }
-                break;
-            default:
-                var t = Roo.getDom(this.msgTarget);
-                t.innerHTML = '';
-                t.style.display = 'none';
-                break;
-        }
-        */
-        this.fireEvent('valid', this);
-    },
-     /**
-     * Mark this field as invalid
-     * @param {String} msg The validation message
-     */
-    markInvalid : function(msg){
-        if(!this.el  || this.preventMark){ // not rendered
-            return;
-        }
-        this.el.addClass(this.invalidClass);
-        /*
-        msg = msg || this.invalidText;
-        switch(this.msgTarget){
-            case 'qtip':
-                this.el.dom.qtip = msg;
-                this.el.dom.qclass = 'x-form-invalid-tip';
-                if(Roo.QuickTips){ // fix for floating editors interacting with DND
-                    Roo.QuickTips.enable();
-                }
-                break;
-            case 'title':
-                this.el.dom.title = msg;
-                break;
-            case 'under':
-                if(!this.errorEl){
-                    var elp = this.el.findParent('.x-form-element', 5, true);
-                    this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
-                    this.errorEl.setWidth(elp.getWidth(true)-20);
-                }
-                this.errorEl.update(msg);
-                Roo.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
-                break;
-            case 'side':
-                if(!this.errorIcon){
-                    var elp = this.el.findParent('.x-form-element', 5, true);
-                    this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
+        return {
+            cls: "modal fade",
+            cn : [
+                {
+                    cls: "modal-dialog",
+                    cn : [
+                        {
+                            cls : "modal-content",
+                            cn : [
+                                {
+                                    cls : 'modal-header',
+                                    cn : [
+                                        {
+                                            tag: 'button',
+                                            cls : 'close',
+                                            html : '&times'
+                                        },
+                                        {
+                                            tag: 'h4',
+                                            cls : 'modal-title',
+                                            html : this.title
+                                        }
+                                    
+                                    ]
+                                },
+                                {
+                                    cls : 'modal-body'
+                                 
+                                },
+                                 {
+                                    cls : 'modal-footer'
+                                    /*
+                                    cn : [
+                                        {
+                                            tag: 'button',
+                                            cls : 'btn btn-default',
+                                            html : 'Close'
+                                        },
+                                        {
+                                            tag: 'button',
+                                            cls : 'btn btn-primary',
+                                            html : 'Save'
+                                        }
+                                    
+                                    ]
+                                    */
+                                }
+                                
+                                
+                            ]
+                            
+                        }
+                    ]
+                        
                 }
-                this.alignErrorIcon();
-                this.errorIcon.dom.qtip = msg;
-                this.errorIcon.dom.qclass = 'x-form-invalid-tip';
-                this.errorIcon.show();
-                this.on('resize', this.alignErrorIcon, this);
-                break;
-            default:
-                var t = Roo.getDom(this.msgTarget);
-                t.innerHTML = msg;
-                t.style.display = this.msgDisplay;
-                break;
-        }
-        */
-        this.fireEvent('invalid', this, msg);
-    },
-    // private
-    SafariOnKeyDown : function(event)
-    {
-        // this is a workaround for a password hang bug on chrome/ webkit.
-        
-        var isSelectAll = false;
-        
-        if(this.inputEl().dom.selectionEnd > 0){
-            isSelectAll = (this.inputEl().dom.selectionEnd - this.inputEl().dom.selectionStart - this.getValue().length == 0) ? true : false;
-        }
-        if(((event.getKey() == 8 || event.getKey() == 46) && this.getValue().length ==1)){ // backspace and delete key
-            event.preventDefault();
-            this.setValue('');
-            return;
-        }
-        
-        if(isSelectAll){ // backspace and delete key
+            ]
             
-            event.preventDefault();
-            // this is very hacky as keydown always get's upper case.
-            //
-            var cc = String.fromCharCode(event.getCharCode());
-            this.setValue( event.shiftKey ?  cc : cc.toLowerCase());
             
-        }
+        };
+          
+    },
+    getChildContainer : function() {
+         
+         return this.el.select('.modal-body',true).first();
         
+    },
+    getButtonContainer : function() {
+         return this.el.select('.modal-footer',true).first();
         
+    },
+    initEvents : function()
+    {
+        this.el.select('.modal-header .close').on('click', this.hide, this);
+    },
+    show : function() {
+        this.el.addClass('on');
+        this.el.removeClass('fade');
+        this.el.setStyle('display', 'block');
+    },
+    hide : function() {
+        this.el.removeClass('on');
+        this.el.addClass('fade');
+        this.el.setStyle('display', 'none');
     }
 });
 
-/*
+ /*
  * - LGPL
  *
- * header
+ * navbar
  * 
  */
 
 /**
- * @class Roo.bootstrap.Header
+ * @class Roo.bootstrap.Navbar
  * @extends Roo.bootstrap.Component
- * Bootstrap Header class
- * @cfg {String} html content of header
- * @cfg {Number} level (1|2|3|4|5|6) default 1
+ * Bootstrap Navbar class
+ * @cfg {Boolean} sidebar has side bar
+ * @cfg {Boolean} bar is a bar?
+ * @cfg {String} position (fixed-top|fixed-bottom|static-top) position
+ * @cfg {String} brand what is brand
+ * @cfg {Boolean} inverse is inverted color
+ * @cfg {String} type (nav | pills | tabs)
+ * @cfg {Boolean} arrangement stacked | justified
+ * @cfg {String} align (left | right) alignment
+ *
  * 
  * @constructor
- * Create a new Header
+ * Create a new Navbar
  * @param {Object} config The config object
  */
 
 
-Roo.bootstrap.Header  = function(config){
-    Roo.bootstrap.Header.superclass.constructor.call(this, config);
+Roo.bootstrap.Navbar = function(config){
+    Roo.bootstrap.Navbar.superclass.constructor.call(this, config);
 };
 
-Roo.extend(Roo.bootstrap.Header, Roo.bootstrap.Component,  {
-    
-    //href : false,
-    html : false,
-    level : 1,
+Roo.extend(Roo.bootstrap.Navbar, Roo.bootstrap.Component,  {
     
+    sidebar: false,
     
+    bar: false,
+    brand: '',
+    inverse: false,
+    position: '',
+    align : false,
+    type: 'nav',
+    arrangement: '',
     
     getAutoCreate : function(){
-        
         var cfg = {
-            tag: 'h' + (1 *this.level),
-            html: this.html || 'fill in html'
-        } ;
+            cls : 'navbar'
+        };
+       
+        if (this.sidebar === true) {
+            cfg = {
+                tag: 'div',
+                cls: 'sidebar-nav'
+            };
+            return cfg;
+        }
+        
+        if (this.bar === true) {
+            cfg = {
+                tag: 'nav',
+                cls: 'navbar',
+                role: 'navigation',
+                cn: [
+                    {
+                        tag: 'div',
+                        cls: 'navbar-header',
+                        cn: [
+                            {
+                            tag: 'button',
+                            type: 'button',
+                            cls: 'navbar-toggle',
+                            'data-toggle': 'collapse',
+                            cn: [
+                                {
+                                    tag: 'span',
+                                    cls: 'sr-only',
+                                    html: 'Toggle navigation'
+                                },
+                                {
+                                    tag: 'span',
+                                    cls: 'icon-bar'
+                                },
+                                {
+                                    tag: 'span',
+                                    cls: 'icon-bar'
+                                },
+                                {
+                                    tag: 'span',
+                                    cls: 'icon-bar'
+                                }
+                            ]
+                            }
+                        ]
+                    },
+                    {
+                    tag: 'div',
+                    cls: 'collapse navbar-collapse'
+                    }
+                ]
+            };
+            
+            cfg.cls += this.inverse ? ' navbar-inverse' : ' navbar-default';
+            
+            if (['fixed-top','fixed-bottom','static-top'].indexOf(this.position)>-1) {
+            cfg.cls += ' navbar-' + this.position;
+            cfg.tag = this.position  == 'fixed-bottom' ? 'footer' : 'header';
+            }
+            
+            if (this.brand !== '') {
+                cfg.cn[0].cn.push({
+                    tag: 'a',
+                    href: '#',
+                    cls: 'navbar-brand',
+                    cn: [
+                    this.brand
+                    ]
+                });
+            }
+            
+            return cfg;
+        
+        } else if (this.bar === false) {
+            
+        } else {
+            Roo.log('Property \'bar\' in of Navbar must be either true or false')
+        }
+       
+        cfg.cn = [
+            {
+                cls: 'nav',
+                tag : 'ul'
+            }
+        ];
+        
+        if (['tabs','pills'].indexOf(this.type)!==-1) {
+            cfg.cn[0].cls += ' nav-' + this.type
+        } else {
+            if (this.type!=='nav') {
+            Roo.log('nav type must be nav/tabs/pills')
+            }
+            cfg.cn[0].cls += ' navbar-nav'
+        }
+        
+        if (['stacked','justified'].indexOf(this.arrangement)!==-1) {
+            cfg.cn[0].cls += ' nav-' + this.arrangement;
+        }
+        
+        if (this.align === 'right') {
+            cfg.cn[0].cls += ' navbar-right';
+        }
+        if (this.inverse) {
+            cfg.cls += ' navbar-inverse';
+            
+        }
+        
         
         return cfg;
+    },
+    
+    getChildContainer : function() {
+        if (this.bar === true) {
+            return this.el.select('.collapse',true).first();
+        }
+        console.log(this);
+        return this.el;
     }
    
 });
@@ -1485,160 +1331,133 @@ Roo.extend(Roo.bootstrap.Header, Roo.bootstrap.Component,  {
  /*
  * - LGPL
  *
- * menu
+ * nav group
  * 
  */
 
 /**
- * @class Roo.bootstrap.Menu
+ * @class Roo.bootstrap.NavGroup
  * @extends Roo.bootstrap.Component
- * Bootstrap Menu class - container for MenuItems
- * @cfg {String} type type of menu
+ * Bootstrap NavGroup class
+ * @cfg {String} align left | right
+ * @cfg {Boolean} inverse false | true
  * 
  * @constructor
- * Create a new Menu
+ * Create a new nav group
  * @param {Object} config The config object
  */
 
-
-Roo.bootstrap.Menu = function(config){
-    Roo.bootstrap.Menu.superclass.constructor.call(this, config);
+Roo.bootstrap.NavGroup = function(config){
+    Roo.bootstrap.NavGroup.superclass.constructor.call(this, config);
 };
 
-Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
-    
-   /// html : false,
-    //align : '',
-    triggerEl : false,
-    type: false,
-    
+Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component,  {
     
-    getChildContainer : function() {
-        return this.el;  
-    },
+    align: '',
+    inverse: false,
+    form: false,
     
     getAutoCreate : function(){
-        
-       //if (['right'].indexOf(this.align)!==-1) {
-       //    cfg.cn[1].cls += ' pull-right'
-       //}
-       var cfg = {
-           tag : 'ul',
-           cls : 'dropdown-menu' 
-           
-       }
-       
-       if (this.type==='submenu') {
-           cfg.cls='submenu active'
-       }
-       
-        return cfg;
-    },
-    initEvents : function() {
-       // Roo.log("ADD event");
-       // Roo.log(this.triggerEl.dom);
-        this.triggerEl.on('click', this.toggle, this);
-        this.triggerEl.addClass('dropdown-toggle');
+        var cfg = Roo.apply({}, Roo.bootstrap.NavGroup.superclass.getAutoCreate.call(this));
         
-    },
-    toggle  : function(e)
-    {
-        //Roo.log(e.getTarget());
-       // Roo.log(this.triggerEl.dom);
-        if (Roo.get(e.getTarget()).findParent('.dropdown-menu')) {
-            return;
+        cfg = {
+            tag : 'ul',
+            cls: 'nav navbar-nav' 
         }
-        var isActive = this.triggerEl.hasClass('open');
-        // if disabled.. ingore
-        this.clearMenus(e);
-        //if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
-         // if mobile we use a backdrop because click events don't delegate
-        // $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
-        // }
-       //var relatedTarget = { relatedTarget: this }
-       //$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
-       //if (e.isDefaultPrevented()) return;
-        
-       this.triggerEl[isActive ? 'removeClass' : 'addClass']('open');
-       
-       //  .trigger('shown.bs.dropdown', relatedTarget)
-       this.triggerEl.focus();
-       Roo.log(e);
-       e.preventDefault(); 
         
+        if (this.parent().sidebar === true) {
+            cfg = {
+                tag: 'ul',
+                cls: 'dashboard-menu'
+            }
+            
+            return cfg;
+        }
         
-    },
-    clearMenus : function()
-    {
-        //$(backdrop).remove()
-        Roo.select('.dropdown-toggle',true).each(function(aa) {
-            if (!aa.hasClass('open')) {
-                return;
+        if (this.form === true) {
+            cfg = {
+                tag: 'form',
+                cls: 'navbar-form'
             }
-            // triger close...
-            aa.removeClass('open');
-          //var parent = getParent($(this))
-          //var relatedTarget = { relatedTarget: this }
-          
-           //$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
-          //if (e.isDefaultPrevented()) return
-           //$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
-        })
-    }
-    
-   
-});
-
-
- /*
- * - LGPL
- *
- * menu item
- * 
- */
+            
+            if (this.align === 'right') {
+                cfg.cls += ' navbar-right';
+            } else {
+                cfg.cls += ' navbar-left';
+            }
+        }
+        
+        
+        if (this.align === 'right') {
+            cfg.cls += ' navbar-right';
+        }
+        
+        if (this.inverse) {
+            cfg.cls += ' navbar-inverse';
+            
+        }
+        
+        
+        return cfg;
+    }
+   
+});
 
 
+ /*
+ * - LGPL
+ *
+ * row
+ * 
+ */
 /**
- * @class Roo.bootstrap.MenuItem
+ * @class Roo.bootstrap.Navbar.Button
  * @extends Roo.bootstrap.Component
- * Bootstrap MenuItem class
- * @cfg {String} html the menu label
- * @cfg {String} href the link
- * 
- * 
+ * Bootstrap Navbar.Button class
+ * @cfg {String} href  link to
+ * @cfg {String} html content of button
+    
  * @constructor
- * Create a new MenuItem
+ * Create a new Navbar Button
  * @param {Object} config The config object
  */
 
 
-Roo.bootstrap.MenuItem = function(config){
-    Roo.bootstrap.MenuItem.superclass.constructor.call(this, config);
+Roo.bootstrap.Navbar.Button = function(config){
+    Roo.bootstrap.Navbar.Button.superclass.constructor.call(this, config);
 };
 
-Roo.extend(Roo.bootstrap.MenuItem, Roo.bootstrap.Component,  {
+Roo.extend(Roo.bootstrap.Navbar.Button, Roo.bootstrap.Component,  {
     
     href : false,
     html : false,
     
+    autoCreate : {
+        cls: 'btn',
+        tag : 'button',
+        html: 'hello'
+    },
+    
     getAutoCreate : function(){
-        var cfg= {
-           tag: 'li',
-           cn: [
-               {
-                   tag : 'a',
-                   href : '#',
-                   html : 'Link'
-               }
-           ]
-        };
-       
-        cfg.cn[0].href = this.href || cfg.cn[0].href ;
-        cfg.cn[0].html = this.html || cfg.cn[0].html ;
+        
+        var cfg = {
+            cls: 'btn',
+            tag : 'button',
+            html: 'hello',
+            cn : []
+            
+        } ;
+        cfg.cn.push({
+            html : this.html || ''
+            //href : this.
+             //       )
+        });
+        cfg.cn.push({
+            tag: 'span',
+            cls : 'carat'
+        });
+        
         return cfg;
     }
    
@@ -1649,371 +1468,315 @@ Roo.extend(Roo.bootstrap.MenuItem, Roo.bootstrap.Component,  {
  /*
  * - LGPL
  *
- * menu separator
+ * row
  * 
  */
 
-
 /**
- * @class Roo.bootstrap.MenuSeparator
+ * @class Roo.bootstrap.Navbar.Item
  * @extends Roo.bootstrap.Component
- * Bootstrap MenuSeparator class
- * 
+ * Bootstrap Navbar.Button class
+ * @cfg {String} href  link to
+ * @cfg {String} html content of button
+ * @cfg {String} badge text inside badge
+ * @cfg {String} glyphicon name of glyphicon
+  
  * @constructor
- * Create a new MenuItem
+ * Create a new Navbar Button
  * @param {Object} config The config object
  */
-
-
-Roo.bootstrap.MenuSeparator = function(config){
-    Roo.bootstrap.MenuSeparator.superclass.constructor.call(this, config);
+Roo.bootstrap.Navbar.Item = function(config){
+    Roo.bootstrap.Navbar.Item.superclass.constructor.call(this, config);
 };
 
-Roo.extend(Roo.bootstrap.MenuSeparator, Roo.bootstrap.Component,  {
+Roo.extend(Roo.bootstrap.Navbar.Item, Roo.bootstrap.Component,  {
+    
+    href: false,
+    html: '',
+    badge: '',
+    icon: false,
+    glyphicon: false,
     
     getAutoCreate : function(){
-        var cfg = {
-            cls: 'divider',
-            tag : 'li'
-        };
         
+        var cfg = Roo.apply({}, Roo.bootstrap.Navbar.Item.superclass.getAutoCreate.call(this));
+       
+       if (this.parent().parent().sidebar === true) {
+           cfg = {
+               tag: 'li',
+               cls: '',
+               cn: [
+                   {
+                       tag: 'p',
+                       cls: ''
+                   }
+               ]
+           }
+           
+           if (this.html) {
+               cfg.cn[0].html = this.html;
+           }
+           
+           if (this.active) {
+               this.cls += ' active';
+           }
+           
+           if (this.menu) {
+               cfg.cn[0].cls += ' dropdown-toggle';
+               cfg.cn[0].html = (cfg.cn[0].html || this.html) + '<span class="glyphicon glyphicon-chevron-down"></span>';
+           }
+           
+           if (this.href) {
+               cfg.cn[0].tag = 'a',
+               cfg.cn[0].href = this.href;
+           }
+           
+           if (this.glyphicon) {
+               cfg.cn[0].html = '<i class="glyphicon glyphicon-'+this.glyphicon+'"></i><span>' + cfg.cn[0].html || this.html + '</span>'
+           }
+           
+           return cfg;
+       }
+       
+       cfg = {
+           tag: 'li'
+       }
+       cfg.cn = [
+            {
+               tag: 'p',
+               html: 'Text'
+            }
+        ];
+        
+        if (this.glyphicon) {
+            if(cfg.html){cfg.html = ' ' + this.html};
+            cfg.cn=[
+                {
+                    tag: 'span',
+                    cls: 'glyphicon glyphicon-' + this.glyphicon
+                }
+            ];
+        }
+       
+        cfg.cn[0].html = this.html || cfg.cn[0].html ;
+       if (this.menu) {
+           cfg.cn[0].tag='a';
+           cfg.cn[0].href='#';
+           cfg.cn[0].html += " <span class='caret'></span>";
+       //}else if (!this.href) {
+       //    cfg.cn[0].tag='p';
+       //    cfg.cn[0].cls='navbar-text';
+       } else {
+           cfg.cn[0].tag='a';
+           cfg.cn[0].href=this.href||'#';
+           cfg.cn[0].html=this.html;
+       }
+       
+       if (this.badge !== '') {
+           
+           cfg.cn[0].cn=[
+               cfg.cn[0].html + ' ',
+               {
+                   tag: 'span',
+                   cls: 'badge',
+                   html: this.badge
+               }
+           ];
+           cfg.cn[0].html=''
+       }
+        
+       
         return cfg;
+    },
+    initEvents: function() {
+       // Roo.log('init events?');
+       // Roo.log(this.el.dom);
+        this.el.select('a',true).on('click',
+                function(e) {
+                    this.fireEvent('click', this);
+                },
+                this
+        );
     }
    
 });
-
  
 
-/*
-<div class="modal fade">
-  <div class="modal-dialog">
-    <div class="modal-content">
-      <div class="modal-header">
-        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
-        <h4 class="modal-title">Modal title</h4>
-      </div>
-      <div class="modal-body">
-        <p>One fine body&hellip;</p>
-      </div>
-      <div class="modal-footer">
-        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
-        <button type="button" class="btn btn-primary">Save changes</button>
-      </div>
-    </div><!-- /.modal-content -->
-  </div><!-- /.modal-dialog -->
-</div><!-- /.modal -->
-*/
-/*
+ /*
  * - LGPL
  *
- * page contgainer.
+ * row
  * 
  */
 
 /**
- * @class Roo.bootstrap.Modal
+ * @class Roo.bootstrap.Row
  * @extends Roo.bootstrap.Component
- * Bootstrap Modal class
- * @cfg {String} title Title of dialog
- * @cfg {Array} buttons Array of buttons
+ * Bootstrap Row class (contains columns...)
  * 
  * @constructor
- * Create a new Modal Dialog
+ * Create a new Row
  * @param {Object} config The config object
  */
 
-Roo.bootstrap.Modal = function(config){
-    Roo.bootstrap.Modal.superclass.constructor.call(this, config);
+Roo.bootstrap.Row = function(config){
+    Roo.bootstrap.Row.superclass.constructor.call(this, config);
 };
 
-Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component,  {
+Roo.extend(Roo.bootstrap.Row, Roo.bootstrap.Component,  {
     
-    title : 'test dialog',
-   
-    buttons : false,
+    autoCreate: {
+        cls: 'row clearfix'
+    }
+    
+    
+});
 
-    onRender : function(ct, position)
-    {
-        Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
-        if(!this.el){
-            var cfg = Roo.apply({},  this.getAutoCreate());
-            cfg.id = Roo.id();
-            //if(!cfg.name){
-            //    cfg.name = typeof(this.name) == 'undefined' ? this.id : this.name;
-            //}
-            //if (!cfg.name.length) {
-            //    delete cfg.name;
-           // }
-            if (this.cls) {
-                cfg.cls += ' ' + this.cls;
-            }
-            if (this.style) {
-                cfg.style = this.style;
-            }
-            this.el = Roo.get(document.body).createChild(cfg, position);
-        }
-        //var type = this.el.dom.type;
-         
-        if(this.tabIndex !== undefined){
-            this.el.dom.setAttribute('tabIndex', this.tabIndex);
-        }
-        this.initEvents();
-        //this.el.addClass([this.fieldClass, this.cls]);
-        
-    },
+
+ /*
+ * - LGPL
+ *
+ * element
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.Element
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Element class
+ * @cfg {String} html contents of the element
+ * @cfg {String} tag tag of the element
+ * @cfg {String} cls class of the element
+ * 
+ * @constructor
+ * Create a new Element
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.Element = function(config){
+    Roo.bootstrap.Element.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.Element, Roo.bootstrap.Component,  {
+    
+    tag: 'div',
+    cls: '',
+    html: '',
+    
+    
+    
     getAutoCreate : function(){
-        
-        return {
-            cls: "modal fade",
-            cn : [
-                {
-                    cls: "modal-dialog",
-                    cn : [
-                        {
-                            cls : "modal-content",
-                            cn : [
-                                {
-                                    cls : 'modal-header',
-                                    cn : [
-                                        {
-                                            tag: 'button',
-                                            cls : 'close',
-                                            html : '&times'
-                                        },
-                                        {
-                                            tag: 'h4',
-                                            cls : 'modal-title',
-                                            html : this.title
-                                        }
-                                    
-                                    ]
-                                },
-                                {
-                                    cls : 'modal-body'
-                                 
-                                },
-                                 {
-                                    cls : 'modal-footer'
-                                    /*
-                                    cn : [
-                                        {
-                                            tag: 'button',
-                                            cls : 'btn btn-default',
-                                            html : 'Close'
-                                        },
-                                        {
-                                            tag: 'button',
-                                            cls : 'btn btn-primary',
-                                            html : 'Save'
-                                        }
-                                    
-                                    ]
-                                    */
-                                }
-                                
-                                
-                            ]
-                            
-                        }
-                    ]
-                        
-                }
-            ]
-            
-            
-        };
-          
-    },
-    getChildContainer : function() {
-         
-         return this.el.select('.modal-body',true).first();
-        
-    },
-    getButtonContainer : function() {
-         return this.el.select('.modal-footer',true).first();
-        
-    },
-    initEvents : function()
-    {
-        this.el.select('.modal-header .close').on('click', this.hide, this);
-    },
-    show : function() {
-        this.el.addClass('on');
-        this.el.removeClass('fade');
-        this.el.setStyle('display', 'block');
-    },
-    hide : function() {
-        this.el.removeClass('on');
-        this.el.addClass('fade');
-        this.el.setStyle('display', 'none');
+        var cfg = Roo.apply({}, Roo.bootstrap.Element.superclass.getAutoCreate.call(this));
+       
+       cfg = {
+           tag: this.tag,
+           cls: '',
+            html: this.html
+       }
+       
+        return cfg;
     }
+   
 });
 
+
  /*
  * - LGPL
  *
- * navbar
+ * pagination
  * 
  */
 
 /**
- * @class Roo.bootstrap.Navbar
+ * @class Roo.bootstrap.Pagination
  * @extends Roo.bootstrap.Component
- * Bootstrap Navbar class
- * @cfg {Boolean} sidebar has side bar
- * @cfg {Boolean} bar is a bar?
- * @cfg {String} position (fixed-top|fixed-bottom|static-top) position
- * @cfg {String} brand what is brand
- * @cfg {Boolean} inverse is inverted color
- * @cfg {String} type (nav | pills | tabs)
- * @cfg {Boolean} arrangement stacked | justified
- * @cfg {String} align (left | right) alignment
- *
+ * Bootstrap Pagination class
+ * @cfg {String} size xs | sm | md | lg
+ * @cfg {Boolean} inverse false | true
+ * @cfg {Number} from pagination starting number
+ * @cfg {Number} to pagination ending number
+ * @cfg {String} align empty or left | right
+ * @cfg {Number} active active page number
  * 
  * @constructor
- * Create a new Navbar
+ * Create a new Pagination
  * @param {Object} config The config object
  */
 
-
-Roo.bootstrap.Navbar = function(config){
-    Roo.bootstrap.Navbar.superclass.constructor.call(this, config);
+Roo.bootstrap.Pagination = function(config){
+    Roo.bootstrap.Pagination.superclass.constructor.call(this, config);
 };
 
-Roo.extend(Roo.bootstrap.Navbar, Roo.bootstrap.Component,  {
-    
-    sidebar: false,
+Roo.extend(Roo.bootstrap.Pagination, Roo.bootstrap.Component,  {
     
-    bar: false,
-    brand: '',
+    cls: false,
+    size: false,
     inverse: false,
-    position: '',
-    align : false,
-    type: 'nav',
-    arrangement: '',
+    from: 1,
+    to: 4,
+    align: false,
+    active: 1,
     
     getAutoCreate : function(){
-        var cfg = {
-            cls : 'navbar'
+        cfg = {
+            tag: 'ul',
+                cls: 'pagination',
+                cn: []
         };
-       
-        if (this.sidebar === true) {
-            cfg = {
-                tag: 'div',
-                cls: 'sidebar-nav'
-            };
-            return cfg;
+        if (this.inverse) {
+            cfg.cls += ' inverse';
         }
-        
-        if (this.bar === true) {
-            cfg = {
-                tag: 'nav',
-                cls: 'navbar',
-                role: 'navigation',
-                cn: [
-                    {
-                        tag: 'div',
-                        cls: 'navbar-header',
-                        cn: [
-                            {
-                            tag: 'button',
-                            type: 'button',
-                            cls: 'navbar-toggle',
-                            'data-toggle': 'collapse',
-                            cn: [
-                                {
-                                    tag: 'span',
-                                    cls: 'sr-only',
-                                    html: 'Toggle navigation'
-                                },
-                                {
-                                    tag: 'span',
-                                    cls: 'icon-bar'
-                                },
-                                {
-                                    tag: 'span',
-                                    cls: 'icon-bar'
-                                },
-                                {
-                                    tag: 'span',
-                                    cls: 'icon-bar'
-                                }
-                            ]
-                            }
-                        ]
-                    },
-                    {
-                    tag: 'div',
-                    cls: 'collapse navbar-collapse'
-                    }
-                ]
-            };
-            
-            cfg.cls += this.inverse ? ' navbar-inverse' : ' navbar-default';
-            
-            if (['fixed-top','fixed-bottom','static-top'].indexOf(this.position)>-1) {
-            cfg.cls += ' navbar-' + this.position;
-            cfg.tag = this.position  == 'fixed-bottom' ? 'footer' : 'header';
-            }
-            
-            if (this.brand !== '') {
-                cfg.cn[0].cn.push({
+        if (this.html) {
+            cfg.html=this.html;
+        }
+        if (this.cls) {
+            cfg.cls=this.cls;
+        }
+        cfg.cn[0]={
+            tag: 'li',
+            cn: [
+                {
                     tag: 'a',
-                    href: '#',
-                    cls: 'navbar-brand',
+                    href:'#',
+                    html: '&laquo;'
+                }
+            ]
+        };
+        var from=this.from>0?this.from:1;
+        var to=this.to-from<=10?this.to:from+10;
+        var active=this.active>=from&&this.active<=to?this.active:null;
+        for (var i=from;i<=to;i++) {
+            cfg.cn.push(
+                {
+                    tag: 'li',
+                    cls: active===i?'active':'',
                     cn: [
-                    this.brand
+                        {
+                            tag: 'a',
+                            href: '#',
+                            html: i
+                        }
                     ]
-                });
-            }
-            
-            return cfg;
-        
-        } else if (this.bar === false) {
-            
-        } else {
-            Roo.log('Property \'bar\' in of Navbar must be either true or false')
+                }
+            );
         }
-       
-        cfg.cn = [
-            {
-                cls: 'nav',
-                tag : 'ul'
-            }
-        ];
         
-        if (['tabs','pills'].indexOf(this.type)!==-1) {
-            cfg.cn[0].cls += ' nav-' + this.type
-        } else {
-            if (this.type!=='nav') {
-            Roo.log('nav type must be nav/tabs/pills')
+        cfg.cn.push(
+            {
+                tag: 'li',
+                cn: [
+                    {
+                       tag: 'a',
+                       href: '#',
+                       html: '&raquo;'
+                    }
+                ]
             }
-            cfg.cn[0].cls += ' navbar-nav'
-        }
-        
-        if (['stacked','justified'].indexOf(this.arrangement)!==-1) {
-            cfg.cn[0].cls += ' nav-' + this.arrangement;
-        }
-        
-        if (this.align === 'right') {
-            cfg.cn[0].cls += ' navbar-right';
-        }
-        if (this.inverse) {
-            cfg.cls += ' navbar-inverse';
-            
-        }
-        
-        
+        );
+       
         return cfg;
-    },
-    
-    getChildContainer : function() {
-        if (this.bar === true) {
-            return this.el.select('.collapse',true).first();
-        }
-        console.log(this);
-        return this.el;
     }
    
 });
@@ -2023,133 +1786,89 @@ Roo.extend(Roo.bootstrap.Navbar, Roo.bootstrap.Component,  {
  /*
  * - LGPL
  *
- * nav group
+ * slider
  * 
  */
 
+
 /**
- * @class Roo.bootstrap.NavGroup
+ * @class Roo.bootstrap.Slider
  * @extends Roo.bootstrap.Component
- * Bootstrap NavGroup class
- * @cfg {String} align left | right
- * @cfg {Boolean} inverse false | true
- * 
+ * Bootstrap Slider class
+ *    
  * @constructor
- * Create a new nav group
+ * Create a new Slider
  * @param {Object} config The config object
  */
 
-Roo.bootstrap.NavGroup = function(config){
-    Roo.bootstrap.NavGroup.superclass.constructor.call(this, config);
+Roo.bootstrap.Slider = function(config){
+    Roo.bootstrap.Slider.superclass.constructor.call(this, config);
 };
 
-Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component,  {
-    
-    align: '',
-    inverse: false,
-    form: false,
+Roo.extend(Roo.bootstrap.Slider, Roo.bootstrap.Component,  {
     
     getAutoCreate : function(){
-        var cfg = Roo.apply({}, Roo.bootstrap.NavGroup.superclass.getAutoCreate.call(this));
-        
-        cfg = {
-            tag : 'ul',
-            cls: 'nav navbar-nav' 
-        }
-        
-        if (this.parent().sidebar === true) {
-            cfg = {
-                tag: 'ul',
-                cls: 'dashboard-menu'
-            }
-            
-            return cfg;
-        }
-        
-        if (this.form === true) {
-            cfg = {
-                tag: 'form',
-                cls: 'navbar-form'
-            }
-            
-            if (this.align === 'right') {
-                cfg.cls += ' navbar-right';
-            } else {
-                cfg.cls += ' navbar-left';
-            }
-        }
-        
-        
-        if (this.align === 'right') {
-            cfg.cls += ' navbar-right';
-        }
         
-        if (this.inverse) {
-            cfg.cls += ' navbar-inverse';
-            
+        var cfg = {
+            tag: 'div',
+            cls: 'slider slider-sample1 vertical-handler ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all',
+            cn: [
+                {
+                    tag: 'a',
+                    cls: 'ui-slider-handle ui-state-default ui-corner-all'
+                }
+            ]
         }
         
-        
         return cfg;
     }
    
 });
 
-
  /*
  * - LGPL
  *
- * row
+ * table
  * 
  */
+
 /**
- * @class Roo.bootstrap.Navbar.Button
+ * @class Roo.bootstrap.Table
  * @extends Roo.bootstrap.Component
- * Bootstrap Navbar.Button class
- * @cfg {String} href  link to
- * @cfg {String} html content of button
-    
+ * Bootstrap Table class
+ * 
  * @constructor
- * Create a new Navbar Button
+ * Create a new Table
  * @param {Object} config The config object
  */
 
-
-Roo.bootstrap.Navbar.Button = function(config){
-    Roo.bootstrap.Navbar.Button.superclass.constructor.call(this, config);
+Roo.bootstrap.Table = function(config){
+    Roo.bootstrap.Table.superclass.constructor.call(this, config);
 };
 
-Roo.extend(Roo.bootstrap.Navbar.Button, Roo.bootstrap.Component,  {
-    
-    href : false,
-    html : false,
+Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
     
-    autoCreate : {
-        cls: 'btn',
-        tag : 'button',
-        html: 'hello'
-    },
+    html: false,
+    cls: false,
     
     getAutoCreate : function(){
-        
-        var cfg = {
-            cls: 'btn',
-            tag : 'button',
-            html: 'hello',
-            cn : []
-            
-        } ;
-        cfg.cn.push({
-            html : this.html || ''
-            //href : this.
-             //       )
-        });
-        cfg.cn.push({
-            tag: 'span',
-            cls : 'carat'
-        });
-        
+        var cfg = Roo.apply({}, Roo.bootstrap.Table.superclass.getAutoCreate.call(this));
+       
+       cfg = {
+           tag: 'table',
+           cn: [
+               {
+                   tag: 'tbody'
+               }
+           ]
+       }
+        if (this.html) {
+            cfg.html=this.html
+        }
+        if (this.cls) {
+            cfg.cls=this.cls
+        }
+       
         return cfg;
     }
    
@@ -2160,492 +1879,863 @@ Roo.extend(Roo.bootstrap.Navbar.Button, Roo.bootstrap.Component,  {
  /*
  * - LGPL
  *
- * row
+ * table cell
  * 
  */
 
 /**
- * @class Roo.bootstrap.Navbar.Item
+ * @class Roo.bootstrap.TableCell
  * @extends Roo.bootstrap.Component
- * Bootstrap Navbar.Button class
- * @cfg {String} href  link to
- * @cfg {String} html content of button
- * @cfg {String} badge text inside badge
- * @cfg {String} glyphicon name of glyphicon
-  
+ * Bootstrap TableCell class
+ * 
  * @constructor
- * Create a new Navbar Button
+ * Create a new TableCell
  * @param {Object} config The config object
  */
-Roo.bootstrap.Navbar.Item = function(config){
-    Roo.bootstrap.Navbar.Item.superclass.constructor.call(this, config);
+
+Roo.bootstrap.TableCell = function(config){
+    Roo.bootstrap.TableCell.superclass.constructor.call(this, config);
 };
 
-Roo.extend(Roo.bootstrap.Navbar.Item, Roo.bootstrap.Component,  {
-    
-    href: false,
-    html: '',
-    badge: '',
-    icon: false,
-    glyphicon: false,
+Roo.extend(Roo.bootstrap.TableCell, Roo.bootstrap.Component,  {
     
     getAutoCreate : function(){
-        
-        var cfg = Roo.apply({}, Roo.bootstrap.Navbar.Item.superclass.getAutoCreate.call(this));
-       
-       if (this.parent().parent().sidebar === true) {
-           cfg = {
-               tag: 'li',
-               cls: '',
-               cn: [
-                   {
-                       tag: 'p',
-                       cls: ''
-                   }
-               ]
-           }
-           
-           if (this.html) {
-               cfg.cn[0].html = this.html;
-           }
-           
-           if (this.active) {
-               this.cls += ' active';
-           }
-           
-           if (this.menu) {
-               cfg.cn[0].cls += ' dropdown-toggle';
-               cfg.cn[0].html = (cfg.cn[0].html || this.html) + '<span class="glyphicon glyphicon-chevron-down"></span>';
-           }
-           
-           if (this.href) {
-               cfg.cn[0].tag = 'a',
-               cfg.cn[0].href = this.href;
-           }
-           
-           if (this.glyphicon) {
-               cfg.cn[0].html = '<i class="glyphicon glyphicon-'+this.glyphicon+'"></i><span>' + cfg.cn[0].html || this.html + '</span>'
-           }
-           
-           return cfg;
-       }
+        var cfg = Roo.apply({}, Roo.bootstrap.TableCell.superclass.getAutoCreate.call(this));
        
        cfg = {
-           tag: 'li'
+           tag: 'td'
        }
-       cfg.cn = [
-            {
-               tag: 'p',
-               html: 'Text'
-            }
-        ];
-        
-        if (this.glyphicon) {
-            if(cfg.html){cfg.html = ' ' + this.html};
-            cfg.cn=[
-                {
-                    tag: 'span',
-                    cls: 'glyphicon glyphicon-' + this.glyphicon
-                }
-            ];
+        if (this.html) {
+            cfg.html=this.html
+        }
+        if (this.cls) {
+            cfg.cls=this.cls
         }
        
-        cfg.cn[0].html = this.html || cfg.cn[0].html ;
-       if (this.menu) {
-           cfg.cn[0].tag='a';
-           cfg.cn[0].href='#';
-           cfg.cn[0].html += " <span class='caret'></span>";
-       //}else if (!this.href) {
-       //    cfg.cn[0].tag='p';
-       //    cfg.cn[0].cls='navbar-text';
-       } else {
-           cfg.cn[0].tag='a';
-           cfg.cn[0].href=this.href||'#';
-           cfg.cn[0].html=this.html;
-       }
+        return cfg;
+    }
+   
+});
+
+
+ /*
+ * - LGPL
+ *
+ * table row
+ * 
+ */
+
+/**
+ * @class Roo.bootstrap.TableRow
+ * @extends Roo.bootstrap.Component
+ * Bootstrap TableRow class
+ * 
+ * @constructor
+ * Create a new TableRow
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.TableRow = function(config){
+    Roo.bootstrap.TableRow.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.TableRow, Roo.bootstrap.Component,  {
+    
+    getAutoCreate : function(){
+        var cfg = Roo.apply({}, Roo.bootstrap.TableRow.superclass.getAutoCreate.call(this));
        
-       if (this.badge !== '') {
-           
-           cfg.cn[0].cn=[
-               cfg.cn[0].html + ' ',
-               {
-                   tag: 'span',
-                   cls: 'badge',
-                   html: this.badge
-               }
-           ];
-           cfg.cn[0].html=''
+       cfg = {
+           tag: 'tr'
        }
-        
        
         return cfg;
-    },
-    initEvents: function() {
-       // Roo.log('init events?');
-       // Roo.log(this.el.dom);
-        this.el.select('a',true).on('click',
-                function(e) {
-                    this.fireEvent('click', this);
-                },
-                this
-        );
     }
    
 });
+
  
 
  /*
  * - LGPL
  *
- * row
+ * form
  * 
  */
 
 /**
- * @class Roo.bootstrap.Row
+ * @class Roo.bootstrap.Form
  * @extends Roo.bootstrap.Component
- * Bootstrap Row class (contains columns...)
+ * Bootstrap Form class
+ * @cfg {String} method  GET | POST (default POST)
+ * @cfg {String} labelAlign top | left (default top)
  * 
  * @constructor
- * Create a new Row
+ * Create a new Form
  * @param {Object} config The config object
  */
 
-Roo.bootstrap.Row = function(config){
-    Roo.bootstrap.Row.superclass.constructor.call(this, config);
+
+Roo.bootstrap.Form = function(config){
+    Roo.bootstrap.Form.superclass.constructor.call(this, config);
+    this.addEvents({
+        /**
+         * @event clientvalidation
+         * If the monitorValid config option is true, this event fires repetitively to notify of valid state
+         * @param {Form} this
+         * @param {Boolean} valid true if the form has passed client-side validation
+         */
+        clientvalidation: true,
+        /**
+         * @event rendered
+         * Fires when the form is rendered
+         * @param {Roo.form.Form} form
+         */
+        rendered : true
+    });
 };
 
-Roo.extend(Roo.bootstrap.Row, Roo.bootstrap.Component,  {
+Roo.extend(Roo.bootstrap.Form, Roo.bootstrap.Component,  {
+      
     
-    autoCreate: {
-        cls: 'row clearfix'
+     getAutoCreate : function(){
+        
+        var cfg = {
+            tag: 'form',
+            method : this.method || 'POST',
+            id : this.id || Roo.id(),
+            cls : ''
+        }
+        
+        if (this.labelAlign == 'left' ) {
+            cfg.cls += ' form-horizontal';
+        }
+        return cfg;
     }
     
-    
 });
 
  
+/*
+ * Based on:
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ *
+ * Originally Released Under LGPL - original licence link has changed is not relivant.
+ *
+ * Fork - LGPL
+ * <script type="text/javascript">
+ */
+/**
+ * @class Roo.form.VTypes
+ * Overridable validation definitions. The validations provided are basic and intended to be easily customizable and extended.
+ * @singleton
+ */
+Roo.form.VTypes = function(){
+    // closure these in so they are only created once.
+    var alpha = /^[a-zA-Z_]+$/;
+    var alphanum = /^[a-zA-Z0-9_]+$/;
+    var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;
+    var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
+
+    // All these messages and functions are configurable
+    return {
+        /**
+         * The function used to validate email addresses
+         * @param {String} value The email address
+         */
+        'email' : function(v){
+            return email.test(v);
+        },
+        /**
+         * The error text to display when the email validation function returns false
+         * @type String
+         */
+        'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
+        /**
+         * The keystroke filter mask to be applied on email input
+         * @type RegExp
+         */
+        'emailMask' : /[a-z0-9_\.\-@]/i,
 
- /*
+        /**
+         * The function used to validate URLs
+         * @param {String} value The URL
+         */
+        'url' : function(v){
+            return url.test(v);
+        },
+        /**
+         * The error text to display when the url validation function returns false
+         * @type String
+         */
+        'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
+        
+        /**
+         * The function used to validate alpha values
+         * @param {String} value The value
+         */
+        'alpha' : function(v){
+            return alpha.test(v);
+        },
+        /**
+         * The error text to display when the alpha validation function returns false
+         * @type String
+         */
+        'alphaText' : 'This field should only contain letters and _',
+        /**
+         * The keystroke filter mask to be applied on alpha input
+         * @type RegExp
+         */
+        'alphaMask' : /[a-z_]/i,
+
+        /**
+         * The function used to validate alphanumeric values
+         * @param {String} value The value
+         */
+        'alphanum' : function(v){
+            return alphanum.test(v);
+        },
+        /**
+         * The error text to display when the alphanumeric validation function returns false
+         * @type String
+         */
+        'alphanumText' : 'This field should only contain letters, numbers and _',
+        /**
+         * The keystroke filter mask to be applied on alphanumeric input
+         * @type RegExp
+         */
+        'alphanumMask' : /[a-z0-9_]/i
+    };
+}();/*
  * - LGPL
  *
- * element
+ * Input
  * 
  */
 
 /**
- * @class Roo.bootstrap.Element
+ * @class Roo.bootstrap.Input
  * @extends Roo.bootstrap.Component
- * Bootstrap Element class
- * @cfg {String} html contents of the element
- * @cfg {String} tag tag of the element
- * @cfg {String} cls class of the element
+ * Bootstrap Input class
+ * @cfg {Boolean} disabled is it disabled
+ * @cfg {String} fieldLabel - the label associated
+ * @cfg {String} inputType button | checkbox | email | file | hidden | image | number | password | radio | range | reset | search | submit | text
+ * @cfg {String} name name of the input
+ * @cfg {string} fieldLabel - the label associated
+ * @cfg {string}  inputType - input / file submit ...
+ * @cfg {string} placeholder - placeholder to put in text.
+ * @cfg {string}  before - input group add on before
+ * @cfg {string} after - input group add on after
+ * 
  * 
  * @constructor
- * Create a new Element
+ * Create a new Input
  * @param {Object} config The config object
  */
 
-Roo.bootstrap.Element = function(config){
-    Roo.bootstrap.Element.superclass.constructor.call(this, config);
+Roo.bootstrap.Input = function(config){
+    Roo.bootstrap.Input.superclass.constructor.call(this, config);
+   
+        this.addEvents({
+            /**
+             * @event focus
+             * Fires when this field receives input focus.
+             * @param {Roo.form.Field} this
+             */
+            focus : true,
+            /**
+             * @event blur
+             * Fires when this field loses input focus.
+             * @param {Roo.form.Field} this
+             */
+            blur : true,
+            /**
+             * @event specialkey
+             * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed.  You can check
+             * {@link Roo.EventObject#getKey} to determine which key was pressed.
+             * @param {Roo.form.Field} this
+             * @param {Roo.EventObject} e The event object
+             */
+            specialkey : true,
+            /**
+             * @event change
+             * Fires just before the field blurs if the field value has changed.
+             * @param {Roo.form.Field} this
+             * @param {Mixed} newValue The new value
+             * @param {Mixed} oldValue The original value
+             */
+            change : true,
+            /**
+             * @event invalid
+             * Fires after the field has been marked as invalid.
+             * @param {Roo.form.Field} this
+             * @param {String} msg The validation message
+             */
+            invalid : true,
+            /**
+             * @event valid
+             * Fires after the field has been validated with no errors.
+             * @param {Roo.form.Field} this
+             */
+            valid : true,
+             /**
+             * @event keyup
+             * Fires after the key up
+             * @param {Roo.form.Field} this
+             * @param {Roo.EventObject}  e The event Object
+             */
+            keyup : true
+        });
 };
 
-Roo.extend(Roo.bootstrap.Element, Roo.bootstrap.Component,  {
-    
-    tag: 'div',
-    cls: '',
-    html: '',
+Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
+     /**
+     * @cfg {String/Boolean} validationEvent The event that should initiate field validation. Set to false to disable
+      automatic validation (defaults to "keyup").
+     */
+    validationEvent : "keyup",
+     /**
+     * @cfg {Boolean} validateOnBlur Whether the field should validate when it loses focus (defaults to true).
+     */
+    validateOnBlur : true,
+    /**
+     * @cfg {Number} validationDelay The length of time in milliseconds after user input begins until validation is initiated (defaults to 250)
+     */
+    validationDelay : 250,
+     /**
+     * @cfg {String} focusClass The CSS class to use when the field receives focus (defaults to "x-form-focus")
+     */
+    focusClass : "x-form-focus",  // not needed???
+    
+       
+    /**
+     * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to "x-form-invalid")
+     */
+    invalidClass : "has-error",
+    
+    /**
+     * @cfg {Boolean} selectOnFocus True to automatically select any existing field text when the field receives input focus (defaults to false)
+     */
+    selectOnFocus : false,
+    
+     /**
+     * @cfg {String} maskRe An input mask regular expression that will be used to filter keystrokes that don't match (defaults to null)
+     */
+    maskRe : null,
+       /**
+     * @cfg {String} vtype A validation type name as defined in {@link Roo.form.VTypes} (defaults to null)
+     */
+    vtype : null,
+    
+      /**
+     * @cfg {Boolean} disableKeyFilter True to disable input keystroke filtering (defaults to false)
+     */
+    disableKeyFilter : false,
+    
+       /**
+     * @cfg {Boolean} disabled True to disable the field (defaults to false).
+     */
+    disabled : false,
+     /**
+     * @cfg {Boolean} allowBlank False to validate that the value length > 0 (defaults to true)
+     */
+    allowBlank : true,
+    /**
+     * @cfg {String} blankText Error text to display if the allow blank validation fails (defaults to "This field is required")
+     */
+    blankText : "This field is required",
+    
+     /**
+     * @cfg {Number} minLength Minimum input field length required (defaults to 0)
+     */
+    minLength : 0,
+    /**
+     * @cfg {Number} maxLength Maximum input field length allowed (defaults to Number.MAX_VALUE)
+     */
+    maxLength : Number.MAX_VALUE,
+    /**
+     * @cfg {String} minLengthText Error text to display if the minimum length validation fails (defaults to "The minimum length for this field is {minLength}")
+     */
+    minLengthText : "The minimum length for this field is {0}",
+    /**
+     * @cfg {String} maxLengthText Error text to display if the maximum length validation fails (defaults to "The maximum length for this field is {maxLength}")
+     */
+    maxLengthText : "The maximum length for this field is {0}",
+  
+    
+    /**
+     * @cfg {Function} validator A custom validation function to be called during field validation (defaults to null).
+     * If available, this function will be called only after the basic validators all return true, and will be passed the
+     * current field value and expected to return boolean true if the value is valid or a string error message if invalid.
+     */
+    validator : null,
+    /**
+     * @cfg {RegExp} regex A JavaScript RegExp object to be tested against the field value during validation (defaults to null).
+     * If available, this regex will be evaluated only after the basic validators all return true, and will be passed the
+     * current field value.  If the test fails, the field will be marked invalid using {@link #regexText}.
+     */
+    regex : null,
+    /**
+     * @cfg {String} regexText The error text to display if {@link #regex} is used and the test fails during validation (defaults to "")
+     */
+    regexText : "",
+    
+    
+    
+    fieldLabel : '',
+    inputType : 'text',
+    
+    name : false,
+    placeholder: false,
+    before : false,
+    after : false,
+    
+    // private
+    hasFocus : false,
+    preventMark: false,
+    
+    getAutoCreate : function(){
+        
+        var parent = this.parent();
+        
+        var align = parent.labelAlign;
+        
+        var id = Roo.id();
+        
+        var cfg = {
+            cls: 'form-group' //input-group
+        };
+        
+        var input =  {
+            tag: 'input',
+            id : id,
+            type : this.inputType,
+            cls : 'form-control',
+            placeholder : this.placeholder || '' 
+            
+        };
+        if (this.name) {
+            input.name = name;
+        }
+        
+        var inputblock = input;
+        
+        if (this.before || this.after) {
+            
+            inputblock = {
+                cls : 'input-group',
+                cn :  [] 
+            };
+            if (this.before) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon',
+                    html : this.before
+                });
+            }
+            inputblock.cn.push(input);
+            if (this.after) {
+                inputblock.cn.push({
+                    tag :'span',
+                    cls : 'input-group-addon',
+                    html : this.after
+                });
+            }
+            
+        }
+        
+        Roo.log(align);
+        Roo.log(this.fieldLabel.length);
+        
+        if (align ==='left' && this.fieldLabel.length) {
+                Roo.log("left and has label");
+                cfg.cn = [
+                    
+                    {
+                        tag: 'label',
+                        'for' :  id,
+                        cls : 'col-sm-2 control-label',
+                        html : this.fieldLabel
+                        
+                    },
+                    {
+                        cls : "col-sm-10", 
+                        cn: [
+                            inputblock
+                        ]
+                    }
+                    
+                ];
+        } else if ( this.fieldLabel.length) {
+                Roo.log(" label");
+                 cfg.cn = [
+                   
+                    {
+                        tag: 'label',
+                        //cls : 'input-group-addon',
+                        html : this.fieldLabel
+                        
+                    },
+                    
+                    inputblock
+                    
+                ];
+
+        } else {
+            
+                   Roo.log(" no label && no align");
+                cfg.cn = [
+                    
+                        inputblock
+                    
+                ];
+                
+                
+        }
+         
+        
+        
+        
+        if (this.disabled) {
+            input.disabled=true;
+        }
+        return cfg;
+        
+    },
+    /**
+     * return the real input element.
+     */
+    inputEl: function ()
+    {
+        return this.el.select('input.form-control',true).first();
+    },
+    setDisabled : function(v)
+    {
+        var i  = this.inputEl().dom;
+        if (v) {
+            i.removeAttribute('disabled');
+            return;
+            
+        }
+        i.setAttribute('disabled','true');
+    },
+    initEvents : function()
+    {
+        
+        this.inputEl().on("keydown" , this.fireKey,  this);
+        this.inputEl().on("focus", this.onFocus,  this);
+        this.inputEl().on("blur", this.onBlur,  this);
+        this.inputEl().relayEvent('keyup', this);
+
+        // reference to original value for reset
+        this.originalValue = this.getValue();
+        //Roo.form.TextField.superclass.initEvents.call(this);
+        if(this.validationEvent == 'keyup'){
+            this.validationTask = new Roo.util.DelayedTask(this.validate, this);
+            this.inputEl().on('keyup', this.filterValidation, this);
+        }
+        else if(this.validationEvent !== false){
+            this.inputEl().on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
+        }
+        
+        if(this.selectOnFocus){
+            this.on("focus", this.preFocus, this);
+            
+        }
+        if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Roo.form.VTypes[this.vtype+'Mask']))){
+            this.inputEl().on("keypress", this.filterKeys, this);
+        }
+       /* if(this.grow){
+            this.el.on("keyup", this.onKeyUp,  this, {buffer:50});
+            this.el.on("click", this.autoSize,  this);
+        }
+        */
+        if(this.inputEl().is('input[type=password]') && Roo.isSafari){
+            this.inputEl().on('keydown', this.SafariOnKeyDown, this);
+        }
+        
+    },
+    filterValidation : function(e){
+        if(!e.isNavKeyPress()){
+            this.validationTask.delay(this.validationDelay);
+        }
+    },
+     /**
+     * Validates the field value
+     * @return {Boolean} True if the value is valid, else false
+     */
+    validate : function(){
+        //if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
+        if(this.disabled || this.validateValue(this.getRawValue())){
+            this.clearInvalid();
+            return true;
+        }
+        return false;
+    },
+    
+    
+    /**
+     * Validates a value according to the field's validation rules and marks the field as invalid
+     * if the validation fails
+     * @param {Mixed} value The value to validate
+     * @return {Boolean} True if the value is valid, else false
+     */
+    validateValue : function(value){
+        if(value.length < 1)  { // if it's blank
+             if(this.allowBlank){
+                this.clearInvalid();
+                return true;
+             }else{
+                this.markInvalid(this.blankText);
+                return false;
+             }
+        }
+        if(value.length < this.minLength){
+            this.markInvalid(String.format(this.minLengthText, this.minLength));
+            return false;
+        }
+        if(value.length > this.maxLength){
+            this.markInvalid(String.format(this.maxLengthText, this.maxLength));
+            return false;
+        }
+        if(this.vtype){
+            var vt = Roo.form.VTypes;
+            if(!vt[this.vtype](value, this)){
+                this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
+                return false;
+            }
+        }
+        if(typeof this.validator == "function"){
+            var msg = this.validator(value);
+            if(msg !== true){
+                this.markInvalid(msg);
+                return false;
+            }
+        }
+        if(this.regex && !this.regex.test(value)){
+            this.markInvalid(this.regexText);
+            return false;
+        }
+        return true;
+    },
+
     
     
+     // private
+    fireKey : function(e){
+        //Roo.log('field ' + e.getKey());
+        if(e.isNavKeyPress()){
+            this.fireEvent("specialkey", this, e);
+        }
+    },
+    onFocus : function(){
+        if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
+           // this.el.addClass(this.focusClass);
+        }
+        if(!this.hasFocus){
+            this.hasFocus = true;
+            this.startValue = this.getValue();
+            this.fireEvent("focus", this);
+        }
+    },
     
-    getAutoCreate : function(){
-        var cfg = Roo.apply({}, Roo.bootstrap.Element.superclass.getAutoCreate.call(this));
-       
-       cfg = {
-           tag: this.tag,
-           cls: '',
-            html: this.html
-       }
-       
-        return cfg;
-    }
-   
-});
-
-
- /*
- * - LGPL
- *
- * pagination
- * 
- */
-
-/**
- * @class Roo.bootstrap.Pagination
- * @extends Roo.bootstrap.Component
- * Bootstrap Pagination class
- * @cfg {String} size xs | sm | md | lg
- * @cfg {Boolean} inverse false | true
- * @cfg {Number} from pagination starting number
- * @cfg {Number} to pagination ending number
- * @cfg {String} align empty or left | right
- * @cfg {Number} active active page number
- * 
- * @constructor
- * Create a new Pagination
- * @param {Object} config The config object
- */
-
-Roo.bootstrap.Pagination = function(config){
-    Roo.bootstrap.Pagination.superclass.constructor.call(this, config);
-};
+    beforeBlur : Roo.emptyFn,
 
-Roo.extend(Roo.bootstrap.Pagination, Roo.bootstrap.Component,  {
     
-    cls: false,
-    size: false,
-    inverse: false,
-    from: 1,
-    to: 4,
-    align: false,
-    active: 1,
+    // private
+    onBlur : function(){
+        this.beforeBlur();
+        if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
+            //this.el.removeClass(this.focusClass);
+        }
+        this.hasFocus = false;
+        if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
+            this.validate();
+        }
+        var v = this.getValue();
+        if(String(v) !== String(this.startValue)){
+            this.fireEvent('change', this, v, this.startValue);
+        }
+        this.fireEvent("blur", this);
+    },
+     /**
+     * Returns the normalized data value (undefined or emptyText will be returned as '').  To return the raw value see {@link #getRawValue}.
+     * @return {Mixed} value The field value
+     */
+    getValue : function(){
+        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}.
+     * @return {Mixed} value The field value
+     */
+    getRawValue : function(){
+        var v = this.inputEl().getValue();
+        
+        return v;
+    },
+    /**
+     * Sets a data value into the field and validates it.  To set the value directly without validation see {@link #setRawValue}.
+     * @param {Mixed} value The value to set
+     */
+    setValue : function(v){
+        this.value = v;
+        if(this.rendered){
+            this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
+            this.validate();
+        }
+    },
     
-    getAutoCreate : function(){
-        cfg = {
-            tag: 'ul',
-                cls: 'pagination',
-                cn: []
-        };
-        if (this.inverse) {
-            cfg.cls += ' inverse';
+    /*
+    processValue : function(value){
+        if(this.stripCharsRe){
+            var newValue = value.replace(this.stripCharsRe, '');
+            if(newValue !== value){
+                this.setRawValue(newValue);
+                return newValue;
+            }
         }
-        if (this.html) {
-            cfg.html=this.html;
+        return value;
+    },
+  */
+    preFocus : function(){
+        
+        if(this.selectOnFocus){
+            this.inputEl().dom.select();
         }
-        if (this.cls) {
-            cfg.cls=this.cls;
+    },
+    filterKeys : function(e){
+        var k = e.getKey();
+        if(!Roo.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
+            return;
         }
-        cfg.cn[0]={
-            tag: 'li',
-            cn: [
-                {
-                    tag: 'a',
-                    href:'#',
-                    html: '&laquo;'
+        var c = e.getCharCode(), cc = String.fromCharCode(c);
+        if(Roo.isIE && (e.isSpecialKey() || !cc)){
+            return;
+        }
+        if(!this.maskRe.test(cc)){
+            e.stopEvent();
+        }
+    },
+     /**
+     * Clear any invalid styles/messages for this field
+     */
+    clearInvalid : function(){
+        
+        if(!this.el || this.preventMark){ // not rendered
+            return;
+        }
+        this.el.removeClass(this.invalidClass);
+        /*
+        switch(this.msgTarget){
+            case 'qtip':
+                this.el.dom.qtip = '';
+                break;
+            case 'title':
+                this.el.dom.title = '';
+                break;
+            case 'under':
+                if(this.errorEl){
+                    Roo.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
+                }
+                break;
+            case 'side':
+                if(this.errorIcon){
+                    this.errorIcon.dom.qtip = '';
+                    this.errorIcon.hide();
+                    this.un('resize', this.alignErrorIcon, this);
+                }
+                break;
+            default:
+                var t = Roo.getDom(this.msgTarget);
+                t.innerHTML = '';
+                t.style.display = 'none';
+                break;
+        }
+        */
+        this.fireEvent('valid', this);
+    },
+     /**
+     * Mark this field as invalid
+     * @param {String} msg The validation message
+     */
+    markInvalid : function(msg){
+        if(!this.el  || this.preventMark){ // not rendered
+            return;
+        }
+        this.el.addClass(this.invalidClass);
+        /*
+        msg = msg || this.invalidText;
+        switch(this.msgTarget){
+            case 'qtip':
+                this.el.dom.qtip = msg;
+                this.el.dom.qclass = 'x-form-invalid-tip';
+                if(Roo.QuickTips){ // fix for floating editors interacting with DND
+                    Roo.QuickTips.enable();
                 }
-            ]
-        };
-        var from=this.from>0?this.from:1;
-        var to=this.to-from<=10?this.to:from+10;
-        var active=this.active>=from&&this.active<=to?this.active:null;
-        for (var i=from;i<=to;i++) {
-            cfg.cn.push(
-                {
-                    tag: 'li',
-                    cls: active===i?'active':'',
-                    cn: [
-                        {
-                            tag: 'a',
-                            href: '#',
-                            html: i
-                        }
-                    ]
+                break;
+            case 'title':
+                this.el.dom.title = msg;
+                break;
+            case 'under':
+                if(!this.errorEl){
+                    var elp = this.el.findParent('.x-form-element', 5, true);
+                    this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
+                    this.errorEl.setWidth(elp.getWidth(true)-20);
                 }
-            );
-        }
-        
-        cfg.cn.push(
-            {
-                tag: 'li',
-                cn: [
-                    {
-                       tag: 'a',
-                       href: '#',
-                       html: '&raquo;'
-                    }
-                ]
-            }
-        );
-       
-        return cfg;
-    }
-   
-});
-
-
- /*
- * - LGPL
- *
- * slider
- * 
- */
-
-
-/**
- * @class Roo.bootstrap.Slider
- * @extends Roo.bootstrap.Component
- * Bootstrap Slider class
- *    
- * @constructor
- * Create a new Slider
- * @param {Object} config The config object
- */
-
-Roo.bootstrap.Slider = function(config){
-    Roo.bootstrap.Slider.superclass.constructor.call(this, config);
-};
-
-Roo.extend(Roo.bootstrap.Slider, Roo.bootstrap.Component,  {
-    
-    getAutoCreate : function(){
-        
-        var cfg = {
-            tag: 'div',
-            cls: 'slider slider-sample1 vertical-handler ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all',
-            cn: [
-                {
-                    tag: 'a',
-                    cls: 'ui-slider-handle ui-state-default ui-corner-all'
+                this.errorEl.update(msg);
+                Roo.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
+                break;
+            case 'side':
+                if(!this.errorIcon){
+                    var elp = this.el.findParent('.x-form-element', 5, true);
+                    this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
                 }
-            ]
+                this.alignErrorIcon();
+                this.errorIcon.dom.qtip = msg;
+                this.errorIcon.dom.qclass = 'x-form-invalid-tip';
+                this.errorIcon.show();
+                this.on('resize', this.alignErrorIcon, this);
+                break;
+            default:
+                var t = Roo.getDom(this.msgTarget);
+                t.innerHTML = msg;
+                t.style.display = this.msgDisplay;
+                break;
         }
+        */
+        this.fireEvent('invalid', this, msg);
+    },
+    // private
+    SafariOnKeyDown : function(event)
+    {
+        // this is a workaround for a password hang bug on chrome/ webkit.
         
-        return cfg;
-    }
-   
-});
-
- /*
- * - LGPL
- *
- * table
- * 
- */
-
-/**
- * @class Roo.bootstrap.Table
- * @extends Roo.bootstrap.Component
- * Bootstrap Table class
- * 
- * @constructor
- * Create a new Table
- * @param {Object} config The config object
- */
-
-Roo.bootstrap.Table = function(config){
-    Roo.bootstrap.Table.superclass.constructor.call(this, config);
-};
-
-Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
-    
-    html: false,
-    cls: false,
-    
-    getAutoCreate : function(){
-        var cfg = Roo.apply({}, Roo.bootstrap.Table.superclass.getAutoCreate.call(this));
-       
-       cfg = {
-           tag: 'table',
-           cn: [
-               {
-                   tag: 'tbody'
-               }
-           ]
-       }
-        if (this.html) {
-            cfg.html=this.html
-        }
-        if (this.cls) {
-            cfg.cls=this.cls
+        var isSelectAll = false;
+        
+        if(this.inputEl().dom.selectionEnd > 0){
+            isSelectAll = (this.inputEl().dom.selectionEnd - this.inputEl().dom.selectionStart - this.getValue().length == 0) ? true : false;
         }
-       
-        return cfg;
-    }
-   
-});
-
-
- /*
- * - LGPL
- *
- * table cell
- * 
- */
-
-/**
- * @class Roo.bootstrap.TableCell
- * @extends Roo.bootstrap.Component
- * Bootstrap TableCell class
- * 
- * @constructor
- * Create a new TableCell
- * @param {Object} config The config object
- */
-
-Roo.bootstrap.TableCell = function(config){
-    Roo.bootstrap.TableCell.superclass.constructor.call(this, config);
-};
-
-Roo.extend(Roo.bootstrap.TableCell, Roo.bootstrap.Component,  {
-    
-    getAutoCreate : function(){
-        var cfg = Roo.apply({}, Roo.bootstrap.TableCell.superclass.getAutoCreate.call(this));
-       
-       cfg = {
-           tag: 'td'
-       }
-        if (this.html) {
-            cfg.html=this.html
+        if(((event.getKey() == 8 || event.getKey() == 46) && this.getValue().length ==1)){ // backspace and delete key
+            event.preventDefault();
+            this.setValue('');
+            return;
         }
-        if (this.cls) {
-            cfg.cls=this.cls
+        
+        if(isSelectAll){ // backspace and delete key
+            
+            event.preventDefault();
+            // this is very hacky as keydown always get's upper case.
+            //
+            var cc = String.fromCharCode(event.getCharCode());
+            this.setValue( event.shiftKey ?  cc : cc.toLowerCase());
+            
         }
-       
-        return cfg;
-    }
-   
-});
-
-
- /*
- * - LGPL
- *
- * table row
- * 
- */
-
-/**
- * @class Roo.bootstrap.TableRow
- * @extends Roo.bootstrap.Component
- * Bootstrap TableRow class
- * 
- * @constructor
- * Create a new TableRow
- * @param {Object} config The config object
- */
-
-Roo.bootstrap.TableRow = function(config){
-    Roo.bootstrap.TableRow.superclass.constructor.call(this, config);
-};
-
-Roo.extend(Roo.bootstrap.TableRow, Roo.bootstrap.Component,  {
-    
-    getAutoCreate : function(){
-        var cfg = Roo.apply({}, Roo.bootstrap.TableRow.superclass.getAutoCreate.call(this));
-       
-       cfg = {
-           tag: 'tr'
-       }
-       
-        return cfg;
+        
+        
     }
-   
 });
 
  
-
\ No newline at end of file
index cff2bca..aece006 100644 (file)
@@ -19,20 +19,9 @@ Roo.bootstrap.Column=function(A){Roo.bootstrap.Column.superclass.constructor.cal
 Roo.bootstrap.Container=function(A){Roo.bootstrap.Container.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Container,Roo.bootstrap.Component,{jumbotron:false,well:'',panel:'',header:'',footer:'',sticky:'',getChildContainer:function(){if(this.panel.length){return this.el.select('.panel-body',true).first();}return this.el;},getAutoCreate:function(){var A={html:'',cls:''};if(this.jumbotron){A.cls='jumbotron';}if(this.cls){A.cls=this.cls+'';}if(this.sticky.length){var bd=Roo.get(document.body);if(!bd.hasClass('bootstrap-sticky')){bd.addClass('bootstrap-sticky');Roo.select('html',true).setStyle('height','100%');}
 A.cls+='bootstrap-sticky-'+this.sticky;}if(this.well.length){switch(this.well){case 'lg':case 'sm':A.cls+=' well well-'+this.well;break;default:A.cls+=' well';break;}}var B=A;if(this.panel.length){A.cls+='panel panel-'+this.panel;A.cn=[];if(this.header.length){A.cn.push({cls:'panel-heading',cn:[{tag:'h3',cls:'panel-title',html:this.header}]});}
 B=false;A.cn.push({cls:'panel-body',html:this.html});if(this.footer.length){A.cn.push({cls:'panel-footer',html:this.footer});}}if(B){B.html=this.html||A.html;}if(!A.cls.length){A.cls='container';}return A;}});
-//Roo/bootstrap/Form.js
-Roo.bootstrap.Form=function(A){Roo.bootstrap.Form.superclass.constructor.call(this,A);this.addEvents({clientvalidation:true,rendered:true});};Roo.extend(Roo.bootstrap.Form,Roo.bootstrap.Component,{getAutoCreate:function(){var A={tag:'form',method:this.method||'POST',id:this.id||Roo.id(),cls:''};if(this.labelAlign=='left'){A.cls+=' form-horizontal';}return A;}});
 //Roo/bootstrap/Img.js
 Roo.bootstrap.Img=function(A){Roo.bootstrap.Img.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Img,Roo.bootstrap.Component,{imgResponsive:true,border:'',src:'',getAutoCreate:function(){cfg={tag:'img',cls:'img-responsive',html:null}
 cfg.html=this.html||cfg.html;cfg.src=this.src||cfg.src;if(['rounded','circle','thumbnail'].indexOf(this.border)>-1){cfg.cls+=' img-'+this.border;}if(this.alt){cfg.alt=this.alt;}return cfg;}});
-//Roo/bootstrap/Input.js
-Roo.bootstrap.Input=function(A){Roo.bootstrap.Input.superclass.constructor.call(this,A);this.addEvents({focus:true,blur:true,specialkey:true,change:true,invalid:true,valid:true,keyup:true});};Roo.extend(Roo.bootstrap.Input,Roo.bootstrap.Component,{validationEvent:"keyup",validateOnBlur:true,validationDelay:250,focusClass:"x-form-focus",invalidClass:"has-error",selectOnFocus:false,maskRe:null,vtype:null,disableKeyFilter:false,disabled:false,allowBlank:true,blankText:"This field is required",minLength:0,maxLength:Number.MAX_VALUE,minLengthText:"The minimum length for this field is {0}",maxLengthText:"The maximum length for this field is {0}",validator:null,regex:null,regexText:"",fieldLabel:'',inputType:'text',name:false,placeholder:false,before:false,after:false,hasFocus:false,preventMark:false,getAutoCreate:function(){var A=this.parent();var B=A.labelAlign;var id=Roo.id();var C={cls:'form-group'};var D={tag:'input',id:id,type:this.inputType,cls:'form-control',placeholder:this.placeholder||''};if(this.name){D.name=name;}var E=D;if(this.before||this.after){E={cls:'input-group',cn:[]};if(this.before){E.cn.push({tag:'span',cls:'input-group-addon',html:this.before});}
-E.cn.push(D);if(this.after){E.cn.push({tag:'span',cls:'input-group-addon',html:this.after});}}
-Roo.log(B);Roo.log(this.fieldLabel.length);if(B==='left'&&this.fieldLabel.length){Roo.log("left and has label");C.cn=[{tag:'label','for':id,cls:'col-sm-2 control-label',html:this.fieldLabel},{cls:"col-sm-10",cn:[E]}];}else if(this.fieldLabel.length){Roo.log(" label");C.cn=[{tag:'label',html:this.fieldLabel},E];}else {Roo.log(" no label && no align");C.cn=[E];}if(this.disabled){D.disabled=true;}return C;},inputEl:function(){return this.el.select('input.form-control',true).first();},setDisabled:function(v){var i=this.inputEl().dom;if(v){i.removeAttribute('disabled');return;}
-i.setAttribute('disabled','true');},initEvents:function(){this.inputEl().on("keydown",this.fireKey,this);this.inputEl().on("focus",this.onFocus,this);this.inputEl().on("blur",this.onBlur,this);this.inputEl().relayEvent('keyup',this);this.originalValue=this.getValue();if(this.validationEvent=='keyup'){this.validationTask=new Roo.util.DelayedTask(this.validate,this);this.inputEl().on('keyup',this.filterValidation,this);}else if(this.validationEvent!==false){this.inputEl().on(this.validationEvent,this.validate,this,{buffer:this.validationDelay});}if(this.selectOnFocus){this.on("focus",this.preFocus,this);}if(this.maskRe||(this.vtype&&this.disableKeyFilter!==true&&(this.maskRe=Roo.form.VTypes[this.vtype+'Mask']))){this.inputEl().on("keypress",this.filterKeys,this);}if(this.inputEl().is('input[type=password]')&&Roo.isSafari){this.inputEl().on('keydown',this.SafariOnKeyDown,this);}},filterValidation:function(e){if(!e.isNavKeyPress()){this.validationTask.delay(this.validationDelay);}},validate:function(){if(this.disabled||this.validateValue(this.getRawValue())){this.clearInvalid();return true;}return false;},validateValue:function(A){if(A.length<1){if(this.allowBlank){this.clearInvalid();return true;}else {this.markInvalid(this.blankText);return false;}}if(A.length<this.minLength){this.markInvalid(String.format(this.minLengthText,this.minLength));return false;}if(A.length>this.maxLength){this.markInvalid(String.format(this.maxLengthText,this.maxLength));return false;}if(this.vtype){var vt=Roo.form.VTypes;if(!vt[this.vtype](A,this)){this.markInvalid(this.vtypeText||vt[this.vtype+'Text']);return false;}}if(typeof this.validator=="function"){var B=this.validator(A);if(B!==true){this.markInvalid(B);return false;}}if(this.regex&&!this.regex.test(A)){this.markInvalid(this.regexText);return false;}return true;},fireKey:function(e){if(e.isNavKeyPress()){this.fireEvent("specialkey",this,e);}},onFocus:function(){if(!Roo.isOpera&&this.focusClass){}if(!this.hasFocus){this.hasFocus=true;this.startValue=this.getValue();this.fireEvent("focus",this);}},beforeBlur:Roo.emptyFn,onBlur:function(){this.beforeBlur();if(!Roo.isOpera&&this.focusClass){}
-this.hasFocus=false;if(this.validationEvent!==false&&this.validateOnBlur&&this.validationEvent!="blur"){this.validate();}var v=this.getValue();if(String(v)!==String(this.startValue)){this.fireEvent('change',this,v,this.startValue);}
-this.fireEvent("blur",this);},getValue:function(){var v=this.inputEl().getValue();return v;},getRawValue:function(){var v=this.inputEl().getValue();return v;},setValue:function(v){this.value=v;if(this.rendered){this.inputEl().dom.value=(v===null||v===undefined?'':v);this.validate();}},preFocus:function(){if(this.selectOnFocus){this.inputEl().dom.select();}},filterKeys:function(e){var k=e.getKey();if(!Roo.isIE&&(e.isNavKeyPress()||k==e.BACKSPACE||(k==e.DELETE &&e.button==-1))){return;}var c=e.getCharCode(),cc=String.fromCharCode(c);if(Roo.isIE&&(e.isSpecialKey()||!cc)){return;}if(!this.maskRe.test(cc)){e.stopEvent();}},clearInvalid:function(){if(!this.el||this.preventMark){return;}
-this.el.removeClass(this.invalidClass);this.fireEvent('valid',this);},markInvalid:function(A){if(!this.el||this.preventMark){return;}
-this.el.addClass(this.invalidClass);this.fireEvent('invalid',this,A);},SafariOnKeyDown:function(A){var B=false;if(this.inputEl().dom.selectionEnd>0){B=(this.inputEl().dom.selectionEnd-this.inputEl().dom.selectionStart-this.getValue().length==0)?true:false;}if(((A.getKey()==8||A.getKey()==46)&&this.getValue().length==1)){A.preventDefault();this.setValue('');return;}if(B){A.preventDefault();var cc=String.fromCharCode(A.getCharCode());this.setValue(A.shiftKey?cc:cc.toLowerCase());}}});
 //Roo/bootstrap/Header.js
 Roo.bootstrap.Header=function(A){Roo.bootstrap.Header.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.Header,Roo.bootstrap.Component,{html:false,level:1,getAutoCreate:function(){var A={tag:'h'+(1*this.level),html:this.html||'fill in html'};return A;}});
 //Roo/bootstrap/Menu.js
@@ -76,3 +65,16 @@ Roo.bootstrap.Table=function(A){Roo.bootstrap.Table.superclass.constructor.call(
 Roo.bootstrap.TableCell=function(A){Roo.bootstrap.TableCell.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.TableCell,Roo.bootstrap.Component,{getAutoCreate:function(){var A=Roo.apply({},Roo.bootstrap.TableCell.superclass.getAutoCreate.call(this));A={tag:'td'};if(this.html){A.html=this.html}if(this.cls){A.cls=this.cls}return A;}});
 //Roo/bootstrap/TableRow.js
 Roo.bootstrap.TableRow=function(A){Roo.bootstrap.TableRow.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.TableRow,Roo.bootstrap.Component,{getAutoCreate:function(){var A=Roo.apply({},Roo.bootstrap.TableRow.superclass.getAutoCreate.call(this));A={tag:'tr'};return A;}});
+//Roo/bootstrap/Form.js
+Roo.bootstrap.Form=function(A){Roo.bootstrap.Form.superclass.constructor.call(this,A);this.addEvents({clientvalidation:true,rendered:true});};Roo.extend(Roo.bootstrap.Form,Roo.bootstrap.Component,{getAutoCreate:function(){var A={tag:'form',method:this.method||'POST',id:this.id||Roo.id(),cls:''};if(this.labelAlign=='left'){A.cls+=' form-horizontal';}return A;}});
+//Roo/form/VTypes.js
+Roo.form.VTypes=function(){var A=/^[a-zA-Z_]+$/;var B=/^[a-zA-Z0-9_]+$/;var C=/^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;var D=/(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;return {'email':function(v){return C.test(v);},'emailText':'This field should be an e-mail address in the format "user@domain.com"','emailMask':/[a-z0-9_\.\-@]/i,'url':function(v){return D.test(v);},'urlText':'This field should be a URL in the format "http:/'+'/www.domain.com"','alpha':function(v){return A.test(v);},'alphaText':'This field should only contain letters and _','alphaMask':/[a-z_]/i,'alphanum':function(v){return B.test(v);},'alphanumText':'This field should only contain letters, numbers and _','alphanumMask':/[a-z0-9_]/i};}();
+//Roo/bootstrap/Input.js
+Roo.bootstrap.Input=function(A){Roo.bootstrap.Input.superclass.constructor.call(this,A);this.addEvents({focus:true,blur:true,specialkey:true,change:true,invalid:true,valid:true,keyup:true});};Roo.extend(Roo.bootstrap.Input,Roo.bootstrap.Component,{validationEvent:"keyup",validateOnBlur:true,validationDelay:250,focusClass:"x-form-focus",invalidClass:"has-error",selectOnFocus:false,maskRe:null,vtype:null,disableKeyFilter:false,disabled:false,allowBlank:true,blankText:"This field is required",minLength:0,maxLength:Number.MAX_VALUE,minLengthText:"The minimum length for this field is {0}",maxLengthText:"The maximum length for this field is {0}",validator:null,regex:null,regexText:"",fieldLabel:'',inputType:'text',name:false,placeholder:false,before:false,after:false,hasFocus:false,preventMark:false,getAutoCreate:function(){var A=this.parent();var B=A.labelAlign;var id=Roo.id();var C={cls:'form-group'};var D={tag:'input',id:id,type:this.inputType,cls:'form-control',placeholder:this.placeholder||''};if(this.name){D.name=name;}var E=D;if(this.before||this.after){E={cls:'input-group',cn:[]};if(this.before){E.cn.push({tag:'span',cls:'input-group-addon',html:this.before});}
+E.cn.push(D);if(this.after){E.cn.push({tag:'span',cls:'input-group-addon',html:this.after});}}
+Roo.log(B);Roo.log(this.fieldLabel.length);if(B==='left'&&this.fieldLabel.length){Roo.log("left and has label");C.cn=[{tag:'label','for':id,cls:'col-sm-2 control-label',html:this.fieldLabel},{cls:"col-sm-10",cn:[E]}];}else if(this.fieldLabel.length){Roo.log(" label");C.cn=[{tag:'label',html:this.fieldLabel},E];}else {Roo.log(" no label && no align");C.cn=[E];}if(this.disabled){D.disabled=true;}return C;},inputEl:function(){return this.el.select('input.form-control',true).first();},setDisabled:function(v){var i=this.inputEl().dom;if(v){i.removeAttribute('disabled');return;}
+i.setAttribute('disabled','true');},initEvents:function(){this.inputEl().on("keydown",this.fireKey,this);this.inputEl().on("focus",this.onFocus,this);this.inputEl().on("blur",this.onBlur,this);this.inputEl().relayEvent('keyup',this);this.originalValue=this.getValue();if(this.validationEvent=='keyup'){this.validationTask=new Roo.util.DelayedTask(this.validate,this);this.inputEl().on('keyup',this.filterValidation,this);}else if(this.validationEvent!==false){this.inputEl().on(this.validationEvent,this.validate,this,{buffer:this.validationDelay});}if(this.selectOnFocus){this.on("focus",this.preFocus,this);}if(this.maskRe||(this.vtype&&this.disableKeyFilter!==true&&(this.maskRe=Roo.form.VTypes[this.vtype+'Mask']))){this.inputEl().on("keypress",this.filterKeys,this);}if(this.inputEl().is('input[type=password]')&&Roo.isSafari){this.inputEl().on('keydown',this.SafariOnKeyDown,this);}},filterValidation:function(e){if(!e.isNavKeyPress()){this.validationTask.delay(this.validationDelay);}},validate:function(){if(this.disabled||this.validateValue(this.getRawValue())){this.clearInvalid();return true;}return false;},validateValue:function(A){if(A.length<1){if(this.allowBlank){this.clearInvalid();return true;}else {this.markInvalid(this.blankText);return false;}}if(A.length<this.minLength){this.markInvalid(String.format(this.minLengthText,this.minLength));return false;}if(A.length>this.maxLength){this.markInvalid(String.format(this.maxLengthText,this.maxLength));return false;}if(this.vtype){var vt=Roo.form.VTypes;if(!vt[this.vtype](A,this)){this.markInvalid(this.vtypeText||vt[this.vtype+'Text']);return false;}}if(typeof this.validator=="function"){var B=this.validator(A);if(B!==true){this.markInvalid(B);return false;}}if(this.regex&&!this.regex.test(A)){this.markInvalid(this.regexText);return false;}return true;},fireKey:function(e){if(e.isNavKeyPress()){this.fireEvent("specialkey",this,e);}},onFocus:function(){if(!Roo.isOpera&&this.focusClass){}if(!this.hasFocus){this.hasFocus=true;this.startValue=this.getValue();this.fireEvent("focus",this);}},beforeBlur:Roo.emptyFn,onBlur:function(){this.beforeBlur();if(!Roo.isOpera&&this.focusClass){}
+this.hasFocus=false;if(this.validationEvent!==false&&this.validateOnBlur&&this.validationEvent!="blur"){this.validate();}var v=this.getValue();if(String(v)!==String(this.startValue)){this.fireEvent('change',this,v,this.startValue);}
+this.fireEvent("blur",this);},getValue:function(){var v=this.inputEl().getValue();return v;},getRawValue:function(){var v=this.inputEl().getValue();return v;},setValue:function(v){this.value=v;if(this.rendered){this.inputEl().dom.value=(v===null||v===undefined?'':v);this.validate();}},preFocus:function(){if(this.selectOnFocus){this.inputEl().dom.select();}},filterKeys:function(e){var k=e.getKey();if(!Roo.isIE&&(e.isNavKeyPress()||k==e.BACKSPACE||(k==e.DELETE &&e.button==-1))){return;}var c=e.getCharCode(),cc=String.fromCharCode(c);if(Roo.isIE&&(e.isSpecialKey()||!cc)){return;}if(!this.maskRe.test(cc)){e.stopEvent();}},clearInvalid:function(){if(!this.el||this.preventMark){return;}
+this.el.removeClass(this.invalidClass);this.fireEvent('valid',this);},markInvalid:function(A){if(!this.el||this.preventMark){return;}
+this.el.addClass(this.invalidClass);this.fireEvent('invalid',this,A);},SafariOnKeyDown:function(A){var B=false;if(this.inputEl().dom.selectionEnd>0){B=(this.inputEl().dom.selectionEnd-this.inputEl().dom.selectionStart-this.getValue().length==0)?true:false;}if(((A.getKey()==8||A.getKey()==46)&&this.getValue().length==1)){A.preventDefault();this.setValue('');return;}if(B){A.preventDefault();var cc=String.fromCharCode(A.getCharCode());this.setValue(A.shiftKey?cc:cc.toLowerCase());}}});