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