roojs-bootstrap.js
[roojs1] / roojs-bootstrap-debug.js
1 /*
2  * - LGPL
3  *
4  * base class for bootstrap elements.
5  * 
6  */
7
8 Roo.bootstrap = Roo.bootstrap || {};
9 /**
10  * @class Roo.bootstrap.Component
11  * @extends Roo.Component
12  * Bootstrap Component base class
13  * @cfg {String} cls css class
14  * @cfg {String} style any extra css
15  * @cfg {Object} xattr extra attributes to add to 'element' (used by builder to store stuff.)
16  
17  * 
18  * @constructor
19  * Do not use directly - it does not do anything..
20  * @param {Object} config The config object
21  */
22
23
24
25 Roo.bootstrap.Component = function(config){
26     Roo.bootstrap.Component.superclass.constructor.call(this, config);
27 };
28
29 Roo.extend(Roo.bootstrap.Component, Roo.BoxComponent,  {
30     
31     cls : false,
32     
33     style : false,
34     
35     autoCreate : false,
36     
37     initEvents : function() {  },
38     
39     xattr : false,
40     
41     parentId : false,
42     
43     parent: function() {
44         // returns the parent component..
45         return Roo.ComponentMgr.get(this.parentId)
46         
47         
48     },
49     
50     // private
51     onRender : function(ct, position)
52     {
53         Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
54         if(this.el){
55             
56             if (this.el.attr('xtype')) {
57                 this.el.dom.removeAttribute('xtype');
58                 this.initEvents();
59             }
60             
61             return;
62         }
63         
64          
65         
66         var cfg = Roo.apply({},  this.getAutoCreate());
67         cfg.id = Roo.id();
68         
69         // fill in the extra attributes 
70         if (this.xattr && typeof(this.xattr) =='object') {
71             for (var i in this.xattr) {
72                 cfg[i] = this.xattr[i];
73             }
74         }
75         
76         if (this.cls) {
77             cfg.cls += ' ' + this.cls;
78         }
79         if (this.style) { // fixme needs to support more complex style data.
80             cfg.style = this.style;
81         }
82         this.el = ct.createChild(cfg, position);
83         if(this.tabIndex !== undefined){
84             this.el.dom.setAttribute('tabIndex', this.tabIndex);
85         }
86         this.initEvents();
87         
88         
89     },
90     
91     getChildContainer : function()
92     {
93         return this.el;
94     },
95     
96     addxtype : function (tree, cntr) {
97         var cn = this;
98         cntr = typeof(cntr == 'undefined' ) ? 'getChildContainer' : cntr;
99         
100         // render the element if it's not BODY.
101         if (tree.xtype != 'Body') {
102             
103             cn = Roo.factory(tree);
104             
105             cn.parentType = this.xtype; //??
106             cn.parentId = this.id;
107             
108             // does the container contain child eleemnts with 'xtype' attributes.
109             // that match this xtype..
110             // note - when we render we create these as well..
111             // so we should check to see if body has xtype set.
112             if (Roo.get(document.body).attr('xtype') == 'Roo.bootstrap.Body') {
113             
114                 var echild = Roo.get(this[cntr]()).child('*[xtype]');
115                 if (echild) {
116                     cn.el = echild;
117                     //echild.dom.removeAttribute('xtype');
118                 }
119             }
120             cn.render(this[cntr]());
121             // then add the element..
122         }
123         
124         
125         
126         
127         var nitems = [];
128         if (typeof (tree.menu) != 'undefined') {
129             tree.menu.parentType = cn.xtype;
130             tree.menu.triggerEl = cn.el;
131             nitems.push(cn.addxtype(Roo.apply({}, tree.menu)));
132             
133         }
134         if (typeof (tree.buttons) != 'undefined' && typeof(cn.getButtonContainer) == 'function') {
135             
136             for(var i =0;i < tree.buttons.length;i++) {
137                 nitems.push(cn.addxtype(Roo.apply({}, tree.buttons[i]), 'getButtonContainer'));
138             }
139             
140             
141         }
142         if (!tree.items || !tree.items.length) {
143             this.items = nitems;
144             return this;
145         }
146         var items = tree.items;
147         delete tree.items;
148         
149         //Roo.log(items.length);
150             // add the items..
151         for(var i =0;i < items.length;i++) {
152             nitems.push(cn.addxtype(Roo.apply({}, items[i])));
153         }
154         
155         this.items = nitems;
156         
157         
158         return this;
159     }
160     
161     
162     
163     
164 });
165
166  /*
167  * - LGPL
168  *
169  * page container.
170  * 
171  */ 
172 Roo.bootstrap.Body = function(config){
173     Roo.bootstrap.Body.superclass.constructor.call(this, config);
174     this.el = Roo.get(document.body);
175 };
176
177 Roo.extend(Roo.bootstrap.Body, Roo.bootstrap.Component,  {
178       
179         autoCreate : {
180         cls: 'container'
181     },
182     onRender : function(ct, position){
183         
184         
185         //this.el.addClass([this.fieldClass, this.cls]);
186         
187     }
188     
189     
190  
191    
192 });
193
194  /*
195  * - LGPL
196  *
197  * button group
198  * 
199  */
200
201
202 /**
203  * @class Roo.bootstrap.ButtonGroup
204  * @extends Roo.bootstrap.Component
205  * Bootstrap ButtonGroup class
206  * @cfg {String} size lg | sm | xs (default empty normal)
207  * @cfg {String} align vertical | justified  (default none)
208  * @cfg {String} direction up | down (default down)
209  * @cfg {Boolean} toolbar false | true
210  * @cfg {Boolean} btn true | false
211  * 
212  * 
213  * @constructor
214  * Create a new Input
215  * @param {Object} config The config object
216  */
217
218 Roo.bootstrap.ButtonGroup = function(config){
219     Roo.bootstrap.ButtonGroup.superclass.constructor.call(this, config);
220 };
221
222 Roo.extend(Roo.bootstrap.ButtonGroup, Roo.bootstrap.Component,  {
223     
224     size: '',
225     align: '',
226     direction: '',
227     toolbar: false,
228     btn: true,
229
230     getAutoCreate : function(){
231         var cfg = {
232             cls: 'btn-group',
233             html : null
234         }
235         
236         cfg.html = this.html || cfg.html;
237         
238         if (this.toolbar) {
239             cfg = {
240                 cls: 'btn-toolbar',
241                 html: null
242             }
243             
244             return cfg;
245         }
246         
247         if (['vertical','justified'].indexOf(this.align)!==-1) {
248             cfg.cls = 'btn-group-' + this.align;
249             
250             if (this.align == 'justified') {
251                 console.log(this.items);
252             }
253         }
254         
255         if (['lg','sm','xs'].indexOf(this.size)!==-1) {
256             cfg.cls += ' btn-group-' + this.size;
257         }
258         
259         if (this.direction == 'up') {
260             cfg.cls += ' dropup' ;
261         }
262         
263         return cfg;
264     }
265    
266 });
267
268  /*
269  * - LGPL
270  *
271  * button
272  * 
273  */
274
275 /**
276  * @class Roo.bootstrap.Button
277  * @extends Roo.bootstrap.Component
278  * Bootstrap Button class
279  * @cfg {String} html The button content
280  * @cfg {String} weight default (or empty) | primary | success | info | warning | danger
281  * @cfg {String} size empty | lg | sm | xs
282  * @cfg {String} tag empty | a | input | submit
283  * @cfg {String} href empty or href
284  * @cfg {Boolean} disabled false | true
285  * @cfg {Boolean} isClose false | true
286  * @cfg {String} glyphicon empty | adjust | align-center | align-justify | align-left | align-right | arrow-down | arrow-left | arrow-right | arrow-up | asterisk | backward | ban-circle | barcode | bell | bold | book | bookmark | briefcase | bullhorn | calendar | camera | certificate | check | chevron-down | chevron-left | chevron-right | chevron-up | circle-arrow-down | circle-arrow-left | circle-arrow-right | circle-arrow-up | cloud | cloud-download | cloud-upload | cog | collapse-down | collapse-up | comment | compressed | copyright-mark | credit-card | cutlery | dashboard | download | download-alt | earphone | edit | eject | envelope | euro | exclamation-sign | expand | export | eye-close | eye-open | facetime-video | fast-backward | fast-forward | file | film | filter | fire | flag | flash | floppy-disk | floppy-open | floppy-remove | floppy-save | floppy-saved | folder-close | folder-open | font | forward | fullscreen | gbp | gift | glass | globe | hand-down | hand-left | hand-right | hand-up | hd-video | hdd | header | headphones | heart | heart-empty | home | import | inbox | indent-left | indent-right | info-sign | italic | leaf | link | list | list-alt | lock | log-in | log-out | magnet | map-marker | minus | minus-sign | move | music | new-window | off | ok | ok-circle | ok-sign | open | paperclip | pause | pencil | phone | phone-alt | picture | plane | play | play-circle | plus | plus-sign | print | pushpin | qrcode | question-sign | random | record | refresh | registration-mark | remove | remove-circle | remove-sign | repeat | resize-full | resize-horizontal | resize-small | resize-vertical | retweet | road | save | saved | screenshot | sd-video | search | send | share | share-alt | shopping-cart | signal | sort | sort-by-alphabet | sort-by-alphabet-alt | sort-by-attributes | sort-by-attributes-alt | sort-by-order | sort-by-order-alt | sound-5-1 | sound-6-1 | sound-7-1 | sound-dolby | sound-stereo | star | star-empty | stats | step-backward | step-forward | stop | subtitles | tag | tags | tasks | text-height | text-width | th | th-large | th-list | thumbs-down | thumbs-up | time | tint | tower | transfer | trash | tree-conifer | tree-deciduous | unchecked | upload | usd | user | volume-down | volume-off | volume-up | warning-sign | wrench | zoom-in | zoom-out
287  * @cfg {String} badge text for badge
288  * @cfg {String} theme default (or empty) | glow
289  * @cfg {Boolean} inverse false | true
290  * @cfg {Boolean} toggle false | true
291  * @cfg {String} ontext text for on toggle state
292  * @cfg {String} offtext text for off toggle state
293  * @cfg {Boolean} defaulton true | false
294  * 
295  * @constructor
296  * Create a new button
297  * @param {Object} config The config object
298  */
299
300
301 Roo.bootstrap.Button = function(config){
302     Roo.bootstrap.Button.superclass.constructor.call(this, config);
303     this.addEvents({
304         // raw events
305         /**
306          * @event click
307          * The raw click event for the entire grid.
308          * @param {Roo.EventObject} e
309          */
310         "click" : true
311     });
312 };
313
314 Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component,  {
315     html: false,
316     active: false,
317     weight: '',
318     size: '',
319     tag: 'button',
320     href: '',
321     disabled: false,
322     isClose: false,
323     glyphicon: '',
324     badge: '',
325     theme: 'default',
326     inverse: false,
327     
328     toggle: false,
329     ontext: 'ON',
330     offtext: 'OFF',
331     defaulton: true,
332     
333     getAutoCreate : function(){
334         
335         var cfg = {
336             tag : 'button',
337             html: 'hello'
338         };
339         
340         if (['a', 'button', 'input', 'submit'].indexOf(this.tag) < 0) {
341             throw "Invalid value for tag: " + this.tag + ". must be a, button, input or submit.";
342             this.tag = 'button';
343         } else {
344             cfg.tag = this.tag;
345         }
346         cfg.html = this.html || cfg.html;
347         
348         if (this.toggle===true) {
349             cfg={
350                 tag: 'div',
351                 cls: 'slider-frame',
352                 cn: [
353                     {
354                         tag: 'span',
355                         'data-on-text':'ON',
356                         'data-off-text':'OFF',
357                         cls: 'slider-button',
358                         html: this.offtext
359                     }
360                 ]
361             };
362             
363             if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
364                 cfg.cls += ' '+this.weight;
365             }
366             
367             return cfg;
368         }
369         
370         if (this.isClose) {
371             cfg.cls += ' close';
372             
373             cfg["aria-hidden"] = true;
374             
375             cfg.html = "&times;";
376             
377             return cfg;
378         }
379         
380         if (true) {
381             if (this.theme==='default') {
382                 cfg.cls = 'btn';
383                 
384                 if (this.parentType != 'Navbar') {
385                     this.weight = this.weight.length ?  this.weight : 'default';
386                 }
387                 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
388                     
389                     cfg.cls += ' btn-' + this.weight;
390                 }
391             } else if (this.theme==='glow') {
392                 
393                 cfg.tag = 'a';
394                 cfg.cls='btn-glow';
395                 
396                 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
397                     
398                     cfg.cls += ' ' + this.weight;
399                 }
400             }
401         }
402         
403         if (this.inverse) {
404             this.cls += ' inverse';
405         }
406         
407         
408         if (this.active) {
409             cfg.cls += ' active';
410         }
411         
412         cfg.cls += this.size.length ? (' btn-' + this.size) : '';
413          
414         //gsRoo.log(this.parentType);
415         if (this.parentType === 'Navbar') {
416             cfg.tag = 'li';
417             
418             cfg.cls = '';
419             cfg.cn =  [{
420                 tag : 'a',
421                 html : this.html,
422                 href : this.href || '#'
423             }];
424             if (this.menu) {
425                 cfg.cn[0].html = this.html  + ' <span class="caret"></span>';
426                 cfg.cls += ' dropdown';
427             }   
428             
429             delete cfg.html;
430             
431         } else if (this.menu) {
432             cfg.tag = 'a';
433             cfg.cls += ' dropdown test';
434         }
435         
436         
437         
438         if (this.disabled) {
439             cfg.disabled = 'disabled';
440         }
441         
442         if (this.items) {
443             Roo.log('changing to ul' );
444             cfg.tag = 'ul';
445             this.glyphicon = 'caret';
446         }
447         
448         if (this.glyphicon) {
449             cfg.html = ' ' + cfg.html;
450             
451             cfg.cn = [
452                 {
453                     tag: 'span',
454                     cls: 'glyphicon glyphicon-' + this.glyphicon
455                 }
456             ];
457         }
458         
459         if (this.badge) {
460             cfg.html += ' ';
461             
462             cfg.tag = 'a';
463             
464             cfg.cls='btn';
465             
466             cfg.href=this.href;
467             
468             cfg.cn = [
469                 cfg.html,
470                 {
471                     tag: 'span',
472                     cls: 'badge',
473                     html: this.badge
474                 }
475             ];
476             
477             cfg.html='';
478         }
479         
480         if (cfg.tag !== 'a' && this.href !== '') {
481             throw "Tag must be a to set href.";
482         } else if (this.href.length > 0) {
483             cfg.href = this.href;
484         }
485         
486         return cfg;
487     },
488     initEvents: function() {
489        // Roo.log('init events?');
490        // Roo.log(this.el.dom);
491        this.el.select('a',true).relayEvent('click', this);
492        this.el.select('button',true).relayEvent('click', this);
493         
494     },
495     onClick : function(e)
496     {
497         e.preventDefault();
498         this.fireEvent('click', this, e);
499     }
500     
501     
502 });
503
504  /*
505  * - LGPL
506  *
507  * column
508  * 
509  */
510
511 /**
512  * @class Roo.bootstrap.Column
513  * @extends Roo.bootstrap.Component
514  * Bootstrap Column class
515  * @cfg {Number} xs colspan out of 12 for mobile-sized screens
516  * @cfg {Number} sm colspan out of 12 for tablet-sized screens
517  * @cfg {Number} md colspan out of 12 for computer-sized screens
518  * @cfg {Number} lg colspan out of 12 for large computer-sized screens
519  * @cfg {String} html content of column.
520  * 
521  * @constructor
522  * Create a new Column
523  * @param {Object} config The config object
524  */
525
526 Roo.bootstrap.Column = function(config){
527     Roo.bootstrap.Column.superclass.constructor.call(this, config);
528 };
529
530 Roo.extend(Roo.bootstrap.Column, Roo.bootstrap.Component,  {
531     
532     xs: null,
533     sm: null,
534     md: null,
535     lg: null,
536     html: '',
537     offset: 0,
538     
539     getAutoCreate : function(){
540         var cfg = Roo.apply({}, Roo.bootstrap.Column.superclass.getAutoCreate.call(this));
541         
542         cfg = {
543             tag: 'div',
544             cls: 'column'
545         };
546         
547         var settings=this;
548         ['xs','sm','md','lg'].map(function(size){
549             if (settings[size]) {
550                 cfg.cls += ' col-' + size + '-' + settings[size];
551             }
552         });
553         if (this.html.length) {
554             cfg.html = this.html;
555         }
556         
557         return cfg;
558     }
559    
560 });
561
562  
563
564  /*
565  * - LGPL
566  *
567  * page container.
568  * 
569  */
570
571
572 /**
573  * @class Roo.bootstrap.Container
574  * @extends Roo.bootstrap.Component
575  * Bootstrap Container class
576  * @cfg {Boolean} jumbotron is it a jumbotron element
577  * @cfg {String} html content of element
578  * @cfg {String} well (lg|sm|md) a well, large, small or medium.
579  * @cfg {String} panel (primary|success|info|warning|danger) render as a panel.
580  * @cfg {String} header content of header (for panel)
581  * @cfg {String} footer content of footer (for panel)
582  * @cfg {String} sticky (footer|wrap|push) block to use as footer or body- needs css-bootstrap/sticky-footer.css
583  *     
584  * @constructor
585  * Create a new Container
586  * @param {Object} config The config object
587  */
588
589 Roo.bootstrap.Container = function(config){
590     Roo.bootstrap.Container.superclass.constructor.call(this, config);
591 };
592
593 Roo.extend(Roo.bootstrap.Container, Roo.bootstrap.Component,  {
594     
595     jumbotron : false,
596     well: '',
597     panel : '',
598     header: '',
599     footer : '',
600     sticky: '',
601   
602      
603     getChildContainer : function() {
604         if (this.panel.length) {
605             return this.el.select('.panel-body',true).first();
606         }
607         
608         return this.el;
609     },
610     
611     
612     getAutoCreate : function(){
613         
614         var cfg = {
615             html : '',
616             cls : ''
617         };
618         if (this.jumbotron) {
619             cfg.cls = 'jumbotron';
620         }
621         if (this.cls) {
622             cfg.cls = this.cls + '';
623         }
624         
625         if (this.sticky.length) {
626             var bd = Roo.get(document.body);
627             if (!bd.hasClass('bootstrap-sticky')) {
628                 bd.addClass('bootstrap-sticky');
629                 Roo.select('html',true).setStyle('height', '100%');
630             }
631              
632             cfg.cls += 'bootstrap-sticky-' + this.sticky;
633         }
634         
635         
636         if (this.well.length) {
637             switch (this.well) {
638                 case 'lg':
639                 case 'sm':
640                     cfg.cls +=' well well-' +this.well;
641                     break;
642                 default:
643                     cfg.cls +=' well';
644                     break;
645             }
646         }
647         
648         var body = cfg;
649         
650         if (this.panel.length) {
651             cfg.cls += 'panel panel-' + this.panel;
652             cfg.cn = [];
653             if (this.header.length) {
654                 cfg.cn.push({
655                     
656                     cls : 'panel-heading',
657                     cn : [{
658                         tag: 'h3',
659                         cls : 'panel-title',
660                         html : this.header
661                     }]
662                     
663                 });
664             }
665             body = false;
666             cfg.cn.push({
667                 cls : 'panel-body',
668                 html : this.html
669             });
670             
671             
672             if (this.footer.length) {
673                 cfg.cn.push({
674                     cls : 'panel-footer',
675                     html : this.footer
676                     
677                 });
678             }
679             
680         }
681         if (body) {
682             body.html = this.html || cfg.html;
683         }
684         if (!cfg.cls.length) {
685             cfg.cls =  'container';
686         }
687         
688         return cfg;
689     }
690    
691 });
692
693  /*
694  * - LGPL
695  *
696  * image
697  * 
698  */
699
700
701 /**
702  * @class Roo.bootstrap.Img
703  * @extends Roo.bootstrap.Component
704  * Bootstrap Img class
705  * @cfg {Boolean} imgResponsive false | true
706  * @cfg {String} border rounded | circle | thumbnail
707  * @cfg {String} src image source
708  * @cfg {String} alt image alternative text
709  * 
710  * @constructor
711  * Create a new Input
712  * @param {Object} config The config object
713  */
714
715 Roo.bootstrap.Img = function(config){
716     Roo.bootstrap.Img.superclass.constructor.call(this, config);
717 };
718
719 Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component,  {
720     
721     imgResponsive: true,
722     border: '',
723     src: '',
724
725     getAutoCreate : function(){
726         
727         cfg = {
728             tag: 'img',
729             cls: 'img-responsive',
730             html : null
731         }
732         
733         cfg.html = this.html || cfg.html;
734         
735         cfg.src = this.src || cfg.src;
736         
737         if (['rounded','circle','thumbnail'].indexOf(this.border)>-1) {
738             cfg.cls += ' img-' + this.border;
739         }
740         
741         if(this.alt){
742             cfg.alt = this.alt;
743         }
744         
745         return cfg;
746     }
747    
748 });
749
750  /*
751  * - LGPL
752  *
753  * header
754  * 
755  */
756
757 /**
758  * @class Roo.bootstrap.Header
759  * @extends Roo.bootstrap.Component
760  * Bootstrap Header class
761  * @cfg {String} html content of header
762  * @cfg {Number} level (1|2|3|4|5|6) default 1
763  * 
764  * @constructor
765  * Create a new Header
766  * @param {Object} config The config object
767  */
768
769
770 Roo.bootstrap.Header  = function(config){
771     Roo.bootstrap.Header.superclass.constructor.call(this, config);
772 };
773
774 Roo.extend(Roo.bootstrap.Header, Roo.bootstrap.Component,  {
775     
776     //href : false,
777     html : false,
778     level : 1,
779     
780     
781     
782     getAutoCreate : function(){
783         
784         var cfg = {
785             tag: 'h' + (1 *this.level),
786             html: this.html || 'fill in html'
787         } ;
788         
789         return cfg;
790     }
791    
792 });
793
794  
795
796  /*
797  * - LGPL
798  *
799  * menu
800  * 
801  */
802
803 /**
804  * @class Roo.bootstrap.Menu
805  * @extends Roo.bootstrap.Component
806  * Bootstrap Menu class - container for MenuItems
807  * @cfg {String} type type of menu
808  * 
809  * @constructor
810  * Create a new Menu
811  * @param {Object} config The config object
812  */
813
814
815 Roo.bootstrap.Menu = function(config){
816     Roo.bootstrap.Menu.superclass.constructor.call(this, config);
817 };
818
819 Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component,  {
820     
821    /// html : false,
822     //align : '',
823     triggerEl : false,
824     type: false,
825     
826     
827     getChildContainer : function() {
828         return this.el;  
829     },
830     
831     getAutoCreate : function(){
832          
833         //if (['right'].indexOf(this.align)!==-1) {
834         //    cfg.cn[1].cls += ' pull-right'
835         //}
836         var cfg = {
837             tag : 'ul',
838             cls : 'dropdown-menu' 
839             
840         }
841         
842         if (this.type==='submenu') {
843             cfg.cls='submenu active'
844         }
845         
846         return cfg;
847     },
848     initEvents : function() {
849        // Roo.log("ADD event");
850        // Roo.log(this.triggerEl.dom);
851         this.triggerEl.on('click', this.toggle, this);
852         this.triggerEl.addClass('dropdown-toggle');
853         
854     },
855     toggle  : function(e)
856     {
857         //Roo.log(e.getTarget());
858        // Roo.log(this.triggerEl.dom);
859         if (Roo.get(e.getTarget()).findParent('.dropdown-menu')) {
860             return;
861         }
862         var isActive = this.triggerEl.hasClass('open');
863         // if disabled.. ingore
864         this.clearMenus(e);
865         //if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
866          // if mobile we use a backdrop because click events don't delegate
867         // $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
868         // }
869  
870        //var relatedTarget = { relatedTarget: this }
871        //$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
872  
873        //if (e.isDefaultPrevented()) return;
874         
875        this.triggerEl[isActive ? 'removeClass' : 'addClass']('open');
876        
877        //  .trigger('shown.bs.dropdown', relatedTarget)
878  
879        this.triggerEl.focus();
880        Roo.log(e);
881        e.preventDefault(); 
882         
883         
884     },
885     clearMenus : function()
886     {
887         //$(backdrop).remove()
888         Roo.select('.dropdown-toggle',true).each(function(aa) {
889             if (!aa.hasClass('open')) {
890                 return;
891             }
892             // triger close...
893             aa.removeClass('open');
894           //var parent = getParent($(this))
895           //var relatedTarget = { relatedTarget: this }
896           
897            //$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
898           //if (e.isDefaultPrevented()) return
899            //$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
900         })
901     }
902     
903    
904 });
905
906  
907
908  /*
909  * - LGPL
910  *
911  * menu item
912  * 
913  */
914
915
916 /**
917  * @class Roo.bootstrap.MenuItem
918  * @extends Roo.bootstrap.Component
919  * Bootstrap MenuItem class
920  * @cfg {String} html the menu label
921  * @cfg {String} href the link
922  * 
923  * 
924  * @constructor
925  * Create a new MenuItem
926  * @param {Object} config The config object
927  */
928
929
930 Roo.bootstrap.MenuItem = function(config){
931     Roo.bootstrap.MenuItem.superclass.constructor.call(this, config);
932 };
933
934 Roo.extend(Roo.bootstrap.MenuItem, Roo.bootstrap.Component,  {
935     
936     href : false,
937     html : false,
938     
939     getAutoCreate : function(){
940         var cfg= {
941             tag: 'li',
942             cn: [
943                 {
944                     tag : 'a',
945                     href : '#',
946                     html : 'Link'
947                 }
948             ]
949         };
950         
951         cfg.cn[0].href = this.href || cfg.cn[0].href ;
952         cfg.cn[0].html = this.html || cfg.cn[0].html ;
953         return cfg;
954     }
955    
956 });
957
958  
959
960  /*
961  * - LGPL
962  *
963  * menu separator
964  * 
965  */
966
967
968 /**
969  * @class Roo.bootstrap.MenuSeparator
970  * @extends Roo.bootstrap.Component
971  * Bootstrap MenuSeparator class
972  * 
973  * @constructor
974  * Create a new MenuItem
975  * @param {Object} config The config object
976  */
977
978
979 Roo.bootstrap.MenuSeparator = function(config){
980     Roo.bootstrap.MenuSeparator.superclass.constructor.call(this, config);
981 };
982
983 Roo.extend(Roo.bootstrap.MenuSeparator, Roo.bootstrap.Component,  {
984     
985     getAutoCreate : function(){
986         var cfg = {
987             cls: 'divider',
988             tag : 'li'
989         };
990         
991         return cfg;
992     }
993    
994 });
995
996  
997
998  
999 /*
1000 <div class="modal fade">
1001   <div class="modal-dialog">
1002     <div class="modal-content">
1003       <div class="modal-header">
1004         <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
1005         <h4 class="modal-title">Modal title</h4>
1006       </div>
1007       <div class="modal-body">
1008         <p>One fine body&hellip;</p>
1009       </div>
1010       <div class="modal-footer">
1011         <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1012         <button type="button" class="btn btn-primary">Save changes</button>
1013       </div>
1014     </div><!-- /.modal-content -->
1015   </div><!-- /.modal-dialog -->
1016 </div><!-- /.modal -->
1017 */
1018 /*
1019  * - LGPL
1020  *
1021  * page contgainer.
1022  * 
1023  */
1024
1025 /**
1026  * @class Roo.bootstrap.Modal
1027  * @extends Roo.bootstrap.Component
1028  * Bootstrap Modal class
1029  * @cfg {String} title Title of dialog
1030  * @cfg {Array} buttons Array of buttons
1031  * 
1032  * @constructor
1033  * Create a new Modal Dialog
1034  * @param {Object} config The config object
1035  */
1036
1037 Roo.bootstrap.Modal = function(config){
1038     Roo.bootstrap.Modal.superclass.constructor.call(this, config);
1039 };
1040
1041 Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component,  {
1042     
1043     title : 'test dialog',
1044    
1045     buttons : false,
1046
1047     onRender : function(ct, position)
1048     {
1049         Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
1050         if(!this.el){
1051             var cfg = Roo.apply({},  this.getAutoCreate());
1052             cfg.id = Roo.id();
1053             //if(!cfg.name){
1054             //    cfg.name = typeof(this.name) == 'undefined' ? this.id : this.name;
1055             //}
1056             //if (!cfg.name.length) {
1057             //    delete cfg.name;
1058            // }
1059             if (this.cls) {
1060                 cfg.cls += ' ' + this.cls;
1061             }
1062             if (this.style) {
1063                 cfg.style = this.style;
1064             }
1065             this.el = Roo.get(document.body).createChild(cfg, position);
1066         }
1067         //var type = this.el.dom.type;
1068          
1069         if(this.tabIndex !== undefined){
1070             this.el.dom.setAttribute('tabIndex', this.tabIndex);
1071         }
1072         this.initEvents();
1073         //this.el.addClass([this.fieldClass, this.cls]);
1074         
1075     },
1076     getAutoCreate : function(){
1077         
1078         return {
1079             cls: "modal fade",
1080             cn : [
1081                 {
1082                     cls: "modal-dialog",
1083                     cn : [
1084                         {
1085                             cls : "modal-content",
1086                             cn : [
1087                                 {
1088                                     cls : 'modal-header',
1089                                     cn : [
1090                                         {
1091                                             tag: 'button',
1092                                             cls : 'close',
1093                                             html : '&times'
1094                                         },
1095                                         {
1096                                             tag: 'h4',
1097                                             cls : 'modal-title',
1098                                             html : this.title
1099                                         }
1100                                     
1101                                     ]
1102                                 },
1103                                 {
1104                                     cls : 'modal-body'
1105                                  
1106                                 },
1107                                  {
1108                                     cls : 'modal-footer'
1109                                     /*
1110                                     cn : [
1111                                         {
1112                                             tag: 'button',
1113                                             cls : 'btn btn-default',
1114                                             html : 'Close'
1115                                         },
1116                                         {
1117                                             tag: 'button',
1118                                             cls : 'btn btn-primary',
1119                                             html : 'Save'
1120                                         }
1121                                     
1122                                     ]
1123                                     */
1124                                 }
1125                                 
1126                                 
1127                             ]
1128                             
1129                         }
1130                     ]
1131                         
1132                 }
1133             ]
1134             
1135             
1136         };
1137           
1138     },
1139     getChildContainer : function() {
1140          
1141          return this.el.select('.modal-body',true).first();
1142         
1143     },
1144     getButtonContainer : function() {
1145          return this.el.select('.modal-footer',true).first();
1146         
1147     },
1148     initEvents : function()
1149     {
1150         this.el.select('.modal-header .close').on('click', this.hide, this);
1151     },
1152     show : function() {
1153         this.el.addClass('on');
1154         this.el.removeClass('fade');
1155         this.el.setStyle('display', 'block');
1156     },
1157     hide : function() {
1158         this.el.removeClass('on');
1159         this.el.addClass('fade');
1160         this.el.setStyle('display', 'none');
1161     }
1162 });
1163
1164  /*
1165  * - LGPL
1166  *
1167  * navbar
1168  * 
1169  */
1170
1171 /**
1172  * @class Roo.bootstrap.Navbar
1173  * @extends Roo.bootstrap.Component
1174  * Bootstrap Navbar class
1175  * @cfg {Boolean} sidebar has side bar
1176  * @cfg {Boolean} bar is a bar?
1177  * @cfg {String} position (fixed-top|fixed-bottom|static-top) position
1178  * @cfg {String} brand what is brand
1179  * @cfg {Boolean} inverse is inverted color
1180  * @cfg {String} type (nav | pills | tabs)
1181  * @cfg {Boolean} arrangement stacked | justified
1182  * @cfg {String} align (left | right) alignment
1183  *
1184  * 
1185  * @constructor
1186  * Create a new Navbar
1187  * @param {Object} config The config object
1188  */
1189
1190
1191 Roo.bootstrap.Navbar = function(config){
1192     Roo.bootstrap.Navbar.superclass.constructor.call(this, config);
1193 };
1194
1195 Roo.extend(Roo.bootstrap.Navbar, Roo.bootstrap.Component,  {
1196     
1197     sidebar: false,
1198     
1199     bar: false,
1200     brand: '',
1201     inverse: false,
1202     position: '',
1203     align : false,
1204     type: 'nav',
1205     arrangement: '',
1206     
1207     getAutoCreate : function(){
1208         var cfg = {
1209             cls : 'navbar'
1210         };
1211         
1212         if (this.sidebar === true) {
1213             cfg = {
1214                 tag: 'div',
1215                 cls: 'sidebar-nav'
1216             };
1217             return cfg;
1218         }
1219         
1220         if (this.bar === true) {
1221             cfg = {
1222                 tag: 'nav',
1223                 cls: 'navbar',
1224                 role: 'navigation',
1225                 cn: [
1226                     {
1227                         tag: 'div',
1228                         cls: 'navbar-header',
1229                         cn: [
1230                             {
1231                             tag: 'button',
1232                             type: 'button',
1233                             cls: 'navbar-toggle',
1234                             'data-toggle': 'collapse',
1235                             cn: [
1236                                 {
1237                                     tag: 'span',
1238                                     cls: 'sr-only',
1239                                     html: 'Toggle navigation'
1240                                 },
1241                                 {
1242                                     tag: 'span',
1243                                     cls: 'icon-bar'
1244                                 },
1245                                 {
1246                                     tag: 'span',
1247                                     cls: 'icon-bar'
1248                                 },
1249                                 {
1250                                     tag: 'span',
1251                                     cls: 'icon-bar'
1252                                 }
1253                             ]
1254                             }
1255                         ]
1256                     },
1257                     {
1258                     tag: 'div',
1259                     cls: 'collapse navbar-collapse'
1260                     }
1261                 ]
1262             };
1263             
1264             cfg.cls += this.inverse ? ' navbar-inverse' : ' navbar-default';
1265             
1266             if (['fixed-top','fixed-bottom','static-top'].indexOf(this.position)>-1) {
1267             cfg.cls += ' navbar-' + this.position;
1268             cfg.tag = this.position  == 'fixed-bottom' ? 'footer' : 'header';
1269             }
1270             
1271             if (this.brand !== '') {
1272                 cfg.cn[0].cn.push({
1273                     tag: 'a',
1274                     href: '#',
1275                     cls: 'navbar-brand',
1276                     cn: [
1277                     this.brand
1278                     ]
1279                 });
1280             }
1281             
1282             return cfg;
1283         
1284         } else if (this.bar === false) {
1285             
1286         } else {
1287             Roo.log('Property \'bar\' in of Navbar must be either true or false')
1288         }
1289         
1290         cfg.cn = [
1291             {
1292                 cls: 'nav',
1293                 tag : 'ul'
1294             }
1295         ];
1296         
1297         if (['tabs','pills'].indexOf(this.type)!==-1) {
1298             cfg.cn[0].cls += ' nav-' + this.type
1299         } else {
1300             if (this.type!=='nav') {
1301             Roo.log('nav type must be nav/tabs/pills')
1302             }
1303             cfg.cn[0].cls += ' navbar-nav'
1304         }
1305         
1306         if (['stacked','justified'].indexOf(this.arrangement)!==-1) {
1307             cfg.cn[0].cls += ' nav-' + this.arrangement;
1308         }
1309         
1310         if (this.align === 'right') {
1311             cfg.cn[0].cls += ' navbar-right';
1312         }
1313         if (this.inverse) {
1314             cfg.cls += ' navbar-inverse';
1315             
1316         }
1317         
1318         
1319         return cfg;
1320     },
1321     
1322     getChildContainer : function() {
1323         if (this.bar === true) {
1324             return this.el.select('.collapse',true).first();
1325         }
1326         console.log(this);
1327         return this.el;
1328     }
1329    
1330 });
1331
1332  
1333
1334  /*
1335  * - LGPL
1336  *
1337  * nav group
1338  * 
1339  */
1340
1341 /**
1342  * @class Roo.bootstrap.NavGroup
1343  * @extends Roo.bootstrap.Component
1344  * Bootstrap NavGroup class
1345  * @cfg {String} align left | right
1346  * @cfg {Boolean} inverse false | true
1347  * 
1348  * @constructor
1349  * Create a new nav group
1350  * @param {Object} config The config object
1351  */
1352
1353 Roo.bootstrap.NavGroup = function(config){
1354     Roo.bootstrap.NavGroup.superclass.constructor.call(this, config);
1355 };
1356
1357 Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component,  {
1358     
1359     align: '',
1360     inverse: false,
1361     form: false,
1362     
1363     getAutoCreate : function(){
1364         var cfg = Roo.apply({}, Roo.bootstrap.NavGroup.superclass.getAutoCreate.call(this));
1365         
1366         cfg = {
1367             tag : 'ul',
1368             cls: 'nav navbar-nav' 
1369         }
1370         
1371         if (this.parent().sidebar === true) {
1372             cfg = {
1373                 tag: 'ul',
1374                 cls: 'dashboard-menu'
1375             }
1376             
1377             return cfg;
1378         }
1379         
1380         if (this.form === true) {
1381             cfg = {
1382                 tag: 'form',
1383                 cls: 'navbar-form'
1384             }
1385             
1386             if (this.align === 'right') {
1387                 cfg.cls += ' navbar-right';
1388             } else {
1389                 cfg.cls += ' navbar-left';
1390             }
1391         }
1392         
1393         
1394         if (this.align === 'right') {
1395             cfg.cls += ' navbar-right';
1396         }
1397         
1398         if (this.inverse) {
1399             cfg.cls += ' navbar-inverse';
1400             
1401         }
1402         
1403         
1404         return cfg;
1405     }
1406    
1407 });
1408
1409  
1410
1411  /*
1412  * - LGPL
1413  *
1414  * row
1415  * 
1416  */
1417 /**
1418  * @class Roo.bootstrap.Navbar.Button
1419  * @extends Roo.bootstrap.Component
1420  * Bootstrap Navbar.Button class
1421  * @cfg {String} href  link to
1422  * @cfg {String} html content of button
1423     
1424  * @constructor
1425  * Create a new Navbar Button
1426  * @param {Object} config The config object
1427  */
1428
1429
1430 Roo.bootstrap.Navbar.Button = function(config){
1431     Roo.bootstrap.Navbar.Button.superclass.constructor.call(this, config);
1432 };
1433
1434 Roo.extend(Roo.bootstrap.Navbar.Button, Roo.bootstrap.Component,  {
1435     
1436     href : false,
1437     html : false,
1438     
1439     autoCreate : {
1440         cls: 'btn',
1441         tag : 'button',
1442         html: 'hello'
1443     },
1444     
1445     getAutoCreate : function(){
1446         
1447         var cfg = {
1448             cls: 'btn',
1449             tag : 'button',
1450             html: 'hello',
1451             cn : []
1452             
1453         } ;
1454         cfg.cn.push({
1455             html : this.html || ''
1456             //href : this.
1457              //       )
1458         });
1459         cfg.cn.push({
1460             tag: 'span',
1461             cls : 'carat'
1462         });
1463         
1464         return cfg;
1465     }
1466    
1467 });
1468
1469  
1470
1471  /*
1472  * - LGPL
1473  *
1474  * row
1475  * 
1476  */
1477
1478 /**
1479  * @class Roo.bootstrap.Navbar.Item
1480  * @extends Roo.bootstrap.Component
1481  * Bootstrap Navbar.Button class
1482  * @cfg {String} href  link to
1483  * @cfg {String} html content of button
1484  * @cfg {String} badge text inside badge
1485  * @cfg {String} glyphicon name of glyphicon
1486   
1487  * @constructor
1488  * Create a new Navbar Button
1489  * @param {Object} config The config object
1490  */
1491 Roo.bootstrap.Navbar.Item = function(config){
1492     Roo.bootstrap.Navbar.Item.superclass.constructor.call(this, config);
1493 };
1494
1495 Roo.extend(Roo.bootstrap.Navbar.Item, Roo.bootstrap.Component,  {
1496     
1497     href: false,
1498     html: '',
1499     badge: '',
1500     icon: false,
1501     glyphicon: false,
1502     
1503     getAutoCreate : function(){
1504         
1505         var cfg = Roo.apply({}, Roo.bootstrap.Navbar.Item.superclass.getAutoCreate.call(this));
1506         
1507         if (this.parent().parent().sidebar === true) {
1508             cfg = {
1509                 tag: 'li',
1510                 cls: '',
1511                 cn: [
1512                     {
1513                         tag: 'p',
1514                         cls: ''
1515                     }
1516                 ]
1517             }
1518             
1519             if (this.html) {
1520                 cfg.cn[0].html = this.html;
1521             }
1522             
1523             if (this.active) {
1524                 this.cls += ' active';
1525             }
1526             
1527             if (this.menu) {
1528                 cfg.cn[0].cls += ' dropdown-toggle';
1529                 cfg.cn[0].html = (cfg.cn[0].html || this.html) + '<span class="glyphicon glyphicon-chevron-down"></span>';
1530             }
1531             
1532             if (this.href) {
1533                 cfg.cn[0].tag = 'a',
1534                 cfg.cn[0].href = this.href;
1535             }
1536             
1537             if (this.glyphicon) {
1538                 cfg.cn[0].html = '<i class="glyphicon glyphicon-'+this.glyphicon+'"></i><span>' + cfg.cn[0].html || this.html + '</span>'
1539             }
1540             
1541             return cfg;
1542         }
1543         
1544         cfg = {
1545             tag: 'li'
1546         }
1547         cfg.cn = [
1548             {
1549                 tag: 'p',
1550                 html: 'Text'
1551             }
1552         ];
1553         
1554         if (this.glyphicon) {
1555             if(cfg.html){cfg.html = ' ' + this.html};
1556             cfg.cn=[
1557                 {
1558                     tag: 'span',
1559                     cls: 'glyphicon glyphicon-' + this.glyphicon
1560                 }
1561             ];
1562         }
1563         
1564         cfg.cn[0].html = this.html || cfg.cn[0].html ;
1565         if (this.menu) {
1566             cfg.cn[0].tag='a';
1567             cfg.cn[0].href='#';
1568             cfg.cn[0].html += " <span class='caret'></span>";
1569         //}else if (!this.href) {
1570         //    cfg.cn[0].tag='p';
1571         //    cfg.cn[0].cls='navbar-text';
1572         } else {
1573             cfg.cn[0].tag='a';
1574             cfg.cn[0].href=this.href||'#';
1575             cfg.cn[0].html=this.html;
1576         }
1577         
1578         if (this.badge !== '') {
1579             
1580             cfg.cn[0].cn=[
1581                 cfg.cn[0].html + ' ',
1582                 {
1583                     tag: 'span',
1584                     cls: 'badge',
1585                     html: this.badge
1586                 }
1587             ];
1588             cfg.cn[0].html=''
1589         }
1590          
1591         
1592         return cfg;
1593     },
1594     initEvents: function() {
1595        // Roo.log('init events?');
1596        // Roo.log(this.el.dom);
1597         this.el.select('a',true).on('click',
1598                 function(e) {
1599                     this.fireEvent('click', this);
1600                 },
1601                 this
1602         );
1603     }
1604    
1605 });
1606  
1607
1608  /*
1609  * - LGPL
1610  *
1611  * row
1612  * 
1613  */
1614
1615 /**
1616  * @class Roo.bootstrap.Row
1617  * @extends Roo.bootstrap.Component
1618  * Bootstrap Row class (contains columns...)
1619  * 
1620  * @constructor
1621  * Create a new Row
1622  * @param {Object} config The config object
1623  */
1624
1625 Roo.bootstrap.Row = function(config){
1626     Roo.bootstrap.Row.superclass.constructor.call(this, config);
1627 };
1628
1629 Roo.extend(Roo.bootstrap.Row, Roo.bootstrap.Component,  {
1630     
1631     autoCreate: {
1632         cls: 'row clearfix'
1633     }
1634     
1635     
1636 });
1637
1638  
1639
1640  /*
1641  * - LGPL
1642  *
1643  * element
1644  * 
1645  */
1646
1647 /**
1648  * @class Roo.bootstrap.Element
1649  * @extends Roo.bootstrap.Component
1650  * Bootstrap Element class
1651  * @cfg {String} html contents of the element
1652  * @cfg {String} tag tag of the element
1653  * @cfg {String} cls class of the element
1654  * 
1655  * @constructor
1656  * Create a new Element
1657  * @param {Object} config The config object
1658  */
1659
1660 Roo.bootstrap.Element = function(config){
1661     Roo.bootstrap.Element.superclass.constructor.call(this, config);
1662 };
1663
1664 Roo.extend(Roo.bootstrap.Element, Roo.bootstrap.Component,  {
1665     
1666     tag: 'div',
1667     cls: '',
1668     html: '',
1669     
1670     
1671     
1672     getAutoCreate : function(){
1673         var cfg = Roo.apply({}, Roo.bootstrap.Element.superclass.getAutoCreate.call(this));
1674         
1675         cfg = {
1676             tag: this.tag,
1677             cls: '',
1678             html: this.html
1679         }
1680         
1681         return cfg;
1682     }
1683    
1684 });
1685
1686  
1687
1688  /*
1689  * - LGPL
1690  *
1691  * pagination
1692  * 
1693  */
1694
1695 /**
1696  * @class Roo.bootstrap.Pagination
1697  * @extends Roo.bootstrap.Component
1698  * Bootstrap Pagination class
1699  * @cfg {String} size xs | sm | md | lg
1700  * @cfg {Boolean} inverse false | true
1701  * @cfg {Number} from pagination starting number
1702  * @cfg {Number} to pagination ending number
1703  * @cfg {String} align empty or left | right
1704  * @cfg {Number} active active page number
1705  * 
1706  * @constructor
1707  * Create a new Pagination
1708  * @param {Object} config The config object
1709  */
1710
1711 Roo.bootstrap.Pagination = function(config){
1712     Roo.bootstrap.Pagination.superclass.constructor.call(this, config);
1713 };
1714
1715 Roo.extend(Roo.bootstrap.Pagination, Roo.bootstrap.Component,  {
1716     
1717     cls: false,
1718     size: false,
1719     inverse: false,
1720     from: 1,
1721     to: 4,
1722     align: false,
1723     active: 1,
1724     
1725     getAutoCreate : function(){
1726         cfg = {
1727             tag: 'ul',
1728                 cls: 'pagination',
1729                 cn: []
1730         };
1731         if (this.inverse) {
1732             cfg.cls += ' inverse';
1733         }
1734         if (this.html) {
1735             cfg.html=this.html;
1736         }
1737         if (this.cls) {
1738             cfg.cls=this.cls;
1739         }
1740         cfg.cn[0]={
1741             tag: 'li',
1742             cn: [
1743                 {
1744                     tag: 'a',
1745                     href:'#',
1746                     html: '&laquo;'
1747                 }
1748             ]
1749         };
1750         var from=this.from>0?this.from:1;
1751         var to=this.to-from<=10?this.to:from+10;
1752         var active=this.active>=from&&this.active<=to?this.active:null;
1753         for (var i=from;i<=to;i++) {
1754             cfg.cn.push(
1755                 {
1756                     tag: 'li',
1757                     cls: active===i?'active':'',
1758                     cn: [
1759                         {
1760                             tag: 'a',
1761                             href: '#',
1762                             html: i
1763                         }
1764                     ]
1765                 }
1766             );
1767         }
1768         
1769         cfg.cn.push(
1770             {
1771                 tag: 'li',
1772                 cn: [
1773                     {
1774                        tag: 'a',
1775                        href: '#',
1776                        html: '&raquo;'
1777                     }
1778                 ]
1779             }
1780         );
1781         
1782         return cfg;
1783     }
1784    
1785 });
1786
1787  
1788
1789  /*
1790  * - LGPL
1791  *
1792  * slider
1793  * 
1794  */
1795
1796
1797 /**
1798  * @class Roo.bootstrap.Slider
1799  * @extends Roo.bootstrap.Component
1800  * Bootstrap Slider class
1801  *    
1802  * @constructor
1803  * Create a new Slider
1804  * @param {Object} config The config object
1805  */
1806
1807 Roo.bootstrap.Slider = function(config){
1808     Roo.bootstrap.Slider.superclass.constructor.call(this, config);
1809 };
1810
1811 Roo.extend(Roo.bootstrap.Slider, Roo.bootstrap.Component,  {
1812     
1813     getAutoCreate : function(){
1814         
1815         var cfg = {
1816             tag: 'div',
1817             cls: 'slider slider-sample1 vertical-handler ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all',
1818             cn: [
1819                 {
1820                     tag: 'a',
1821                     cls: 'ui-slider-handle ui-state-default ui-corner-all'
1822                 }
1823             ]
1824         }
1825         
1826         return cfg;
1827     }
1828    
1829 });
1830
1831  /*
1832  * - LGPL
1833  *
1834  * table
1835  * 
1836  */
1837
1838 /**
1839  * @class Roo.bootstrap.Table
1840  * @extends Roo.bootstrap.Component
1841  * Bootstrap Table class
1842  * 
1843  * @constructor
1844  * Create a new Table
1845  * @param {Object} config The config object
1846  */
1847
1848 Roo.bootstrap.Table = function(config){
1849     Roo.bootstrap.Table.superclass.constructor.call(this, config);
1850 };
1851
1852 Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component,  {
1853     
1854     html: false,
1855     cls: false,
1856     
1857     getAutoCreate : function(){
1858         var cfg = Roo.apply({}, Roo.bootstrap.Table.superclass.getAutoCreate.call(this));
1859         
1860         cfg = {
1861             tag: 'table',
1862             cn: [
1863                 {
1864                     tag: 'tbody'
1865                 }
1866             ]
1867         }
1868         if (this.html) {
1869             cfg.html=this.html
1870         }
1871         if (this.cls) {
1872             cfg.cls=this.cls
1873         }
1874         
1875         return cfg;
1876     }
1877    
1878 });
1879
1880  
1881
1882  /*
1883  * - LGPL
1884  *
1885  * table cell
1886  * 
1887  */
1888
1889 /**
1890  * @class Roo.bootstrap.TableCell
1891  * @extends Roo.bootstrap.Component
1892  * Bootstrap TableCell class
1893  * 
1894  * @constructor
1895  * Create a new TableCell
1896  * @param {Object} config The config object
1897  */
1898
1899 Roo.bootstrap.TableCell = function(config){
1900     Roo.bootstrap.TableCell.superclass.constructor.call(this, config);
1901 };
1902
1903 Roo.extend(Roo.bootstrap.TableCell, Roo.bootstrap.Component,  {
1904     
1905     getAutoCreate : function(){
1906         var cfg = Roo.apply({}, Roo.bootstrap.TableCell.superclass.getAutoCreate.call(this));
1907         
1908         cfg = {
1909             tag: 'td'
1910         }
1911         if (this.html) {
1912             cfg.html=this.html
1913         }
1914         if (this.cls) {
1915             cfg.cls=this.cls
1916         }
1917         
1918         return cfg;
1919     }
1920    
1921 });
1922
1923  
1924
1925  /*
1926  * - LGPL
1927  *
1928  * table row
1929  * 
1930  */
1931
1932 /**
1933  * @class Roo.bootstrap.TableRow
1934  * @extends Roo.bootstrap.Component
1935  * Bootstrap TableRow class
1936  * 
1937  * @constructor
1938  * Create a new TableRow
1939  * @param {Object} config The config object
1940  */
1941
1942 Roo.bootstrap.TableRow = function(config){
1943     Roo.bootstrap.TableRow.superclass.constructor.call(this, config);
1944 };
1945
1946 Roo.extend(Roo.bootstrap.TableRow, Roo.bootstrap.Component,  {
1947     
1948     getAutoCreate : function(){
1949         var cfg = Roo.apply({}, Roo.bootstrap.TableRow.superclass.getAutoCreate.call(this));
1950         
1951         cfg = {
1952             tag: 'tr'
1953         }
1954         
1955         return cfg;
1956     }
1957    
1958 });
1959
1960  
1961
1962  /*
1963  * - LGPL
1964  *
1965  * form
1966  * 
1967  */
1968
1969 /**
1970  * @class Roo.bootstrap.Form
1971  * @extends Roo.bootstrap.Component
1972  * Bootstrap Form class
1973  * @cfg {String} method  GET | POST (default POST)
1974  * @cfg {String} labelAlign top | left (default top)
1975  * 
1976  * @constructor
1977  * Create a new Form
1978  * @param {Object} config The config object
1979  */
1980
1981
1982 Roo.bootstrap.Form = function(config){
1983     Roo.bootstrap.Form.superclass.constructor.call(this, config);
1984     this.addEvents({
1985         /**
1986          * @event clientvalidation
1987          * If the monitorValid config option is true, this event fires repetitively to notify of valid state
1988          * @param {Form} this
1989          * @param {Boolean} valid true if the form has passed client-side validation
1990          */
1991         clientvalidation: true,
1992         /**
1993          * @event rendered
1994          * Fires when the form is rendered
1995          * @param {Roo.form.Form} form
1996          */
1997         rendered : true
1998     });
1999 };
2000
2001 Roo.extend(Roo.bootstrap.Form, Roo.bootstrap.Component,  {
2002       
2003     
2004      getAutoCreate : function(){
2005         
2006         var cfg = {
2007             tag: 'form',
2008             method : this.method || 'POST',
2009             id : this.id || Roo.id(),
2010             cls : ''
2011         }
2012         
2013         if (this.labelAlign == 'left' ) {
2014             cfg.cls += ' form-horizontal';
2015         }
2016         return cfg;
2017     }
2018     
2019 });
2020
2021  
2022 /*
2023  * Based on:
2024  * Ext JS Library 1.1.1
2025  * Copyright(c) 2006-2007, Ext JS, LLC.
2026  *
2027  * Originally Released Under LGPL - original licence link has changed is not relivant.
2028  *
2029  * Fork - LGPL
2030  * <script type="text/javascript">
2031  */
2032 /**
2033  * @class Roo.form.VTypes
2034  * Overridable validation definitions. The validations provided are basic and intended to be easily customizable and extended.
2035  * @singleton
2036  */
2037 Roo.form.VTypes = function(){
2038     // closure these in so they are only created once.
2039     var alpha = /^[a-zA-Z_]+$/;
2040     var alphanum = /^[a-zA-Z0-9_]+$/;
2041     var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;
2042     var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
2043
2044     // All these messages and functions are configurable
2045     return {
2046         /**
2047          * The function used to validate email addresses
2048          * @param {String} value The email address
2049          */
2050         'email' : function(v){
2051             return email.test(v);
2052         },
2053         /**
2054          * The error text to display when the email validation function returns false
2055          * @type String
2056          */
2057         'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
2058         /**
2059          * The keystroke filter mask to be applied on email input
2060          * @type RegExp
2061          */
2062         'emailMask' : /[a-z0-9_\.\-@]/i,
2063
2064         /**
2065          * The function used to validate URLs
2066          * @param {String} value The URL
2067          */
2068         'url' : function(v){
2069             return url.test(v);
2070         },
2071         /**
2072          * The error text to display when the url validation function returns false
2073          * @type String
2074          */
2075         'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
2076         
2077         /**
2078          * The function used to validate alpha values
2079          * @param {String} value The value
2080          */
2081         'alpha' : function(v){
2082             return alpha.test(v);
2083         },
2084         /**
2085          * The error text to display when the alpha validation function returns false
2086          * @type String
2087          */
2088         'alphaText' : 'This field should only contain letters and _',
2089         /**
2090          * The keystroke filter mask to be applied on alpha input
2091          * @type RegExp
2092          */
2093         'alphaMask' : /[a-z_]/i,
2094
2095         /**
2096          * The function used to validate alphanumeric values
2097          * @param {String} value The value
2098          */
2099         'alphanum' : function(v){
2100             return alphanum.test(v);
2101         },
2102         /**
2103          * The error text to display when the alphanumeric validation function returns false
2104          * @type String
2105          */
2106         'alphanumText' : 'This field should only contain letters, numbers and _',
2107         /**
2108          * The keystroke filter mask to be applied on alphanumeric input
2109          * @type RegExp
2110          */
2111         'alphanumMask' : /[a-z0-9_]/i
2112     };
2113 }();/*
2114  * - LGPL
2115  *
2116  * Input
2117  * 
2118  */
2119
2120 /**
2121  * @class Roo.bootstrap.Input
2122  * @extends Roo.bootstrap.Component
2123  * Bootstrap Input class
2124  * @cfg {Boolean} disabled is it disabled
2125  * @cfg {String} fieldLabel - the label associated
2126  * @cfg {String} inputType button | checkbox | email | file | hidden | image | number | password | radio | range | reset | search | submit | text
2127  * @cfg {String} name name of the input
2128  * @cfg {string} fieldLabel - the label associated
2129  * @cfg {string}  inputType - input / file submit ...
2130  * @cfg {string} placeholder - placeholder to put in text.
2131  * @cfg {string}  before - input group add on before
2132  * @cfg {string} after - input group add on after
2133  * 
2134  * 
2135  * @constructor
2136  * Create a new Input
2137  * @param {Object} config The config object
2138  */
2139
2140 Roo.bootstrap.Input = function(config){
2141     Roo.bootstrap.Input.superclass.constructor.call(this, config);
2142    
2143         this.addEvents({
2144             /**
2145              * @event focus
2146              * Fires when this field receives input focus.
2147              * @param {Roo.form.Field} this
2148              */
2149             focus : true,
2150             /**
2151              * @event blur
2152              * Fires when this field loses input focus.
2153              * @param {Roo.form.Field} this
2154              */
2155             blur : true,
2156             /**
2157              * @event specialkey
2158              * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed.  You can check
2159              * {@link Roo.EventObject#getKey} to determine which key was pressed.
2160              * @param {Roo.form.Field} this
2161              * @param {Roo.EventObject} e The event object
2162              */
2163             specialkey : true,
2164             /**
2165              * @event change
2166              * Fires just before the field blurs if the field value has changed.
2167              * @param {Roo.form.Field} this
2168              * @param {Mixed} newValue The new value
2169              * @param {Mixed} oldValue The original value
2170              */
2171             change : true,
2172             /**
2173              * @event invalid
2174              * Fires after the field has been marked as invalid.
2175              * @param {Roo.form.Field} this
2176              * @param {String} msg The validation message
2177              */
2178             invalid : true,
2179             /**
2180              * @event valid
2181              * Fires after the field has been validated with no errors.
2182              * @param {Roo.form.Field} this
2183              */
2184             valid : true,
2185              /**
2186              * @event keyup
2187              * Fires after the key up
2188              * @param {Roo.form.Field} this
2189              * @param {Roo.EventObject}  e The event Object
2190              */
2191             keyup : true
2192         });
2193 };
2194
2195 Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component,  {
2196      /**
2197      * @cfg {String/Boolean} validationEvent The event that should initiate field validation. Set to false to disable
2198       automatic validation (defaults to "keyup").
2199      */
2200     validationEvent : "keyup",
2201      /**
2202      * @cfg {Boolean} validateOnBlur Whether the field should validate when it loses focus (defaults to true).
2203      */
2204     validateOnBlur : true,
2205     /**
2206      * @cfg {Number} validationDelay The length of time in milliseconds after user input begins until validation is initiated (defaults to 250)
2207      */
2208     validationDelay : 250,
2209      /**
2210      * @cfg {String} focusClass The CSS class to use when the field receives focus (defaults to "x-form-focus")
2211      */
2212     focusClass : "x-form-focus",  // not needed???
2213     
2214        
2215     /**
2216      * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to "x-form-invalid")
2217      */
2218     invalidClass : "has-error",
2219     
2220     /**
2221      * @cfg {Boolean} selectOnFocus True to automatically select any existing field text when the field receives input focus (defaults to false)
2222      */
2223     selectOnFocus : false,
2224     
2225      /**
2226      * @cfg {String} maskRe An input mask regular expression that will be used to filter keystrokes that don't match (defaults to null)
2227      */
2228     maskRe : null,
2229        /**
2230      * @cfg {String} vtype A validation type name as defined in {@link Roo.form.VTypes} (defaults to null)
2231      */
2232     vtype : null,
2233     
2234       /**
2235      * @cfg {Boolean} disableKeyFilter True to disable input keystroke filtering (defaults to false)
2236      */
2237     disableKeyFilter : false,
2238     
2239        /**
2240      * @cfg {Boolean} disabled True to disable the field (defaults to false).
2241      */
2242     disabled : false,
2243      /**
2244      * @cfg {Boolean} allowBlank False to validate that the value length > 0 (defaults to true)
2245      */
2246     allowBlank : true,
2247     /**
2248      * @cfg {String} blankText Error text to display if the allow blank validation fails (defaults to "This field is required")
2249      */
2250     blankText : "This field is required",
2251     
2252      /**
2253      * @cfg {Number} minLength Minimum input field length required (defaults to 0)
2254      */
2255     minLength : 0,
2256     /**
2257      * @cfg {Number} maxLength Maximum input field length allowed (defaults to Number.MAX_VALUE)
2258      */
2259     maxLength : Number.MAX_VALUE,
2260     /**
2261      * @cfg {String} minLengthText Error text to display if the minimum length validation fails (defaults to "The minimum length for this field is {minLength}")
2262      */
2263     minLengthText : "The minimum length for this field is {0}",
2264     /**
2265      * @cfg {String} maxLengthText Error text to display if the maximum length validation fails (defaults to "The maximum length for this field is {maxLength}")
2266      */
2267     maxLengthText : "The maximum length for this field is {0}",
2268   
2269     
2270     /**
2271      * @cfg {Function} validator A custom validation function to be called during field validation (defaults to null).
2272      * If available, this function will be called only after the basic validators all return true, and will be passed the
2273      * current field value and expected to return boolean true if the value is valid or a string error message if invalid.
2274      */
2275     validator : null,
2276     /**
2277      * @cfg {RegExp} regex A JavaScript RegExp object to be tested against the field value during validation (defaults to null).
2278      * If available, this regex will be evaluated only after the basic validators all return true, and will be passed the
2279      * current field value.  If the test fails, the field will be marked invalid using {@link #regexText}.
2280      */
2281     regex : null,
2282     /**
2283      * @cfg {String} regexText The error text to display if {@link #regex} is used and the test fails during validation (defaults to "")
2284      */
2285     regexText : "",
2286     
2287     
2288     
2289     fieldLabel : '',
2290     inputType : 'text',
2291     
2292     name : false,
2293     placeholder: false,
2294     before : false,
2295     after : false,
2296     
2297     // private
2298     hasFocus : false,
2299     preventMark: false,
2300     
2301     getAutoCreate : function(){
2302         
2303         var parent = this.parent();
2304         
2305         var align = parent.labelAlign;
2306         
2307         var id = Roo.id();
2308         
2309         var cfg = {
2310             cls: 'form-group' //input-group
2311         };
2312         
2313         var input =  {
2314             tag: 'input',
2315             id : id,
2316             type : this.inputType,
2317             cls : 'form-control',
2318             placeholder : this.placeholder || '' 
2319             
2320         };
2321         if (this.name) {
2322             input.name = name;
2323         }
2324         
2325         var inputblock = input;
2326         
2327         if (this.before || this.after) {
2328             
2329             inputblock = {
2330                 cls : 'input-group',
2331                 cn :  [] 
2332             };
2333             if (this.before) {
2334                 inputblock.cn.push({
2335                     tag :'span',
2336                     cls : 'input-group-addon',
2337                     html : this.before
2338                 });
2339             }
2340             inputblock.cn.push(input);
2341             if (this.after) {
2342                 inputblock.cn.push({
2343                     tag :'span',
2344                     cls : 'input-group-addon',
2345                     html : this.after
2346                 });
2347             }
2348             
2349         }
2350         
2351         Roo.log(align);
2352         Roo.log(this.fieldLabel.length);
2353         
2354         if (align ==='left' && this.fieldLabel.length) {
2355                 Roo.log("left and has label");
2356                 cfg.cn = [
2357                     
2358                     {
2359                         tag: 'label',
2360                         'for' :  id,
2361                         cls : 'col-sm-2 control-label',
2362                         html : this.fieldLabel
2363                         
2364                     },
2365                     {
2366                         cls : "col-sm-10", 
2367                         cn: [
2368                             inputblock
2369                         ]
2370                     }
2371                     
2372                 ];
2373         } else if ( this.fieldLabel.length) {
2374                 Roo.log(" label");
2375                  cfg.cn = [
2376                    
2377                     {
2378                         tag: 'label',
2379                         //cls : 'input-group-addon',
2380                         html : this.fieldLabel
2381                         
2382                     },
2383                     
2384                     inputblock
2385                     
2386                 ];
2387
2388         } else {
2389             
2390                    Roo.log(" no label && no align");
2391                 cfg.cn = [
2392                     
2393                         inputblock
2394                     
2395                 ];
2396                 
2397                 
2398         }
2399          
2400         
2401         
2402         
2403         if (this.disabled) {
2404             input.disabled=true;
2405         }
2406         return cfg;
2407         
2408     },
2409     /**
2410      * return the real input element.
2411      */
2412     inputEl: function ()
2413     {
2414         return this.el.select('input.form-control',true).first();
2415     },
2416     setDisabled : function(v)
2417     {
2418         var i  = this.inputEl().dom;
2419         if (v) {
2420             i.removeAttribute('disabled');
2421             return;
2422             
2423         }
2424         i.setAttribute('disabled','true');
2425     },
2426     initEvents : function()
2427     {
2428         
2429         this.inputEl().on("keydown" , this.fireKey,  this);
2430         this.inputEl().on("focus", this.onFocus,  this);
2431         this.inputEl().on("blur", this.onBlur,  this);
2432         this.inputEl().relayEvent('keyup', this);
2433
2434         // reference to original value for reset
2435         this.originalValue = this.getValue();
2436         //Roo.form.TextField.superclass.initEvents.call(this);
2437         if(this.validationEvent == 'keyup'){
2438             this.validationTask = new Roo.util.DelayedTask(this.validate, this);
2439             this.inputEl().on('keyup', this.filterValidation, this);
2440         }
2441         else if(this.validationEvent !== false){
2442             this.inputEl().on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
2443         }
2444         
2445         if(this.selectOnFocus){
2446             this.on("focus", this.preFocus, this);
2447             
2448         }
2449         if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Roo.form.VTypes[this.vtype+'Mask']))){
2450             this.inputEl().on("keypress", this.filterKeys, this);
2451         }
2452        /* if(this.grow){
2453             this.el.on("keyup", this.onKeyUp,  this, {buffer:50});
2454             this.el.on("click", this.autoSize,  this);
2455         }
2456         */
2457         if(this.inputEl().is('input[type=password]') && Roo.isSafari){
2458             this.inputEl().on('keydown', this.SafariOnKeyDown, this);
2459         }
2460         
2461     },
2462     filterValidation : function(e){
2463         if(!e.isNavKeyPress()){
2464             this.validationTask.delay(this.validationDelay);
2465         }
2466     },
2467      /**
2468      * Validates the field value
2469      * @return {Boolean} True if the value is valid, else false
2470      */
2471     validate : function(){
2472         //if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
2473         if(this.disabled || this.validateValue(this.getRawValue())){
2474             this.clearInvalid();
2475             return true;
2476         }
2477         return false;
2478     },
2479     
2480     
2481     /**
2482      * Validates a value according to the field's validation rules and marks the field as invalid
2483      * if the validation fails
2484      * @param {Mixed} value The value to validate
2485      * @return {Boolean} True if the value is valid, else false
2486      */
2487     validateValue : function(value){
2488         if(value.length < 1)  { // if it's blank
2489              if(this.allowBlank){
2490                 this.clearInvalid();
2491                 return true;
2492              }else{
2493                 this.markInvalid(this.blankText);
2494                 return false;
2495              }
2496         }
2497         if(value.length < this.minLength){
2498             this.markInvalid(String.format(this.minLengthText, this.minLength));
2499             return false;
2500         }
2501         if(value.length > this.maxLength){
2502             this.markInvalid(String.format(this.maxLengthText, this.maxLength));
2503             return false;
2504         }
2505         if(this.vtype){
2506             var vt = Roo.form.VTypes;
2507             if(!vt[this.vtype](value, this)){
2508                 this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
2509                 return false;
2510             }
2511         }
2512         if(typeof this.validator == "function"){
2513             var msg = this.validator(value);
2514             if(msg !== true){
2515                 this.markInvalid(msg);
2516                 return false;
2517             }
2518         }
2519         if(this.regex && !this.regex.test(value)){
2520             this.markInvalid(this.regexText);
2521             return false;
2522         }
2523         return true;
2524     },
2525
2526     
2527     
2528      // private
2529     fireKey : function(e){
2530         //Roo.log('field ' + e.getKey());
2531         if(e.isNavKeyPress()){
2532             this.fireEvent("specialkey", this, e);
2533         }
2534     },
2535     onFocus : function(){
2536         if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
2537            // this.el.addClass(this.focusClass);
2538         }
2539         if(!this.hasFocus){
2540             this.hasFocus = true;
2541             this.startValue = this.getValue();
2542             this.fireEvent("focus", this);
2543         }
2544     },
2545     
2546     beforeBlur : Roo.emptyFn,
2547
2548     
2549     // private
2550     onBlur : function(){
2551         this.beforeBlur();
2552         if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
2553             //this.el.removeClass(this.focusClass);
2554         }
2555         this.hasFocus = false;
2556         if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
2557             this.validate();
2558         }
2559         var v = this.getValue();
2560         if(String(v) !== String(this.startValue)){
2561             this.fireEvent('change', this, v, this.startValue);
2562         }
2563         this.fireEvent("blur", this);
2564     },
2565      /**
2566      * Returns the normalized data value (undefined or emptyText will be returned as '').  To return the raw value see {@link #getRawValue}.
2567      * @return {Mixed} value The field value
2568      */
2569     getValue : function(){
2570         var v = this.inputEl().getValue();
2571         return v;
2572     },
2573     /**
2574      * Returns the raw data value which may or may not be a valid, defined value.  To return a normalized value see {@link #getValue}.
2575      * @return {Mixed} value The field value
2576      */
2577     getRawValue : function(){
2578         var v = this.inputEl().getValue();
2579         
2580         return v;
2581     },
2582     /**
2583      * Sets a data value into the field and validates it.  To set the value directly without validation see {@link #setRawValue}.
2584      * @param {Mixed} value The value to set
2585      */
2586     setValue : function(v){
2587         this.value = v;
2588         if(this.rendered){
2589             this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
2590             this.validate();
2591         }
2592     },
2593     
2594     /*
2595     processValue : function(value){
2596         if(this.stripCharsRe){
2597             var newValue = value.replace(this.stripCharsRe, '');
2598             if(newValue !== value){
2599                 this.setRawValue(newValue);
2600                 return newValue;
2601             }
2602         }
2603         return value;
2604     },
2605   */
2606     preFocus : function(){
2607         
2608         if(this.selectOnFocus){
2609             this.inputEl().dom.select();
2610         }
2611     },
2612     filterKeys : function(e){
2613         var k = e.getKey();
2614         if(!Roo.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
2615             return;
2616         }
2617         var c = e.getCharCode(), cc = String.fromCharCode(c);
2618         if(Roo.isIE && (e.isSpecialKey() || !cc)){
2619             return;
2620         }
2621         if(!this.maskRe.test(cc)){
2622             e.stopEvent();
2623         }
2624     },
2625      /**
2626      * Clear any invalid styles/messages for this field
2627      */
2628     clearInvalid : function(){
2629         
2630         if(!this.el || this.preventMark){ // not rendered
2631             return;
2632         }
2633         this.el.removeClass(this.invalidClass);
2634         /*
2635         switch(this.msgTarget){
2636             case 'qtip':
2637                 this.el.dom.qtip = '';
2638                 break;
2639             case 'title':
2640                 this.el.dom.title = '';
2641                 break;
2642             case 'under':
2643                 if(this.errorEl){
2644                     Roo.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
2645                 }
2646                 break;
2647             case 'side':
2648                 if(this.errorIcon){
2649                     this.errorIcon.dom.qtip = '';
2650                     this.errorIcon.hide();
2651                     this.un('resize', this.alignErrorIcon, this);
2652                 }
2653                 break;
2654             default:
2655                 var t = Roo.getDom(this.msgTarget);
2656                 t.innerHTML = '';
2657                 t.style.display = 'none';
2658                 break;
2659         }
2660         */
2661         this.fireEvent('valid', this);
2662     },
2663      /**
2664      * Mark this field as invalid
2665      * @param {String} msg The validation message
2666      */
2667     markInvalid : function(msg){
2668         if(!this.el  || this.preventMark){ // not rendered
2669             return;
2670         }
2671         this.el.addClass(this.invalidClass);
2672         /*
2673         msg = msg || this.invalidText;
2674         switch(this.msgTarget){
2675             case 'qtip':
2676                 this.el.dom.qtip = msg;
2677                 this.el.dom.qclass = 'x-form-invalid-tip';
2678                 if(Roo.QuickTips){ // fix for floating editors interacting with DND
2679                     Roo.QuickTips.enable();
2680                 }
2681                 break;
2682             case 'title':
2683                 this.el.dom.title = msg;
2684                 break;
2685             case 'under':
2686                 if(!this.errorEl){
2687                     var elp = this.el.findParent('.x-form-element', 5, true);
2688                     this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
2689                     this.errorEl.setWidth(elp.getWidth(true)-20);
2690                 }
2691                 this.errorEl.update(msg);
2692                 Roo.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
2693                 break;
2694             case 'side':
2695                 if(!this.errorIcon){
2696                     var elp = this.el.findParent('.x-form-element', 5, true);
2697                     this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
2698                 }
2699                 this.alignErrorIcon();
2700                 this.errorIcon.dom.qtip = msg;
2701                 this.errorIcon.dom.qclass = 'x-form-invalid-tip';
2702                 this.errorIcon.show();
2703                 this.on('resize', this.alignErrorIcon, this);
2704                 break;
2705             default:
2706                 var t = Roo.getDom(this.msgTarget);
2707                 t.innerHTML = msg;
2708                 t.style.display = this.msgDisplay;
2709                 break;
2710         }
2711         */
2712         this.fireEvent('invalid', this, msg);
2713     },
2714     // private
2715     SafariOnKeyDown : function(event)
2716     {
2717         // this is a workaround for a password hang bug on chrome/ webkit.
2718         
2719         var isSelectAll = false;
2720         
2721         if(this.inputEl().dom.selectionEnd > 0){
2722             isSelectAll = (this.inputEl().dom.selectionEnd - this.inputEl().dom.selectionStart - this.getValue().length == 0) ? true : false;
2723         }
2724         if(((event.getKey() == 8 || event.getKey() == 46) && this.getValue().length ==1)){ // backspace and delete key
2725             event.preventDefault();
2726             this.setValue('');
2727             return;
2728         }
2729         
2730         if(isSelectAll){ // backspace and delete key
2731             
2732             event.preventDefault();
2733             // this is very hacky as keydown always get's upper case.
2734             //
2735             var cc = String.fromCharCode(event.getCharCode());
2736             this.setValue( event.shiftKey ?  cc : cc.toLowerCase());
2737             
2738         }
2739         
2740         
2741     }
2742 });
2743
2744