4 * base class for bootstrap elements.
8 Roo.bootstrap = Roo.bootstrap || {};
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 * @cfg {Boolean} can_build_overlaid True if element can be rebuild from a HTML page
17 * @cfg {string} dataId cutomer id
18 * @cfg {string} name Specifies name attribute
21 * Do not use directly - it does not do anything..
22 * @param {Object} config The config object
27 Roo.bootstrap.Component = function(config){
28 Roo.bootstrap.Component.superclass.constructor.call(this, config);
31 Roo.extend(Roo.bootstrap.Component, Roo.BoxComponent, {
34 allowDomMove : false, // to stop relocations in parent onRender...
42 initEvents : function() { },
48 can_build_overlaid : true,
55 // returns the parent component..
56 return Roo.ComponentMgr.get(this.parentId)
62 onRender : function(ct, position)
64 // Roo.log("Call onRender: " + this.xtype);
66 Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
69 if (this.el.attr('xtype')) {
70 this.el.attr('xtypex', this.el.attr('xtype'));
71 this.el.dom.removeAttribute('xtype');
81 var cfg = Roo.apply({}, this.getAutoCreate());
84 // fill in the extra attributes
85 if (this.xattr && typeof(this.xattr) =='object') {
86 for (var i in this.xattr) {
87 cfg[i] = this.xattr[i];
92 cfg.dataId = this.dataId;
96 cfg.cls = (typeof(cfg.cls) == 'undefined') ? this.cls : cfg.cls + ' ' + this.cls;
99 if (this.style) { // fixme needs to support more complex style data.
100 cfg.style = this.style;
104 cfg.name = this.name;
107 this.el = ct.createChild(cfg, position);
109 if(this.tabIndex !== undefined){
110 this.el.dom.setAttribute('tabIndex', this.tabIndex);
117 getChildContainer : function()
123 addxtype : function(tree,cntr)
127 cn = Roo.factory(tree);
129 cn.parentType = this.xtype; //??
130 cn.parentId = this.id;
132 cntr = (typeof(cntr) == 'undefined' ) ? 'getChildContainer' : cntr;
134 var has_flexy_each = (typeof(tree['flexy:foreach']) != 'undefined');
136 var has_flexy_if = (typeof(tree['flexy:if']) != 'undefined');
138 var build_from_html = Roo.XComponent.build_from_html;
140 var is_body = (tree.xtype == 'Body') ;
142 var page_has_body = (Roo.get(document.body).attr('xtype') == 'Roo.bootstrap.Body');
144 var self_cntr_el = Roo.get(this[cntr]());
146 if (!has_flexy_each || !build_from_html || is_body || !page_has_body) {
147 if(!has_flexy_if || typeof(tree.name) == 'undefined' || !build_from_html || is_body || !page_has_body){
148 return this.addxtypeChild(tree,cntr);
151 var echild =self_cntr_el ? self_cntr_el.child('>*[name=' + tree.name + ']') : false;
154 return this.addxtypeChild(Roo.apply({}, tree),cntr);
157 Roo.log('skipping render');
165 var echild =self_cntr_el ? self_cntr_el.child('>*[xtype]') : false;
171 if (echild && echild.attr('xtype').split('.').pop() != cn.xtype) {
175 ret = this.addxtypeChild(Roo.apply({}, tree),cntr);
180 addxtypeChild : function (tree, cntr)
182 Roo.log('addxtypeChild:' + cntr);
184 cntr = (typeof(cntr) == 'undefined' ) ? 'getChildContainer' : cntr;
187 var has_flexy = (typeof(tree['flexy:if']) != 'undefined') ||
188 (typeof(tree['flexy:foreach']) != 'undefined');
193 // render the element if it's not BODY.
194 if (tree.xtype != 'Body') {
196 cn = Roo.factory(tree);
198 cn.parentType = this.xtype; //??
199 cn.parentId = this.id;
201 var build_from_html = Roo.XComponent.build_from_html;
204 // does the container contain child eleemnts with 'xtype' attributes.
205 // that match this xtype..
206 // note - when we render we create these as well..
207 // so we should check to see if body has xtype set.
208 if (Roo.get(document.body).attr('xtype') == 'Roo.bootstrap.Body') {
210 var self_cntr_el = Roo.get(this[cntr]());
211 var echild =self_cntr_el ? self_cntr_el.child('>*[xtype]') : false;
213 if (echild && echild.attr('xtype').split('.').pop() == cn.xtype) {
214 // Roo.log("found child for " + this.xtype +": " + echild.attr('xtype') );
220 //echild.dom.removeAttribute('xtype');
222 Roo.log("MISSING " + cn.xtype + " on child of " + (this.el ? this.el.attr('xbuilderid') : 'no parent'));
229 // if object has flexy:if - then it may or may not be rendered.
230 if (build_from_html && has_flexy && !cn.el && cn.can_build_overlaid) {
231 // skip a flexy if element.
232 Roo.log('skipping render');
235 // actually if flexy:foreach is found, we really want to create
236 // multiple copies here...
238 //Roo.log(this[cntr]());
239 cn.render(this[cntr]());
241 // then add the element..
248 if (typeof (tree.menu) != 'undefined') {
249 tree.menu.parentType = cn.xtype;
250 tree.menu.triggerEl = cn.el;
251 nitems.push(cn.addxtype(Roo.apply({}, tree.menu)));
255 if (!tree.items || !tree.items.length) {
259 var items = tree.items;
262 //Roo.log(items.length);
264 for(var i =0;i < items.length;i++) {
265 nitems.push(cn.addxtype(Roo.apply({}, items[i])));
286 * @class Roo.bootstrap.Body
287 * @extends Roo.bootstrap.Component
288 * Bootstrap Body class
292 * @param {Object} config The config object
295 Roo.bootstrap.Body = function(config){
296 Roo.bootstrap.Body.superclass.constructor.call(this, config);
297 this.el = Roo.get(document.body);
298 if (this.cls && this.cls.length) {
299 Roo.get(document.body).addClass(this.cls);
303 Roo.extend(Roo.bootstrap.Body, Roo.bootstrap.Component, {
308 onRender : function(ct, position)
310 /* Roo.log("Roo.bootstrap.Body - onRender");
311 if (this.cls && this.cls.length) {
312 Roo.get(document.body).addClass(this.cls);
332 * @class Roo.bootstrap.ButtonGroup
333 * @extends Roo.bootstrap.Component
334 * Bootstrap ButtonGroup class
335 * @cfg {String} size lg | sm | xs (default empty normal)
336 * @cfg {String} align vertical | justified (default none)
337 * @cfg {String} direction up | down (default down)
338 * @cfg {Boolean} toolbar false | true
339 * @cfg {Boolean} btn true | false
344 * @param {Object} config The config object
347 Roo.bootstrap.ButtonGroup = function(config){
348 Roo.bootstrap.ButtonGroup.superclass.constructor.call(this, config);
351 Roo.extend(Roo.bootstrap.ButtonGroup, Roo.bootstrap.Component, {
359 getAutoCreate : function(){
365 cfg.html = this.html || cfg.html;
376 if (['vertical','justified'].indexOf(this.align)!==-1) {
377 cfg.cls = 'btn-group-' + this.align;
379 if (this.align == 'justified') {
380 console.log(this.items);
384 if (['lg','sm','xs'].indexOf(this.size)!==-1) {
385 cfg.cls += ' btn-group-' + this.size;
388 if (this.direction == 'up') {
389 cfg.cls += ' dropup' ;
405 * @class Roo.bootstrap.Button
406 * @extends Roo.bootstrap.Component
407 * Bootstrap Button class
408 * @cfg {String} html The button content
409 * @cfg {String} weight default (or empty) | primary | success | info | warning | danger | link
410 * @cfg {String} size empty | lg | sm | xs
411 * @cfg {String} tag empty | a | input | submit
412 * @cfg {String} href empty or href
413 * @cfg {Boolean} disabled false | true
414 * @cfg {Boolean} isClose false | true
415 * @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
416 * @cfg {String} badge text for badge
417 * @cfg {String} theme default (or empty) | glow
418 * @cfg {Boolean} inverse false | true
419 * @cfg {Boolean} toggle false | true
420 * @cfg {String} ontext text for on toggle state
421 * @cfg {String} offtext text for off toggle state
422 * @cfg {Boolean} defaulton true | false
423 * @cfg {Boolean} preventDefault (true | false) default true
424 * @cfg {Boolean} removeClass true | false remove the standard class..
425 * @cfg {String} target (_self|_blank|_parent|_top)target for a href.
428 * Create a new button
429 * @param {Object} config The config object
433 Roo.bootstrap.Button = function(config){
434 Roo.bootstrap.Button.superclass.constructor.call(this, config);
439 * When a butotn is pressed
440 * @param {Roo.EventObject} e
445 * After the button has been toggles
446 * @param {Roo.EventObject} e
447 * @param {boolean} pressed (also available as button.pressed)
453 Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, {
471 preventDefault: true,
480 getAutoCreate : function(){
488 if (['a', 'button', 'input', 'submit'].indexOf(this.tag) < 0) {
489 throw "Invalid value for tag: " + this.tag + ". must be a, button, input or submit.";
494 cfg.html = '<span class="roo-button-text">' + (this.html || cfg.html) + '</span>';
496 if (this.toggle == true) {
499 cls: 'slider-frame roo-button',
504 'data-off-text':'OFF',
505 cls: 'slider-button',
511 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
512 cfg.cls += ' '+this.weight;
521 cfg["aria-hidden"] = true;
523 cfg.html = "×";
529 if (this.theme==='default') {
530 cfg.cls = 'btn roo-button';
532 //if (this.parentType != 'Navbar') {
533 this.weight = this.weight.length ? this.weight : 'default';
535 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
537 cfg.cls += ' btn-' + this.weight;
539 } else if (this.theme==='glow') {
542 cfg.cls = 'btn-glow roo-button';
544 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
546 cfg.cls += ' ' + this.weight;
552 this.cls += ' inverse';
557 cfg.cls += ' active';
561 cfg.disabled = 'disabled';
565 Roo.log('changing to ul' );
567 this.glyphicon = 'caret';
570 cfg.cls += this.size.length ? (' btn-' + this.size) : '';
572 //gsRoo.log(this.parentType);
573 if (this.parentType === 'Navbar' && !this.parent().bar) {
574 Roo.log('changing to li?');
583 href : this.href || '#'
586 cfg.cn[0].html = this.html + ' <span class="caret"></span>';
587 cfg.cls += ' dropdown';
594 cfg.cls += this.parentType === 'Navbar' ? ' navbar-btn' : '';
596 if (this.glyphicon) {
597 cfg.html = ' ' + cfg.html;
602 cls: 'glyphicon glyphicon-' + this.glyphicon
612 // cfg.cls='btn roo-button';
616 var value = cfg.html;
621 cls: 'glyphicon glyphicon-' + this.glyphicon,
640 cfg.cls += ' dropdown';
641 cfg.html = typeof(cfg.html) != 'undefined' ? cfg.html + ' <span class="caret"></span>' : '<span class="caret"></span>';
644 if (cfg.tag !== 'a' && this.href !== '') {
645 throw "Tag must be a to set href.";
646 } else if (this.href.length > 0) {
647 cfg.href = this.href;
650 if(this.removeClass){
655 cfg.target = this.target;
660 initEvents: function() {
661 // Roo.log('init events?');
662 // Roo.log(this.el.dom);
663 if (this.el.hasClass('roo-button')) {
664 this.el.on('click', this.onClick, this);
666 this.el.select('.roo-button').on('click', this.onClick, this);
669 if(this.removeClass){
670 this.el.on('click', this.onClick, this);
673 this.el.enableDisplayMode();
676 onClick : function(e)
682 Roo.log('button on click ');
683 if(this.preventDefault){
686 if (this.pressed === true || this.pressed === false) {
687 this.pressed = !this.pressed;
688 this.el[this.pressed ? 'addClass' : 'removeClass']('active');
689 this.fireEvent('toggle', this, e, this.pressed);
693 this.fireEvent('click', this, e);
697 * Enables this button
701 this.disabled = false;
702 this.el.removeClass('disabled');
706 * Disable this button
710 this.disabled = true;
711 this.el.addClass('disabled');
714 * sets the active state on/off,
715 * @param {Boolean} state (optional) Force a particular state
717 setActive : function(v) {
719 this.el[v ? 'addClass' : 'removeClass']('active');
722 * toggles the current active state
724 toggleActive : function()
726 var active = this.el.hasClass('active');
727 this.setActive(!active);
731 setText : function(str)
733 this.el.select('.roo-button-text',true).first().dom.innerHTML = str;
756 * @class Roo.bootstrap.Column
757 * @extends Roo.bootstrap.Component
758 * Bootstrap Column class
759 * @cfg {Number} xs colspan out of 12 for mobile-sized screens
760 * @cfg {Number} sm colspan out of 12 for tablet-sized screens
761 * @cfg {Number} md colspan out of 12 for computer-sized screens
762 * @cfg {Number} lg colspan out of 12 for large computer-sized screens
763 * @cfg {String} html content of column.
766 * Create a new Column
767 * @param {Object} config The config object
770 Roo.bootstrap.Column = function(config){
771 Roo.bootstrap.Column.superclass.constructor.call(this, config);
774 Roo.extend(Roo.bootstrap.Column, Roo.bootstrap.Component, {
783 getAutoCreate : function(){
784 var cfg = Roo.apply({}, Roo.bootstrap.Column.superclass.getAutoCreate.call(this));
792 ['xs','sm','md','lg'].map(function(size){
793 if (settings[size]) {
794 cfg.cls += ' col-' + size + '-' + settings[size];
797 if (this.html.length) {
798 cfg.html = this.html;
817 * @class Roo.bootstrap.Container
818 * @extends Roo.bootstrap.Component
819 * Bootstrap Container class
820 * @cfg {Boolean} jumbotron is it a jumbotron element
821 * @cfg {String} html content of element
822 * @cfg {String} well (lg|sm|md) a well, large, small or medium.
823 * @cfg {String} panel (primary|success|info|warning|danger) render as a panel.
824 * @cfg {String} header content of header (for panel)
825 * @cfg {String} footer content of footer (for panel)
826 * @cfg {String} sticky (footer|wrap|push) block to use as footer or body- needs css-bootstrap/sticky-footer.css
827 * @cfg {String} tag (header|aside|section) type of HTML tag.
831 * Create a new Container
832 * @param {Object} config The config object
835 Roo.bootstrap.Container = function(config){
836 Roo.bootstrap.Container.superclass.constructor.call(this, config);
839 Roo.extend(Roo.bootstrap.Container, Roo.bootstrap.Component, {
850 getChildContainer : function() {
856 if (this.panel.length) {
857 return this.el.select('.panel-body',true).first();
864 getAutoCreate : function(){
867 tag : this.tag || 'div',
871 if (this.jumbotron) {
872 cfg.cls = 'jumbotron';
874 // - this is applied by the parent..
876 // cfg.cls = this.cls + '';
879 if (this.sticky.length) {
881 var bd = Roo.get(document.body);
882 if (!bd.hasClass('bootstrap-sticky')) {
883 bd.addClass('bootstrap-sticky');
884 Roo.select('html',true).setStyle('height', '100%');
887 cfg.cls += 'bootstrap-sticky-' + this.sticky;
891 if (this.well.length) {
895 cfg.cls +=' well well-' +this.well;
905 if (this.panel.length) {
906 cfg.cls += ' panel panel-' + this.panel;
908 if (this.header.length) {
911 cls : 'panel-heading',
927 if (this.footer.length) {
929 cls : 'panel-footer',
938 body.html = this.html || cfg.html;
940 if ((!this.cls || !this.cls.length) && (!cfg.cls || !cfg.cls.length)) {
941 cfg.cls = 'container';
958 * @class Roo.bootstrap.Img
959 * @extends Roo.bootstrap.Component
960 * Bootstrap Img class
961 * @cfg {Boolean} imgResponsive false | true
962 * @cfg {String} border rounded | circle | thumbnail
963 * @cfg {String} src image source
964 * @cfg {String} alt image alternative text
965 * @cfg {String} href a tag href
966 * @cfg {String} target (_self|_blank|_parent|_top)target for a href.
970 * @param {Object} config The config object
973 Roo.bootstrap.Img = function(config){
974 Roo.bootstrap.Img.superclass.constructor.call(this, config);
980 * The img click event for the img.
981 * @param {Roo.EventObject} e
987 Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component, {
995 getAutoCreate : function(){
999 cls: (this.imgResponsive) ? 'img-responsive' : '',
1003 cfg.html = this.html || cfg.html;
1005 cfg.src = this.src || cfg.src;
1007 if (['rounded','circle','thumbnail'].indexOf(this.border)>-1) {
1008 cfg.cls += ' img-' + this.border;
1025 a.target = this.target;
1031 return (this.href) ? a : cfg;
1034 initEvents: function() {
1037 this.el.on('click', this.onClick, this);
1041 onClick : function(e)
1043 Roo.log('img onclick');
1044 this.fireEvent('click', this, e);
1058 * @class Roo.bootstrap.Link
1059 * @extends Roo.bootstrap.Component
1060 * Bootstrap Link Class
1061 * @cfg {String} alt image alternative text
1062 * @cfg {String} href a tag href
1063 * @cfg {String} target (_self|_blank|_parent|_top) target for a href.
1064 * @cfg {String} html the content of the link.
1068 * Create a new Input
1069 * @param {Object} config The config object
1072 Roo.bootstrap.Link = function(config){
1073 Roo.bootstrap.Link.superclass.constructor.call(this, config);
1079 * The img click event for the img.
1080 * @param {Roo.EventObject} e
1086 Roo.extend(Roo.bootstrap.Link, Roo.bootstrap.Component, {
1091 getAutoCreate : function(){
1095 html : this.html || 'html-missing'
1102 cfg.href = this.href || '#';
1104 cfg.target = this.target;
1110 initEvents: function() {
1113 this.el.on('click', this.onClick, this);
1117 onClick : function(e)
1119 //Roo.log('img onclick');
1120 this.fireEvent('click', this, e);
1133 * @class Roo.bootstrap.Header
1134 * @extends Roo.bootstrap.Component
1135 * Bootstrap Header class
1136 * @cfg {String} html content of header
1137 * @cfg {Number} level (1|2|3|4|5|6) default 1
1140 * Create a new Header
1141 * @param {Object} config The config object
1145 Roo.bootstrap.Header = function(config){
1146 Roo.bootstrap.Header.superclass.constructor.call(this, config);
1149 Roo.extend(Roo.bootstrap.Header, Roo.bootstrap.Component, {
1157 getAutoCreate : function(){
1160 tag: 'h' + (1 *this.level),
1161 html: this.html || 'fill in html'
1173 * Ext JS Library 1.1.1
1174 * Copyright(c) 2006-2007, Ext JS, LLC.
1176 * Originally Released Under LGPL - original licence link has changed is not relivant.
1179 * <script type="text/javascript">
1183 * @class Roo.bootstrap.MenuMgr
1184 * Provides a common registry of all menu items on a page so that they can be easily accessed by id.
1187 Roo.bootstrap.MenuMgr = function(){
1188 var menus, active, groups = {}, attached = false, lastShow = new Date();
1190 // private - called when first menu is created
1193 active = new Roo.util.MixedCollection();
1194 Roo.get(document).addKeyListener(27, function(){
1195 if(active.length > 0){
1203 if(active && active.length > 0){
1204 var c = active.clone();
1214 if(active.length < 1){
1215 Roo.get(document).un("mouseup", onMouseDown);
1223 var last = active.last();
1224 lastShow = new Date();
1227 Roo.get(document).on("mouseup", onMouseDown);
1232 //m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
1233 m.parentMenu.activeChild = m;
1234 }else if(last && last.isVisible()){
1235 //m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
1240 function onBeforeHide(m){
1242 m.activeChild.hide();
1244 if(m.autoHideTimer){
1245 clearTimeout(m.autoHideTimer);
1246 delete m.autoHideTimer;
1251 function onBeforeShow(m){
1252 var pm = m.parentMenu;
1253 if(!pm && !m.allowOtherMenus){
1255 }else if(pm && pm.activeChild && active != m){
1256 pm.activeChild.hide();
1261 function onMouseDown(e){
1262 Roo.log("on MouseDown");
1263 if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
1271 function onBeforeCheck(mi, state){
1273 var g = groups[mi.group];
1274 for(var i = 0, l = g.length; i < l; i++){
1276 g[i].setChecked(false);
1285 * Hides all menus that are currently visible
1287 hideAll : function(){
1292 register : function(menu){
1296 menus[menu.id] = menu;
1297 menu.on("beforehide", onBeforeHide);
1298 menu.on("hide", onHide);
1299 menu.on("beforeshow", onBeforeShow);
1300 menu.on("show", onShow);
1302 if(g && menu.events["checkchange"]){
1306 groups[g].push(menu);
1307 menu.on("checkchange", onCheck);
1312 * Returns a {@link Roo.menu.Menu} object
1313 * @param {String/Object} menu The string menu id, an existing menu object reference, or a Menu config that will
1314 * be used to generate and return a new Menu instance.
1316 get : function(menu){
1317 if(typeof menu == "string"){ // menu id
1319 }else if(menu.events){ // menu instance
1322 /*else if(typeof menu.length == 'number'){ // array of menu items?
1323 return new Roo.bootstrap.Menu({items:menu});
1324 }else{ // otherwise, must be a config
1325 return new Roo.bootstrap.Menu(menu);
1332 unregister : function(menu){
1333 delete menus[menu.id];
1334 menu.un("beforehide", onBeforeHide);
1335 menu.un("hide", onHide);
1336 menu.un("beforeshow", onBeforeShow);
1337 menu.un("show", onShow);
1339 if(g && menu.events["checkchange"]){
1340 groups[g].remove(menu);
1341 menu.un("checkchange", onCheck);
1346 registerCheckable : function(menuItem){
1347 var g = menuItem.group;
1352 groups[g].push(menuItem);
1353 menuItem.on("beforecheckchange", onBeforeCheck);
1358 unregisterCheckable : function(menuItem){
1359 var g = menuItem.group;
1361 groups[g].remove(menuItem);
1362 menuItem.un("beforecheckchange", onBeforeCheck);
1374 * @class Roo.bootstrap.Menu
1375 * @extends Roo.bootstrap.Component
1376 * Bootstrap Menu class - container for MenuItems
1377 * @cfg {String} type (dropdown|treeview|submenu) type of menu
1381 * @param {Object} config The config object
1385 Roo.bootstrap.Menu = function(config){
1386 Roo.bootstrap.Menu.superclass.constructor.call(this, config);
1387 if (this.registerMenu) {
1388 Roo.bootstrap.MenuMgr.register(this);
1393 * Fires before this menu is displayed
1394 * @param {Roo.menu.Menu} this
1399 * Fires before this menu is hidden
1400 * @param {Roo.menu.Menu} this
1405 * Fires after this menu is displayed
1406 * @param {Roo.menu.Menu} this
1411 * Fires after this menu is hidden
1412 * @param {Roo.menu.Menu} this
1417 * Fires when this menu is clicked (or when the enter key is pressed while it is active)
1418 * @param {Roo.menu.Menu} this
1419 * @param {Roo.menu.Item} menuItem The menu item that was clicked
1420 * @param {Roo.EventObject} e
1425 * Fires when the mouse is hovering over this menu
1426 * @param {Roo.menu.Menu} this
1427 * @param {Roo.EventObject} e
1428 * @param {Roo.menu.Item} menuItem The menu item that was clicked
1433 * Fires when the mouse exits this menu
1434 * @param {Roo.menu.Menu} this
1435 * @param {Roo.EventObject} e
1436 * @param {Roo.menu.Item} menuItem The menu item that was clicked
1441 * Fires when a menu item contained in this menu is clicked
1442 * @param {Roo.menu.BaseItem} baseItem The BaseItem that was clicked
1443 * @param {Roo.EventObject} e
1447 this.menuitems = new Roo.util.MixedCollection(false, function(o) { return o.el.id; });
1450 Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component, {
1454 triggerEl : false, // is this set by component builder? -- it should really be fetched from parent()???
1457 * @cfg {Boolean} registerMenu True (default) - means that clicking on screen etc. hides it.
1459 registerMenu : true,
1461 menuItems :false, // stores the menu items..
1467 getChildContainer : function() {
1471 getAutoCreate : function(){
1473 //if (['right'].indexOf(this.align)!==-1) {
1474 // cfg.cn[1].cls += ' pull-right'
1480 cls : 'dropdown-menu' ,
1481 style : 'z-index:1000'
1485 if (this.type === 'submenu') {
1486 cfg.cls = 'submenu active';
1488 if (this.type === 'treeview') {
1489 cfg.cls = 'treeview-menu';
1494 initEvents : function() {
1496 // Roo.log("ADD event");
1497 // Roo.log(this.triggerEl.dom);
1498 this.triggerEl.on('click', this.onTriggerPress, this);
1499 this.triggerEl.addClass('dropdown-toggle');
1500 this.el.on(Roo.isTouch ? 'touchstart' : 'click' , this.onClick, this);
1502 this.el.on("mouseover", this.onMouseOver, this);
1503 this.el.on("mouseout", this.onMouseOut, this);
1507 findTargetItem : function(e){
1508 var t = e.getTarget(".dropdown-menu-item", this.el, true);
1512 //Roo.log(t); Roo.log(t.id);
1514 //Roo.log(this.menuitems);
1515 return this.menuitems.get(t.id);
1517 //return this.items.get(t.menuItemId);
1522 onClick : function(e){
1523 Roo.log("menu.onClick");
1524 var t = this.findTargetItem(e);
1530 if (Roo.isTouch && e.type == 'touchstart' && t.menu && !t.disabled) {
1531 if(t == this.activeItem && t.shouldDeactivate(e)){
1532 this.activeItem.deactivate();
1533 delete this.activeItem;
1537 this.setActiveItem(t, true);
1544 Roo.log('pass click event');
1548 this.fireEvent("click", this, t, e);
1552 onMouseOver : function(e){
1553 var t = this.findTargetItem(e);
1556 // if(t.canActivate && !t.disabled){
1557 // this.setActiveItem(t, true);
1561 this.fireEvent("mouseover", this, e, t);
1563 isVisible : function(){
1564 return !this.hidden;
1566 onMouseOut : function(e){
1567 var t = this.findTargetItem(e);
1570 // if(t == this.activeItem && t.shouldDeactivate(e)){
1571 // this.activeItem.deactivate();
1572 // delete this.activeItem;
1575 this.fireEvent("mouseout", this, e, t);
1580 * Displays this menu relative to another element
1581 * @param {String/HTMLElement/Roo.Element} element The element to align to
1582 * @param {String} position (optional) The {@link Roo.Element#alignTo} anchor position to use in aligning to
1583 * the element (defaults to this.defaultAlign)
1584 * @param {Roo.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)
1586 show : function(el, pos, parentMenu){
1587 this.parentMenu = parentMenu;
1591 this.fireEvent("beforeshow", this);
1592 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);
1595 * Displays this menu at a specific xy position
1596 * @param {Array} xyPosition Contains X & Y [x, y] values for the position at which to show the menu (coordinates are page-based)
1597 * @param {Roo.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)
1599 showAt : function(xy, parentMenu, /* private: */_e){
1600 this.parentMenu = parentMenu;
1605 this.fireEvent("beforeshow", this);
1607 //xy = this.el.adjustForConstraints(xy);
1609 //this.el.setXY(xy);
1611 this.hideMenuItems();
1612 this.hidden = false;
1613 this.triggerEl.addClass('open');
1615 this.fireEvent("show", this);
1621 this.doFocus.defer(50, this);
1625 doFocus : function(){
1627 this.focusEl.focus();
1632 * Hides this menu and optionally all parent menus
1633 * @param {Boolean} deep (optional) True to hide all parent menus recursively, if any (defaults to false)
1635 hide : function(deep){
1637 this.hideMenuItems();
1638 if(this.el && this.isVisible()){
1639 this.fireEvent("beforehide", this);
1640 if(this.activeItem){
1641 this.activeItem.deactivate();
1642 this.activeItem = null;
1644 this.triggerEl.removeClass('open');;
1646 this.fireEvent("hide", this);
1648 if(deep === true && this.parentMenu){
1649 this.parentMenu.hide(true);
1653 onTriggerPress : function(e)
1656 Roo.log('trigger press');
1657 //Roo.log(e.getTarget());
1658 // Roo.log(this.triggerEl.dom);
1659 if (Roo.get(e.getTarget()).findParent('.dropdown-menu')) {
1662 if (this.isVisible()) {
1666 this.show(this.triggerEl, false, false);
1675 hideMenuItems : function()
1677 //$(backdrop).remove()
1678 Roo.select('.open',true).each(function(aa) {
1680 aa.removeClass('open');
1681 //var parent = getParent($(this))
1682 //var relatedTarget = { relatedTarget: this }
1684 //$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
1685 //if (e.isDefaultPrevented()) return
1686 //$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
1689 addxtypeChild : function (tree, cntr) {
1690 var comp= Roo.bootstrap.Menu.superclass.addxtypeChild.call(this, tree, cntr);
1692 this.menuitems.add(comp);
1713 * @class Roo.bootstrap.MenuItem
1714 * @extends Roo.bootstrap.Component
1715 * Bootstrap MenuItem class
1716 * @cfg {String} html the menu label
1717 * @cfg {String} href the link
1718 * @cfg {Boolean} preventDefault (true | false) default true
1722 * Create a new MenuItem
1723 * @param {Object} config The config object
1727 Roo.bootstrap.MenuItem = function(config){
1728 Roo.bootstrap.MenuItem.superclass.constructor.call(this, config);
1733 * The raw click event for the entire grid.
1734 * @param {Roo.EventObject} e
1740 Roo.extend(Roo.bootstrap.MenuItem, Roo.bootstrap.Component, {
1744 preventDefault: true,
1746 getAutoCreate : function(){
1749 cls: 'dropdown-menu-item',
1758 if (this.parent().type == 'treeview') {
1759 cfg.cls = 'treeview-menu';
1762 cfg.cn[0].href = this.href || cfg.cn[0].href ;
1763 cfg.cn[0].html = this.html || cfg.cn[0].html ;
1767 initEvents: function() {
1769 //this.el.select('a').on('click', this.onClick, this);
1772 onClick : function(e)
1774 Roo.log('item on click ');
1775 //if(this.preventDefault){
1776 // e.preventDefault();
1778 //this.parent().hideMenuItems();
1780 this.fireEvent('click', this, e);
1799 * @class Roo.bootstrap.MenuSeparator
1800 * @extends Roo.bootstrap.Component
1801 * Bootstrap MenuSeparator class
1804 * Create a new MenuItem
1805 * @param {Object} config The config object
1809 Roo.bootstrap.MenuSeparator = function(config){
1810 Roo.bootstrap.MenuSeparator.superclass.constructor.call(this, config);
1813 Roo.extend(Roo.bootstrap.MenuSeparator, Roo.bootstrap.Component, {
1815 getAutoCreate : function(){
1830 <div class="modal fade">
1831 <div class="modal-dialog">
1832 <div class="modal-content">
1833 <div class="modal-header">
1834 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
1835 <h4 class="modal-title">Modal title</h4>
1837 <div class="modal-body">
1838 <p>One fine body…</p>
1840 <div class="modal-footer">
1841 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1842 <button type="button" class="btn btn-primary">Save changes</button>
1844 </div><!-- /.modal-content -->
1845 </div><!-- /.modal-dialog -->
1846 </div><!-- /.modal -->
1856 * @class Roo.bootstrap.Modal
1857 * @extends Roo.bootstrap.Component
1858 * Bootstrap Modal class
1859 * @cfg {String} title Title of dialog
1860 * @cfg {Boolean} specificTitle (true|false) default false
1861 * @cfg {Array} buttons Array of buttons or standard button set..
1862 * @cfg {String} buttonPosition (left|right|center) default right
1865 * Create a new Modal Dialog
1866 * @param {Object} config The config object
1869 Roo.bootstrap.Modal = function(config){
1870 Roo.bootstrap.Modal.superclass.constructor.call(this, config);
1875 * The raw btnclick event for the button
1876 * @param {Roo.EventObject} e
1880 this.buttons = this.buttons || [];
1883 Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component, {
1885 title : 'test dialog',
1892 specificTitle: false,
1894 buttonPosition: 'right',
1896 onRender : function(ct, position)
1898 Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
1901 var cfg = Roo.apply({}, this.getAutoCreate());
1904 // cfg.name = typeof(this.name) == 'undefined' ? this.id : this.name;
1906 //if (!cfg.name.length) {
1910 cfg.cls += ' ' + this.cls;
1913 cfg.style = this.style;
1915 this.el = Roo.get(document.body).createChild(cfg, position);
1917 //var type = this.el.dom.type;
1919 if(this.tabIndex !== undefined){
1920 this.el.dom.setAttribute('tabIndex', this.tabIndex);
1925 this.maskEl = Roo.DomHelper.append(document.body, {tag: "div", cls:"x-dlg-mask"}, true);
1926 this.maskEl.enableDisplayMode("block");
1928 //this.el.addClass("x-dlg-modal");
1930 if (this.buttons.length) {
1931 Roo.each(this.buttons, function(bb) {
1932 b = Roo.apply({}, bb);
1933 b.xns = b.xns || Roo.bootstrap;
1934 b.xtype = b.xtype || 'Button';
1935 if (typeof(b.listeners) == 'undefined') {
1936 b.listeners = { click : this.onButtonClick.createDelegate(this) };
1939 var btn = Roo.factory(b);
1941 btn.onRender(this.el.select('.modal-footer div').first());
1945 // render the children.
1948 if(typeof(this.items) != 'undefined'){
1949 var items = this.items;
1952 for(var i =0;i < items.length;i++) {
1953 nitems.push(this.addxtype(Roo.apply({}, items[i])));
1957 this.items = nitems;
1959 this.body = this.el.select('.modal-body',true).first();
1960 this.close = this.el.select('.modal-header .close', true).first();
1961 this.footer = this.el.select('.modal-footer',true).first();
1963 //this.el.addClass([this.fieldClass, this.cls]);
1966 getAutoCreate : function(){
1971 html : this.html || ''
1976 cls : 'modal-title',
1980 if(this.specificTitle){
1986 style : 'display: none',
1989 cls: "modal-dialog",
1992 cls : "modal-content",
1995 cls : 'modal-header',
2007 cls : 'modal-footer',
2011 cls: 'btn-' + this.buttonPosition
2030 getChildContainer : function() {
2032 return this.el.select('.modal-body',true).first();
2035 getButtonContainer : function() {
2036 return this.el.select('.modal-footer div',true).first();
2039 initEvents : function()
2041 this.el.select('.modal-header .close').on('click', this.hide, this);
2043 // this.addxtype(this);
2047 if (!this.rendered) {
2051 this.el.addClass('on');
2052 this.el.removeClass('fade');
2053 this.el.setStyle('display', 'block');
2054 Roo.get(document.body).addClass("x-body-masked");
2055 this.maskEl.setSize(Roo.lib.Dom.getViewWidth(true), Roo.lib.Dom.getViewHeight(true));
2057 this.el.setStyle('zIndex', '10001');
2058 this.fireEvent('show', this);
2064 Roo.log('Modal hide?!');
2066 Roo.get(document.body).removeClass("x-body-masked");
2067 this.el.removeClass('on');
2068 this.el.addClass('fade');
2069 this.el.setStyle('display', 'none');
2070 this.fireEvent('hide', this);
2073 addButton : function(str, cb)
2077 var b = Roo.apply({}, { html : str } );
2078 b.xns = b.xns || Roo.bootstrap;
2079 b.xtype = b.xtype || 'Button';
2080 if (typeof(b.listeners) == 'undefined') {
2081 b.listeners = { click : cb.createDelegate(this) };
2084 var btn = Roo.factory(b);
2086 btn.onRender(this.el.select('.modal-footer div').first());
2092 setDefaultButton : function(btn)
2094 //this.el.select('.modal-footer').()
2096 resizeTo: function(w,h)
2100 setContentSize : function(w, h)
2104 onButtonClick: function(btn,e)
2107 this.fireEvent('btnclick', btn.name, e);
2109 setTitle: function(str) {
2110 this.el.select('.modal-title',true).first().dom.innerHTML = str;
2116 Roo.apply(Roo.bootstrap.Modal, {
2118 * Button config that displays a single OK button
2127 * Button config that displays Yes and No buttons
2143 * Button config that displays OK and Cancel buttons
2158 * Button config that displays Yes, No and Cancel buttons
2180 * messagebox - can be used as a replace
2184 * @class Roo.MessageBox
2185 * Utility class for generating different styles of message boxes. The alias Roo.Msg can also be used.
2189 Roo.Msg.alert('Status', 'Changes saved successfully.');
2191 // Prompt for user data:
2192 Roo.Msg.prompt('Name', 'Please enter your name:', function(btn, text){
2194 // process text value...
2198 // Show a dialog using config options:
2200 title:'Save Changes?',
2201 msg: 'Your are closing a tab that has unsaved changes. Would you like to save your changes?',
2202 buttons: Roo.Msg.YESNOCANCEL,
2209 Roo.bootstrap.MessageBox = function(){
2210 var dlg, opt, mask, waitTimer;
2211 var bodyEl, msgEl, textboxEl, textareaEl, progressEl, pp;
2212 var buttons, activeTextEl, bwidth;
2216 var handleButton = function(button){
2218 Roo.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value], 1);
2222 var handleHide = function(){
2224 dlg.el.removeClass(opt.cls);
2227 // Roo.TaskMgr.stop(waitTimer);
2228 // waitTimer = null;
2233 var updateButtons = function(b){
2236 buttons["ok"].hide();
2237 buttons["cancel"].hide();
2238 buttons["yes"].hide();
2239 buttons["no"].hide();
2240 //dlg.footer.dom.style.display = 'none';
2243 dlg.footer.dom.style.display = '';
2244 for(var k in buttons){
2245 if(typeof buttons[k] != "function"){
2248 buttons[k].setText(typeof b[k] == "string" ? b[k] : Roo.bootstrap.MessageBox.buttonText[k]);
2249 width += buttons[k].el.getWidth()+15;
2259 var handleEsc = function(d, k, e){
2260 if(opt && opt.closable !== false){
2270 * Returns a reference to the underlying {@link Roo.BasicDialog} element
2271 * @return {Roo.BasicDialog} The BasicDialog element
2273 getDialog : function(){
2275 dlg = new Roo.bootstrap.Modal( {
2278 //constraintoviewport:false,
2280 //collapsible : false,
2285 //buttonAlign:"center",
2286 closeClick : function(){
2287 if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
2290 handleButton("cancel");
2295 dlg.on("hide", handleHide);
2297 //dlg.addKeyListener(27, handleEsc);
2299 this.buttons = buttons;
2300 var bt = this.buttonText;
2301 buttons["ok"] = dlg.addButton(bt["ok"], handleButton.createCallback("ok"));
2302 buttons["yes"] = dlg.addButton(bt["yes"], handleButton.createCallback("yes"));
2303 buttons["no"] = dlg.addButton(bt["no"], handleButton.createCallback("no"));
2304 buttons["cancel"] = dlg.addButton(bt["cancel"], handleButton.createCallback("cancel"));
2306 bodyEl = dlg.body.createChild({
2308 html:'<span class="roo-mb-text"></span><br /><input type="text" class="roo-mb-input" />' +
2309 '<textarea class="roo-mb-textarea"></textarea>' +
2310 '<div class="roo-mb-progress-wrap"><div class="roo-mb-progress"><div class="roo-mb-progress-bar"> </div></div></div>'
2312 msgEl = bodyEl.dom.firstChild;
2313 textboxEl = Roo.get(bodyEl.dom.childNodes[2]);
2314 textboxEl.enableDisplayMode();
2315 textboxEl.addKeyListener([10,13], function(){
2316 if(dlg.isVisible() && opt && opt.buttons){
2319 }else if(opt.buttons.yes){
2320 handleButton("yes");
2324 textareaEl = Roo.get(bodyEl.dom.childNodes[3]);
2325 textareaEl.enableDisplayMode();
2326 progressEl = Roo.get(bodyEl.dom.childNodes[4]);
2327 progressEl.enableDisplayMode();
2328 var pf = progressEl.dom.firstChild;
2330 pp = Roo.get(pf.firstChild);
2331 pp.setHeight(pf.offsetHeight);
2339 * Updates the message box body text
2340 * @param {String} text (optional) Replaces the message box element's innerHTML with the specified string (defaults to
2341 * the XHTML-compliant non-breaking space character '&#160;')
2342 * @return {Roo.MessageBox} This message box
2344 updateText : function(text){
2345 if(!dlg.isVisible() && !opt.width){
2346 dlg.resizeTo(this.maxWidth, 100); // resize first so content is never clipped from previous shows
2348 msgEl.innerHTML = text || ' ';
2350 var cw = Math.max(msgEl.offsetWidth, msgEl.parentNode.scrollWidth);
2351 //Roo.log("guesed size: " + JSON.stringify([cw,msgEl.offsetWidth, msgEl.parentNode.scrollWidth]));
2353 Math.min(opt.width || cw , this.maxWidth),
2354 Math.max(opt.minWidth || this.minWidth, bwidth)
2357 activeTextEl.setWidth(w);
2359 if(dlg.isVisible()){
2360 dlg.fixedcenter = false;
2362 // to big, make it scroll. = But as usual stupid IE does not support
2365 if ( bodyEl.getHeight() > (Roo.lib.Dom.getViewHeight() - 100)) {
2366 bodyEl.setHeight ( Roo.lib.Dom.getViewHeight() - 100 );
2367 bodyEl.dom.style.overflowY = 'auto' + ( Roo.isIE ? '' : ' !important');
2369 bodyEl.dom.style.height = '';
2370 bodyEl.dom.style.overflowY = '';
2373 bodyEl.dom.style.get = 'auto' + ( Roo.isIE ? '' : ' !important');
2375 bodyEl.dom.style.overflowX = '';
2378 dlg.setContentSize(w, bodyEl.getHeight());
2379 if(dlg.isVisible()){
2380 dlg.fixedcenter = true;
2386 * Updates a progress-style message box's text and progress bar. Only relevant on message boxes
2387 * initiated via {@link Roo.MessageBox#progress} or by calling {@link Roo.MessageBox#show} with progress: true.
2388 * @param {Number} value Any number between 0 and 1 (e.g., .5)
2389 * @param {String} text (optional) If defined, the message box's body text is replaced with the specified string (defaults to undefined)
2390 * @return {Roo.MessageBox} This message box
2392 updateProgress : function(value, text){
2394 this.updateText(text);
2396 if (pp) { // weird bug on my firefox - for some reason this is not defined
2397 pp.setWidth(Math.floor(value*progressEl.dom.firstChild.offsetWidth));
2403 * Returns true if the message box is currently displayed
2404 * @return {Boolean} True if the message box is visible, else false
2406 isVisible : function(){
2407 return dlg && dlg.isVisible();
2411 * Hides the message box if it is displayed
2414 if(this.isVisible()){
2420 * Displays a new message box, or reinitializes an existing message box, based on the config options
2421 * passed in. All functions (e.g. prompt, alert, etc) on MessageBox call this function internally.
2422 * The following config object properties are supported:
2424 Property Type Description
2425 ---------- --------------- ------------------------------------------------------------------------------------
2426 animEl String/Element An id or Element from which the message box should animate as it opens and
2427 closes (defaults to undefined)
2428 buttons Object/Boolean A button config object (e.g., Roo.MessageBox.OKCANCEL or {ok:'Foo',
2429 cancel:'Bar'}), or false to not show any buttons (defaults to false)
2430 closable Boolean False to hide the top-right close button (defaults to true). Note that
2431 progress and wait dialogs will ignore this property and always hide the
2432 close button as they can only be closed programmatically.
2433 cls String A custom CSS class to apply to the message box element
2434 defaultTextHeight Number The default height in pixels of the message box's multiline textarea if
2435 displayed (defaults to 75)
2436 fn Function A callback function to execute after closing the dialog. The arguments to the
2437 function will be btn (the name of the button that was clicked, if applicable,
2438 e.g. "ok"), and text (the value of the active text field, if applicable).
2439 Progress and wait dialogs will ignore this option since they do not respond to
2440 user actions and can only be closed programmatically, so any required function
2441 should be called by the same code after it closes the dialog.
2442 icon String A CSS class that provides a background image to be used as an icon for
2443 the dialog (e.g., Roo.MessageBox.WARNING or 'custom-class', defaults to '')
2444 maxWidth Number The maximum width in pixels of the message box (defaults to 600)
2445 minWidth Number The minimum width in pixels of the message box (defaults to 100)
2446 modal Boolean False to allow user interaction with the page while the message box is
2447 displayed (defaults to true)
2448 msg String A string that will replace the existing message box body text (defaults
2449 to the XHTML-compliant non-breaking space character ' ')
2450 multiline Boolean True to prompt the user to enter multi-line text (defaults to false)
2451 progress Boolean True to display a progress bar (defaults to false)
2452 progressText String The text to display inside the progress bar if progress = true (defaults to '')
2453 prompt Boolean True to prompt the user to enter single-line text (defaults to false)
2454 proxyDrag Boolean True to display a lightweight proxy while dragging (defaults to false)
2455 title String The title text
2456 value String The string value to set into the active textbox element if displayed
2457 wait Boolean True to display a progress bar (defaults to false)
2458 width Number The width of the dialog in pixels
2465 msg: 'Please enter your address:',
2467 buttons: Roo.MessageBox.OKCANCEL,
2470 animEl: 'addAddressBtn'
2473 * @param {Object} config Configuration options
2474 * @return {Roo.MessageBox} This message box
2476 show : function(options)
2479 // this causes nightmares if you show one dialog after another
2480 // especially on callbacks..
2482 if(this.isVisible()){
2485 Roo.log("[Roo.Messagebox] Show called while message displayed:" );
2486 Roo.log("Old Dialog Message:" + msgEl.innerHTML );
2487 Roo.log("New Dialog Message:" + options.msg )
2488 //this.alert("ERROR", "Multiple dialogs where displayed at the same time");
2489 //throw "Roo.MessageBox ERROR : Multiple dialogs where displayed at the same time";
2492 var d = this.getDialog();
2494 d.setTitle(opt.title || " ");
2495 d.close.setDisplayed(opt.closable !== false);
2496 activeTextEl = textboxEl;
2497 opt.prompt = opt.prompt || (opt.multiline ? true : false);
2502 textareaEl.setHeight(typeof opt.multiline == "number" ?
2503 opt.multiline : this.defaultTextHeight);
2504 activeTextEl = textareaEl;
2513 progressEl.setDisplayed(opt.progress === true);
2514 this.updateProgress(0);
2515 activeTextEl.dom.value = opt.value || "";
2517 dlg.setDefaultButton(activeTextEl);
2519 var bs = opt.buttons;
2523 }else if(bs && bs.yes){
2524 db = buttons["yes"];
2526 dlg.setDefaultButton(db);
2528 bwidth = updateButtons(opt.buttons);
2529 this.updateText(opt.msg);
2531 d.el.addClass(opt.cls);
2533 d.proxyDrag = opt.proxyDrag === true;
2534 d.modal = opt.modal !== false;
2535 d.mask = opt.modal !== false ? mask : false;
2537 // force it to the end of the z-index stack so it gets a cursor in FF
2538 document.body.appendChild(dlg.el.dom);
2539 d.animateTarget = null;
2540 d.show(options.animEl);
2546 * Displays a message box with a progress bar. This message box has no buttons and is not closeable by
2547 * the user. You are responsible for updating the progress bar as needed via {@link Roo.MessageBox#updateProgress}
2548 * and closing the message box when the process is complete.
2549 * @param {String} title The title bar text
2550 * @param {String} msg The message box body text
2551 * @return {Roo.MessageBox} This message box
2553 progress : function(title, msg){
2560 minWidth: this.minProgressWidth,
2567 * Displays a standard read-only message box with an OK button (comparable to the basic JavaScript Window.alert).
2568 * If a callback function is passed it will be called after the user clicks the button, and the
2569 * id of the button that was clicked will be passed as the only parameter to the callback
2570 * (could also be the top-right close button).
2571 * @param {String} title The title bar text
2572 * @param {String} msg The message box body text
2573 * @param {Function} fn (optional) The callback function invoked after the message box is closed
2574 * @param {Object} scope (optional) The scope of the callback function
2575 * @return {Roo.MessageBox} This message box
2577 alert : function(title, msg, fn, scope){
2590 * Displays a message box with an infinitely auto-updating progress bar. This can be used to block user
2591 * interaction while waiting for a long-running process to complete that does not have defined intervals.
2592 * You are responsible for closing the message box when the process is complete.
2593 * @param {String} msg The message box body text
2594 * @param {String} title (optional) The title bar text
2595 * @return {Roo.MessageBox} This message box
2597 wait : function(msg, title){
2608 waitTimer = Roo.TaskMgr.start({
2610 Roo.MessageBox.updateProgress(((((i+20)%20)+1)*5)*.01);
2618 * Displays a confirmation message box with Yes and No buttons (comparable to JavaScript's Window.confirm).
2619 * If a callback function is passed it will be called after the user clicks either button, and the id of the
2620 * button that was clicked will be passed as the only parameter to the callback (could also be the top-right close button).
2621 * @param {String} title The title bar text
2622 * @param {String} msg The message box body text
2623 * @param {Function} fn (optional) The callback function invoked after the message box is closed
2624 * @param {Object} scope (optional) The scope of the callback function
2625 * @return {Roo.MessageBox} This message box
2627 confirm : function(title, msg, fn, scope){
2631 buttons: this.YESNO,
2640 * Displays a message box with OK and Cancel buttons prompting the user to enter some text (comparable to
2641 * JavaScript's Window.prompt). The prompt can be a single-line or multi-line textbox. If a callback function
2642 * is passed it will be called after the user clicks either button, and the id of the button that was clicked
2643 * (could also be the top-right close button) and the text that was entered will be passed as the two
2644 * parameters to the callback.
2645 * @param {String} title The title bar text
2646 * @param {String} msg The message box body text
2647 * @param {Function} fn (optional) The callback function invoked after the message box is closed
2648 * @param {Object} scope (optional) The scope of the callback function
2649 * @param {Boolean/Number} multiline (optional) True to create a multiline textbox using the defaultTextHeight
2650 * property, or the height in pixels to create the textbox (defaults to false / single-line)
2651 * @return {Roo.MessageBox} This message box
2653 prompt : function(title, msg, fn, scope, multiline){
2657 buttons: this.OKCANCEL,
2662 multiline: multiline,
2669 * Button config that displays a single OK button
2674 * Button config that displays Yes and No buttons
2677 YESNO : {yes:true, no:true},
2679 * Button config that displays OK and Cancel buttons
2682 OKCANCEL : {ok:true, cancel:true},
2684 * Button config that displays Yes, No and Cancel buttons
2687 YESNOCANCEL : {yes:true, no:true, cancel:true},
2690 * The default height in pixels of the message box's multiline textarea if displayed (defaults to 75)
2693 defaultTextHeight : 75,
2695 * The maximum width in pixels of the message box (defaults to 600)
2700 * The minimum width in pixels of the message box (defaults to 100)
2705 * The minimum width in pixels of the message box if it is a progress-style dialog. This is useful
2706 * for setting a different minimum width than text-only dialogs may need (defaults to 250)
2709 minProgressWidth : 250,
2711 * An object containing the default button text strings that can be overriden for localized language support.
2712 * Supported properties are: ok, cancel, yes and no.
2713 * Customize the default text like so: Roo.MessageBox.buttonText.yes = "S?";
2726 * Shorthand for {@link Roo.MessageBox}
2728 Roo.MessageBox = Roo.MessageBox || Roo.bootstrap.MessageBox
2729 Roo.Msg = Roo.Msg || Roo.MessageBox;
2738 * @class Roo.bootstrap.Navbar
2739 * @extends Roo.bootstrap.Component
2740 * Bootstrap Navbar class
2743 * Create a new Navbar
2744 * @param {Object} config The config object
2748 Roo.bootstrap.Navbar = function(config){
2749 Roo.bootstrap.Navbar.superclass.constructor.call(this, config);
2753 Roo.extend(Roo.bootstrap.Navbar, Roo.bootstrap.Component, {
2762 getAutoCreate : function(){
2765 throw { message : "nav bar is now a abstract base class - use NavSimplebar / NavHeaderbar / NavSidebar etc..."};
2769 initEvents :function ()
2771 //Roo.log(this.el.select('.navbar-toggle',true));
2772 this.el.select('.navbar-toggle',true).on('click', function() {
2773 // Roo.log('click');
2774 this.el.select('.navbar-collapse',true).toggleClass('in');
2782 this.maskEl = Roo.DomHelper.append(this.el, mark, true);
2784 var size = this.el.getSize();
2785 this.maskEl.setSize(size.width, size.height);
2786 this.maskEl.enableDisplayMode("block");
2795 getChildContainer : function()
2797 if (this.el.select('.collapse').getCount()) {
2798 return this.el.select('.collapse',true).first();
2830 * @class Roo.bootstrap.NavSimplebar
2831 * @extends Roo.bootstrap.Navbar
2832 * Bootstrap Sidebar class
2834 * @cfg {Boolean} inverse is inverted color
2836 * @cfg {String} type (nav | pills | tabs)
2837 * @cfg {Boolean} arrangement stacked | justified
2838 * @cfg {String} align (left | right) alignment
2840 * @cfg {Boolean} main (true|false) main nav bar? default false
2841 * @cfg {Boolean} loadMask (true|false) loadMask on the bar
2843 * @cfg {String} tag (header|footer|nav|div) default is nav
2849 * Create a new Sidebar
2850 * @param {Object} config The config object
2854 Roo.bootstrap.NavSimplebar = function(config){
2855 Roo.bootstrap.NavSimplebar.superclass.constructor.call(this, config);
2858 Roo.extend(Roo.bootstrap.NavSimplebar, Roo.bootstrap.Navbar, {
2874 getAutoCreate : function(){
2878 tag : this.tag || 'div',
2891 this.type = this.type || 'nav';
2892 if (['tabs','pills'].indexOf(this.type)!==-1) {
2893 cfg.cn[0].cls += ' nav-' + this.type
2897 if (this.type!=='nav') {
2898 Roo.log('nav type must be nav/tabs/pills')
2900 cfg.cn[0].cls += ' navbar-nav'
2906 if (['stacked','justified'].indexOf(this.arrangement)!==-1) {
2907 cfg.cn[0].cls += ' nav-' + this.arrangement;
2911 if (this.align === 'right') {
2912 cfg.cn[0].cls += ' navbar-right';
2916 cfg.cls += ' navbar-inverse';
2943 * @class Roo.bootstrap.NavHeaderbar
2944 * @extends Roo.bootstrap.NavSimplebar
2945 * Bootstrap Sidebar class
2947 * @cfg {String} brand what is brand
2948 * @cfg {String} position (fixed-top|fixed-bottom|static-top) position
2949 * @cfg {String} brand_href href of the brand
2952 * Create a new Sidebar
2953 * @param {Object} config The config object
2957 Roo.bootstrap.NavHeaderbar = function(config){
2958 Roo.bootstrap.NavHeaderbar.superclass.constructor.call(this, config);
2961 Roo.extend(Roo.bootstrap.NavHeaderbar, Roo.bootstrap.NavSimplebar, {
2968 getAutoCreate : function(){
2973 tag: this.nav || 'nav',
2979 cls: 'navbar-header',
2984 cls: 'navbar-toggle',
2985 'data-toggle': 'collapse',
2990 html: 'Toggle navigation'
3010 cls: 'collapse navbar-collapse'
3015 cfg.cls += this.inverse ? ' navbar-inverse' : ' navbar-default';
3017 if (['fixed-top','fixed-bottom','static-top'].indexOf(this.position)>-1) {
3018 cfg.cls += ' navbar-' + this.position;
3020 // tag can override this..
3022 cfg.tag = this.tag || (this.position == 'fixed-bottom' ? 'footer' : 'header');
3025 if (this.brand !== '') {
3028 href: this.brand_href ? this.brand_href : '#',
3029 cls: 'navbar-brand',
3037 cfg.cls += ' main-nav';
3062 * @class Roo.bootstrap.NavSidebar
3063 * @extends Roo.bootstrap.Navbar
3064 * Bootstrap Sidebar class
3067 * Create a new Sidebar
3068 * @param {Object} config The config object
3072 Roo.bootstrap.NavSidebar = function(config){
3073 Roo.bootstrap.NavSidebar.superclass.constructor.call(this, config);
3076 Roo.extend(Roo.bootstrap.NavSidebar, Roo.bootstrap.Navbar, {
3078 sidebar : true, // used by Navbar Item and NavbarGroup at present...
3080 getAutoCreate : function(){
3085 cls: 'sidebar sidebar-nav'
3107 * @class Roo.bootstrap.NavGroup
3108 * @extends Roo.bootstrap.Component
3109 * Bootstrap NavGroup class
3110 * @cfg {String} align left | right
3111 * @cfg {Boolean} inverse false | true
3112 * @cfg {String} type (nav|pills|tab) default nav
3113 * @cfg {String} navId - reference Id for navbar.
3117 * Create a new nav group
3118 * @param {Object} config The config object
3121 Roo.bootstrap.NavGroup = function(config){
3122 Roo.bootstrap.NavGroup.superclass.constructor.call(this, config);
3124 Roo.bootstrap.NavGroup.register(this);
3128 * Fires when the active item changes
3129 * @param {Roo.bootstrap.NavGroup} this
3130 * @param {Roo.bootstrap.Navbar.Item} item The item selected
3131 * @param {Roo.bootstrap.Navbar.Item} item The previously selected item
3138 Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component, {
3149 getAutoCreate : function()
3151 var cfg = Roo.apply({}, Roo.bootstrap.NavGroup.superclass.getAutoCreate.call(this));
3158 if (['tabs','pills'].indexOf(this.type)!==-1) {
3159 cfg.cls += ' nav-' + this.type
3161 if (this.type!=='nav') {
3162 Roo.log('nav type must be nav/tabs/pills')
3164 cfg.cls += ' navbar-nav'
3167 if (this.parent().sidebar) {
3170 cls: 'dashboard-menu sidebar-menu'
3176 if (this.form === true) {
3182 if (this.align === 'right') {
3183 cfg.cls += ' navbar-right';
3185 cfg.cls += ' navbar-left';
3189 if (this.align === 'right') {
3190 cfg.cls += ' navbar-right';
3194 cfg.cls += ' navbar-inverse';
3202 setActiveItem : function(item)
3205 Roo.each(this.navItems, function(v){
3210 v.setActive(false, true);
3217 item.setActive(true, true);
3218 this.fireEvent('changed', this, item, prev);
3224 register : function(item)
3226 this.navItems.push( item);
3227 item.navId = this.navId;
3230 getNavItem: function(tabId)
3233 Roo.each(this.navItems, function(e) {
3234 if (e.tabId == tabId) {
3246 Roo.apply(Roo.bootstrap.NavGroup, {
3250 register : function(navgrp)
3252 this.groups[navgrp.navId] = navgrp;
3255 get: function(navId) {
3256 return this.groups[navId];
3271 * @class Roo.bootstrap.Navbar.Item
3272 * @extends Roo.bootstrap.Component
3273 * Bootstrap Navbar.Button class
3274 * @cfg {String} href link to
3275 * @cfg {String} html content of button
3276 * @cfg {String} badge text inside badge
3277 * @cfg {String} glyphicon name of glyphicon
3278 * @cfg {String} icon name of font awesome icon
3279 * @cfg {Boolean} active Is item active
3280 * @cfg {Boolean} preventDefault (true | false) default false
3281 * @cfg {String} tabId the tab that this item activates.
3284 * Create a new Navbar Button
3285 * @param {Object} config The config object
3287 Roo.bootstrap.Navbar.Item = function(config){
3288 Roo.bootstrap.Navbar.Item.superclass.constructor.call(this, config);
3293 * The raw click event for the entire grid.
3294 * @param {Roo.EventObject} e
3299 * Fires when the active item active state changes
3300 * @param {Roo.bootstrap.Navbar.Item} this
3301 * @param {boolean} state the new state
3309 Roo.extend(Roo.bootstrap.Navbar.Item, Roo.bootstrap.Component, {
3317 preventDefault : false,
3320 getAutoCreate : function(){
3322 var cfg = Roo.apply({}, Roo.bootstrap.Navbar.Item.superclass.getAutoCreate.call(this));
3324 if (this.parent().parent().sidebar === true) {
3337 cfg.cn[0].html = this.html;
3341 this.cls += ' active';
3345 cfg.cn[0].cls += ' dropdown-toggle';
3346 cfg.cn[0].html = (cfg.cn[0].html || this.html) + '<span class="glyphicon glyphicon-chevron-down"></span>';
3350 cfg.cn[0].tag = 'a',
3351 cfg.cn[0].href = this.href;
3354 if (this.glyphicon) {
3355 cfg.cn[0].html = '<i class="glyphicon glyphicon-'+this.glyphicon+'"></i><span>' + cfg.cn[0].html || this.html + '</span>'
3359 cfg.cn[0].html = '<i class="'+this.icon+'"></i><span>' + cfg.cn[0].html || this.html + '</span>'
3371 cfg.cls = typeof(cfg.cls) == 'undefined' ? 'active' : cfg.cls + ' active';
3381 if (this.glyphicon) {
3382 if(cfg.html){cfg.html = ' ' + this.html};
3386 cls: 'glyphicon glyphicon-' + this.glyphicon
3391 cfg.cn[0].html = this.html || cfg.cn[0].html ;
3396 cfg.cn[0].html += " <span class='caret'></span>";
3397 //}else if (!this.href) {
3398 // cfg.cn[0].tag='p';
3399 // cfg.cn[0].cls='navbar-text';
3402 cfg.cn[0].href=this.href||'#';
3403 cfg.cn[0].html=this.html;
3406 if (this.badge !== '') {
3409 cfg.cn[0].html + ' ',
3420 cfg.cn[0].html = '<i class="'+this.icon+'"></i><span>' + cfg.cn[0].html || this.html + '</span>'
3425 initEvents: function() {
3426 // Roo.log('init events?');
3427 // Roo.log(this.el.dom);
3428 this.el.select('a',true).on('click', this.onClick, this);
3429 // at this point parent should be available..
3430 this.parent().register(this);
3433 onClick : function(e)
3435 if(this.preventDefault){
3439 if(this.fireEvent('click', this, e) === false){
3443 if (['tabs','pills'].indexOf(this.parent().type)!==-1) {
3444 if (typeof(this.parent().setActiveItem) !== 'undefined') {
3445 this.parent().setActiveItem(this);
3453 isActive: function () {
3456 setActive : function(state, fire)
3458 this.active = state;
3460 this.el.removeClass('active');
3461 } else if (!this.el.hasClass('active')) {
3462 this.el.addClass('active');
3465 this.fireEvent('changed', this, state);
3470 // this should not be here...
3483 * @class Roo.bootstrap.NavItem
3484 * @extends Roo.bootstrap.Component
3485 * Bootstrap Navbar.NavItem class
3486 * @cfg {String} href link to
3487 * @cfg {String} html content of button
3488 * @cfg {String} badge text inside badge
3489 * @cfg {String} badgecls (bg-green|bg-red|bg-yellow)the extra classes for the badge
3490 * @cfg {String} glyphicon name of glyphicon
3491 * @cfg {String} icon name of font awesome icon
3492 * @cfg {Boolean} active Is item active
3493 * @cfg {Boolean} preventDefault (true | false) default false
3494 * @cfg {String} tabId the tab that this item activates.
3497 * Create a new Navbar Item
3498 * @param {Object} config The config object
3500 Roo.bootstrap.NavItem = function(config){
3501 Roo.bootstrap.NavItem.superclass.constructor.call(this, config);
3506 * The raw click event for the entire grid.
3507 * @param {Roo.EventObject} e
3512 * Fires when the active item active state changes
3513 * @param {Roo.bootstrap.NavItem} this
3514 * @param {boolean} state the new state
3522 Roo.extend(Roo.bootstrap.NavItem, Roo.bootstrap.Component, {
3530 preventDefault : false,
3533 getAutoCreate : function(){
3541 href : this.href || "#",
3542 html: this.html || ''
3548 cfg.cls = typeof(cfg.cls) == 'undefined' ? 'active' : cfg.cls + ' active';
3551 // glyphicon and icon go before content..
3552 if (this.glyphicon || this.icon) {
3554 cfg.cn[0].html = '<i class="'+this.icon+'"></i><span>' + cfg.cn[0].html + '</span>'
3556 cfg.cn[0].html = '<span class="glyphicon glyphicon-' + this.glyphicon + '"></span>' + cfg.cn[0].html;
3564 cfg.cn[0].html += " <span class='caret'></span>";
3568 if (this.badge !== '') {
3570 cfg.cn[0].html += ' <span class="badge">' + this.badge + '</span>';
3577 initEvents: function() {
3578 // Roo.log('init events?');
3579 // Roo.log(this.el.dom);
3580 this.el.select('a',true).on('click', this.onClick, this);
3581 // at this point parent should be available..
3582 this.parent().register(this);
3585 onClick : function(e)
3587 if(this.preventDefault){
3591 if(this.fireEvent('click', this, e) === false){
3595 if (['tabs','pills'].indexOf(this.parent().type)!==-1) {
3596 if (typeof(this.parent().setActiveItem) !== 'undefined') {
3597 this.parent().setActiveItem(this);
3605 isActive: function () {
3608 setActive : function(state, fire)
3610 this.active = state;
3612 this.el.removeClass('active');
3613 } else if (!this.el.hasClass('active')) {
3614 this.el.addClass('active');
3617 this.fireEvent('changed', this, state);
3622 // this should not be here...
3633 * <span> icon </span>
3634 * <span> text </span>
3635 * <span>badge </span>
3639 * @class Roo.bootstrap.NavSidebarItem
3640 * @extends Roo.bootstrap.Component
3641 * Bootstrap Navbar.NavSidebarItem class
3643 * Create a new Navbar Button
3644 * @param {Object} config The config object
3646 Roo.bootstrap.NavSidebarItem = function(config){
3647 Roo.bootstrap.NavSidebarItem.superclass.constructor.call(this, config);
3652 * The raw click event for the entire grid.
3653 * @param {Roo.EventObject} e
3658 * Fires when the active item active state changes
3659 * @param {Roo.bootstrap.Navbar.Item} this
3660 * @param {boolean} state the new state
3668 Roo.extend(Roo.bootstrap.NavSidebarItem, Roo.bootstrap.NavItem, {
3671 getAutoCreate : function(){
3676 href : this.href || '#',
3688 html : this.html || ''
3693 cfg.cls += ' active';
3697 if (this.glyphicon || this.icon) {
3698 var c = this.glyphicon ? ('glyphicon glyphicon-'+this.glyphicon) : this.icon;
3699 a.cn.push({ tag : 'i', cls : c }) ;
3704 if (this.badge !== '') {
3705 a.cn.push({ tag: 'span', cls : 'badge pull-right ' + (this.badgecls || ''), html: this.badge });
3709 a.cn.push({ tag : 'i', cls : 'glyphicon glyphicon-chevron-down pull-right'});
3710 a.cls += 'dropdown-toggle treeview' ;
3734 * @class Roo.bootstrap.Row
3735 * @extends Roo.bootstrap.Component
3736 * Bootstrap Row class (contains columns...)
3740 * @param {Object} config The config object
3743 Roo.bootstrap.Row = function(config){
3744 Roo.bootstrap.Row.superclass.constructor.call(this, config);
3747 Roo.extend(Roo.bootstrap.Row, Roo.bootstrap.Component, {
3749 getAutoCreate : function(){
3768 * @class Roo.bootstrap.Element
3769 * @extends Roo.bootstrap.Component
3770 * Bootstrap Element class
3771 * @cfg {String} html contents of the element
3772 * @cfg {String} tag tag of the element
3773 * @cfg {String} cls class of the element
3776 * Create a new Element
3777 * @param {Object} config The config object
3780 Roo.bootstrap.Element = function(config){
3781 Roo.bootstrap.Element.superclass.constructor.call(this, config);
3784 Roo.extend(Roo.bootstrap.Element, Roo.bootstrap.Component, {
3791 getAutoCreate : function(){
3816 * @class Roo.bootstrap.Pagination
3817 * @extends Roo.bootstrap.Component
3818 * Bootstrap Pagination class
3819 * @cfg {String} size xs | sm | md | lg
3820 * @cfg {Boolean} inverse false | true
3823 * Create a new Pagination
3824 * @param {Object} config The config object
3827 Roo.bootstrap.Pagination = function(config){
3828 Roo.bootstrap.Pagination.superclass.constructor.call(this, config);
3831 Roo.extend(Roo.bootstrap.Pagination, Roo.bootstrap.Component, {
3837 getAutoCreate : function(){
3843 cfg.cls += ' inverse';
3849 cfg.cls += " " + this.cls;
3867 * @class Roo.bootstrap.PaginationItem
3868 * @extends Roo.bootstrap.Component
3869 * Bootstrap PaginationItem class
3870 * @cfg {String} html text
3871 * @cfg {String} href the link
3872 * @cfg {Boolean} preventDefault (true | false) default true
3873 * @cfg {Boolean} active (true | false) default false
3877 * Create a new PaginationItem
3878 * @param {Object} config The config object
3882 Roo.bootstrap.PaginationItem = function(config){
3883 Roo.bootstrap.PaginationItem.superclass.constructor.call(this, config);
3888 * The raw click event for the entire grid.
3889 * @param {Roo.EventObject} e
3895 Roo.extend(Roo.bootstrap.PaginationItem, Roo.bootstrap.Component, {
3899 preventDefault: true,
3903 getAutoCreate : function(){
3909 href : this.href ? this.href : '#',
3910 html : this.html ? this.html : ''
3920 cfg.cls = typeof(cfg.cls) !== 'undefined' ? cfg.cls + ' active' : 'active';
3926 initEvents: function() {
3928 this.el.on('click', this.onClick, this);
3931 onClick : function(e)
3933 Roo.log('PaginationItem on click ');
3934 if(this.preventDefault){
3938 this.fireEvent('click', this, e);
3954 * @class Roo.bootstrap.Slider
3955 * @extends Roo.bootstrap.Component
3956 * Bootstrap Slider class
3959 * Create a new Slider
3960 * @param {Object} config The config object
3963 Roo.bootstrap.Slider = function(config){
3964 Roo.bootstrap.Slider.superclass.constructor.call(this, config);
3967 Roo.extend(Roo.bootstrap.Slider, Roo.bootstrap.Component, {
3969 getAutoCreate : function(){
3973 cls: 'slider slider-sample1 vertical-handler ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all',
3977 cls: 'ui-slider-handle ui-state-default ui-corner-all'
3995 * @class Roo.bootstrap.Table
3996 * @extends Roo.bootstrap.Component
3997 * Bootstrap Table class
3998 * @cfg {String} cls table class
3999 * @cfg {String} align (left|center|right) Specifies the alignment of a table according to surrounding text
4000 * @cfg {String} bgcolor Specifies the background color for a table
4001 * @cfg {Number} border Specifies whether the table cells should have borders or not
4002 * @cfg {Number} cellpadding Specifies the space between the cell wall and the cell content
4003 * @cfg {Number} cellspacing Specifies the space between cells
4004 * @cfg {String} frame Specifies which parts of the outside borders that should be visible
4005 * @cfg {String} rules Specifies which parts of the inside borders that should be visible
4006 * @cfg {String} sortable Specifies that the table should be sortable
4007 * @cfg {String} summary Specifies a summary of the content of a table
4008 * @cfg {Number} width Specifies the width of a table
4010 * @cfg {boolean} striped Should the rows be alternative striped
4011 * @cfg {boolean} bordered Add borders to the table
4012 * @cfg {boolean} hover Add hover highlighting
4013 * @cfg {boolean} condensed Format condensed
4014 * @cfg {boolean} responsive Format condensed
4020 * Create a new Table
4021 * @param {Object} config The config object
4024 Roo.bootstrap.Table = function(config){
4025 Roo.bootstrap.Table.superclass.constructor.call(this, config);
4028 this.selModel = Roo.factory(this.sm, Roo.bootstrap.Table);
4029 this.sm = this.selModel;
4030 this.sm.xmodule = this.xmodule || false;
4032 if (this.cm && typeof(this.cm.config) == 'undefined') {
4033 this.colModel = new Roo.bootstrap.Table.ColumnModel(this.cm);
4034 this.cm = this.colModel;
4035 this.cm.xmodule = this.xmodule || false;
4038 this.store= Roo.factory(this.store, Roo.data);
4039 this.ds = this.store;
4040 this.ds.xmodule = this.xmodule || false;
4045 Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component, {
4067 getAutoCreate : function(){
4068 var cfg = Roo.apply({}, Roo.bootstrap.Table.superclass.getAutoCreate.call(this));
4077 cfg.cls += ' table-striped';
4080 cfg.cls += ' table-hover';
4082 if (this.bordered) {
4083 cfg.cls += ' table-bordered';
4085 if (this.condensed) {
4086 cfg.cls += ' table-condensed';
4088 if (this.responsive) {
4089 cfg.cls += ' table-responsive';
4096 cfg.cls+= ' ' +this.cls;
4099 // this lot should be simplifed...
4102 cfg.align=this.align;
4105 cfg.bgcolor=this.bgcolor;
4108 cfg.border=this.border;
4110 if (this.cellpadding) {
4111 cfg.cellpadding=this.cellpadding;
4113 if (this.cellspacing) {
4114 cfg.cellspacing=this.cellspacing;
4117 cfg.frame=this.frame;
4120 cfg.rules=this.rules;
4122 if (this.sortable) {
4123 cfg.sortable=this.sortable;
4126 cfg.summary=this.summary;
4129 cfg.width=this.width;
4132 if(this.store || this.cm){
4133 cfg.cn.push(this.renderHeader());
4134 cfg.cn.push(this.renderBody());
4135 cfg.cn.push(this.renderFooter());
4137 cfg.cls+= ' TableGrid';
4143 // initTableGrid : function()
4152 // var cm = this.cm;
4154 // for(var i = 0, len = cm.getColumnCount(); i < len; i++){
4157 // html: cm.getColumnHeader(i)
4161 // cfg.push(header);
4168 initEvents : function()
4170 if(!this.store || !this.cm){
4174 Roo.log('initEvents with ds!!!!');
4178 Roo.each(this.el.select('thead th.sortable', true).elements, function(e){
4179 e.on('click', _this.sort, _this);
4181 // this.maskEl = Roo.DomHelper.append(this.el.select('.TableGrid', true).first(), {tag: "div", cls:"x-dlg-mask"}, true);
4182 // this.maskEl.enableDisplayMode("block");
4183 // this.maskEl.show();
4185 this.store.on('load', this.onLoad, this);
4186 this.store.on('beforeload', this.onBeforeLoad, this);
4194 sort : function(e,el)
4196 var col = Roo.get(el)
4198 if(!col.hasClass('sortable')){
4202 var sort = col.attr('sort');
4205 if(col.hasClass('glyphicon-arrow-up')){
4209 this.store.sortInfo = {field : sort, direction : dir};
4214 renderHeader : function()
4223 for(var i = 0, len = cm.getColumnCount(); i < len; i++){
4225 var config = cm.config[i];
4229 html: cm.getColumnHeader(i)
4232 if(typeof(config.dataIndex) != 'undefined'){
4233 c.sort = config.dataIndex;
4236 if(typeof(config.sortable) != 'undefined' && config.sortable){
4240 if(typeof(config.width) != 'undefined'){
4241 c.style = 'width:' + config.width + 'px';
4250 renderBody : function()
4260 renderFooter : function()
4272 Roo.log('ds onload');
4277 Roo.each(this.el.select('thead th.sortable', true).elements, function(e){
4278 e.removeClass(['glyphicon', 'glyphicon-arrow-up', 'glyphicon-arrow-down']);
4280 if(e.hasClass('sortable') && e.attr('sort') == _this.store.sortInfo.field && _this.store.sortInfo.direction.toUpperCase() == 'ASC'){
4281 e.addClass(['glyphicon', 'glyphicon-arrow-up']);
4284 if(e.hasClass('sortable') && e.attr('sort') == _this.store.sortInfo.field && _this.store.sortInfo.direction.toUpperCase() == 'DESC'){
4285 e.addClass(['glyphicon', 'glyphicon-arrow-down']);
4289 var tbody = this.el.select('tbody', true).first();
4293 if(this.store.getCount() > 0){
4294 this.store.data.each(function(d){
4300 for(var i = 0, len = cm.getColumnCount(); i < len; i++){
4301 var renderer = cm.getRenderer(i);
4302 var config = cm.config[i];
4306 if(typeof(renderer) !== 'undefined'){
4307 value = renderer(d.data[cm.getDataIndex(i)], false, d);
4310 if(typeof(value) === 'object'){
4320 html: (typeof(value) === 'object') ? '' : value
4323 if(typeof(config.width) != 'undefined'){
4324 td.style = 'width:' + config.width + 'px';
4331 tbody.createChild(row);
4339 Roo.each(renders, function(r){
4340 _this.renderColumn(r);
4344 // if(this.loadMask){
4345 // this.maskEl.hide();
4349 onBeforeLoad : function()
4351 Roo.log('ds onBeforeLoad');
4355 // if(this.loadMask){
4356 // this.maskEl.show();
4362 this.el.select('tbody', true).first().dom.innerHTML = '';
4365 getSelectionModel : function(){
4367 this.selModel = new Roo.bootstrap.Table.RowSelectionModel();
4369 return this.selModel;
4372 renderColumn : function(r)
4375 r.cfg.render(Roo.get(r.id));
4378 Roo.each(r.cfg.cn, function(c){
4383 _this.renderColumn(child);
4400 * @class Roo.bootstrap.TableCell
4401 * @extends Roo.bootstrap.Component
4402 * Bootstrap TableCell class
4403 * @cfg {String} html cell contain text
4404 * @cfg {String} cls cell class
4405 * @cfg {String} tag cell tag (td|th) default td
4406 * @cfg {String} abbr Specifies an abbreviated version of the content in a cell
4407 * @cfg {String} align Aligns the content in a cell
4408 * @cfg {String} axis Categorizes cells
4409 * @cfg {String} bgcolor Specifies the background color of a cell
4410 * @cfg {Number} charoff Sets the number of characters the content will be aligned from the character specified by the char attribute
4411 * @cfg {Number} colspan Specifies the number of columns a cell should span
4412 * @cfg {String} headers Specifies one or more header cells a cell is related to
4413 * @cfg {Number} height Sets the height of a cell
4414 * @cfg {String} nowrap Specifies that the content inside a cell should not wrap
4415 * @cfg {Number} rowspan Sets the number of rows a cell should span
4416 * @cfg {String} scope Defines a way to associate header cells and data cells in a table
4417 * @cfg {String} valign Vertical aligns the content in a cell
4418 * @cfg {Number} width Specifies the width of a cell
4421 * Create a new TableCell
4422 * @param {Object} config The config object
4425 Roo.bootstrap.TableCell = function(config){
4426 Roo.bootstrap.TableCell.superclass.constructor.call(this, config);
4429 Roo.extend(Roo.bootstrap.TableCell, Roo.bootstrap.Component, {
4449 getAutoCreate : function(){
4450 var cfg = Roo.apply({}, Roo.bootstrap.TableCell.superclass.getAutoCreate.call(this));
4470 cfg.align=this.align
4476 cfg.bgcolor=this.bgcolor
4479 cfg.charoff=this.charoff
4482 cfg.colspan=this.colspan
4485 cfg.headers=this.headers
4488 cfg.height=this.height
4491 cfg.nowrap=this.nowrap
4494 cfg.rowspan=this.rowspan
4497 cfg.scope=this.scope
4500 cfg.valign=this.valign
4503 cfg.width=this.width
4522 * @class Roo.bootstrap.TableRow
4523 * @extends Roo.bootstrap.Component
4524 * Bootstrap TableRow class
4525 * @cfg {String} cls row class
4526 * @cfg {String} align Aligns the content in a table row
4527 * @cfg {String} bgcolor Specifies a background color for a table row
4528 * @cfg {Number} charoff Sets the number of characters the content will be aligned from the character specified by the char attribute
4529 * @cfg {String} valign Vertical aligns the content in a table row
4532 * Create a new TableRow
4533 * @param {Object} config The config object
4536 Roo.bootstrap.TableRow = function(config){
4537 Roo.bootstrap.TableRow.superclass.constructor.call(this, config);
4540 Roo.extend(Roo.bootstrap.TableRow, Roo.bootstrap.Component, {
4548 getAutoCreate : function(){
4549 var cfg = Roo.apply({}, Roo.bootstrap.TableRow.superclass.getAutoCreate.call(this));
4559 cfg.align = this.align;
4562 cfg.bgcolor = this.bgcolor;
4565 cfg.charoff = this.charoff;
4568 cfg.valign = this.valign;
4586 * @class Roo.bootstrap.TableBody
4587 * @extends Roo.bootstrap.Component
4588 * Bootstrap TableBody class
4589 * @cfg {String} cls element class
4590 * @cfg {String} tag element tag (thead|tbody|tfoot) default tbody
4591 * @cfg {String} align Aligns the content inside the element
4592 * @cfg {Number} charoff Sets the number of characters the content inside the element will be aligned from the character specified by the char attribute
4593 * @cfg {String} valign Vertical aligns the content inside the <tbody> element
4596 * Create a new TableBody
4597 * @param {Object} config The config object
4600 Roo.bootstrap.TableBody = function(config){
4601 Roo.bootstrap.TableBody.superclass.constructor.call(this, config);
4604 Roo.extend(Roo.bootstrap.TableBody, Roo.bootstrap.Component, {
4612 getAutoCreate : function(){
4613 var cfg = Roo.apply({}, Roo.bootstrap.TableBody.superclass.getAutoCreate.call(this));
4627 cfg.align = this.align;
4630 cfg.charoff = this.charoff;
4633 cfg.valign = this.valign;
4640 // initEvents : function()
4647 // this.store = Roo.factory(this.store, Roo.data);
4648 // this.store.on('load', this.onLoad, this);
4650 // this.store.load();
4654 // onLoad: function ()
4656 // this.fireEvent('load', this);
4666 * Ext JS Library 1.1.1
4667 * Copyright(c) 2006-2007, Ext JS, LLC.
4669 * Originally Released Under LGPL - original licence link has changed is not relivant.
4672 * <script type="text/javascript">
4675 // as we use this in bootstrap.
4676 Roo.namespace('Roo.form');
4678 * @class Roo.form.Action
4679 * Internal Class used to handle form actions
4681 * @param {Roo.form.BasicForm} el The form element or its id
4682 * @param {Object} config Configuration options
4687 // define the action interface
4688 Roo.form.Action = function(form, options){
4690 this.options = options || {};
4693 * Client Validation Failed
4696 Roo.form.Action.CLIENT_INVALID = 'client';
4698 * Server Validation Failed
4701 Roo.form.Action.SERVER_INVALID = 'server';
4703 * Connect to Server Failed
4706 Roo.form.Action.CONNECT_FAILURE = 'connect';
4708 * Reading Data from Server Failed
4711 Roo.form.Action.LOAD_FAILURE = 'load';
4713 Roo.form.Action.prototype = {
4715 failureType : undefined,
4716 response : undefined,
4720 run : function(options){
4725 success : function(response){
4730 handleResponse : function(response){
4734 // default connection failure
4735 failure : function(response){
4737 this.response = response;
4738 this.failureType = Roo.form.Action.CONNECT_FAILURE;
4739 this.form.afterAction(this, false);
4742 processResponse : function(response){
4743 this.response = response;
4744 if(!response.responseText){
4747 this.result = this.handleResponse(response);
4751 // utility functions used internally
4752 getUrl : function(appendParams){
4753 var url = this.options.url || this.form.url || this.form.el.dom.action;
4755 var p = this.getParams();
4757 url += (url.indexOf('?') != -1 ? '&' : '?') + p;
4763 getMethod : function(){
4764 return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
4767 getParams : function(){
4768 var bp = this.form.baseParams;
4769 var p = this.options.params;
4771 if(typeof p == "object"){
4772 p = Roo.urlEncode(Roo.applyIf(p, bp));
4773 }else if(typeof p == 'string' && bp){
4774 p += '&' + Roo.urlEncode(bp);
4777 p = Roo.urlEncode(bp);
4782 createCallback : function(){
4784 success: this.success,
4785 failure: this.failure,
4787 timeout: (this.form.timeout*1000),
4788 upload: this.form.fileUpload ? this.success : undefined
4793 Roo.form.Action.Submit = function(form, options){
4794 Roo.form.Action.Submit.superclass.constructor.call(this, form, options);
4797 Roo.extend(Roo.form.Action.Submit, Roo.form.Action, {
4800 haveProgress : false,
4801 uploadComplete : false,
4803 // uploadProgress indicator.
4804 uploadProgress : function()
4806 if (!this.form.progressUrl) {
4810 if (!this.haveProgress) {
4811 Roo.MessageBox.progress("Uploading", "Uploading");
4813 if (this.uploadComplete) {
4814 Roo.MessageBox.hide();
4818 this.haveProgress = true;
4820 var uid = this.form.findField('UPLOAD_IDENTIFIER').getValue();
4822 var c = new Roo.data.Connection();
4824 url : this.form.progressUrl,
4829 success : function(req){
4830 //console.log(data);
4834 rdata = Roo.decode(req.responseText)
4836 Roo.log("Invalid data from server..");
4840 if (!rdata || !rdata.success) {
4842 Roo.MessageBox.alert(Roo.encode(rdata));
4845 var data = rdata.data;
4847 if (this.uploadComplete) {
4848 Roo.MessageBox.hide();
4853 Roo.MessageBox.updateProgress(data.bytes_uploaded/data.bytes_total,
4854 Math.floor((data.bytes_total - data.bytes_uploaded)/1000) + 'k remaining'
4857 this.uploadProgress.defer(2000,this);
4860 failure: function(data) {
4861 Roo.log('progress url failed ');
4872 // run get Values on the form, so it syncs any secondary forms.
4873 this.form.getValues();
4875 var o = this.options;
4876 var method = this.getMethod();
4877 var isPost = method == 'POST';
4878 if(o.clientValidation === false || this.form.isValid()){
4880 if (this.form.progressUrl) {
4881 this.form.findField('UPLOAD_IDENTIFIER').setValue(
4882 (new Date() * 1) + '' + Math.random());
4887 Roo.Ajax.request(Roo.apply(this.createCallback(), {
4888 form:this.form.el.dom,
4889 url:this.getUrl(!isPost),
4891 params:isPost ? this.getParams() : null,
4892 isUpload: this.form.fileUpload
4895 this.uploadProgress();
4897 }else if (o.clientValidation !== false){ // client validation failed
4898 this.failureType = Roo.form.Action.CLIENT_INVALID;
4899 this.form.afterAction(this, false);
4903 success : function(response)
4905 this.uploadComplete= true;
4906 if (this.haveProgress) {
4907 Roo.MessageBox.hide();
4911 var result = this.processResponse(response);
4912 if(result === true || result.success){
4913 this.form.afterAction(this, true);
4917 this.form.markInvalid(result.errors);
4918 this.failureType = Roo.form.Action.SERVER_INVALID;
4920 this.form.afterAction(this, false);
4922 failure : function(response)
4924 this.uploadComplete= true;
4925 if (this.haveProgress) {
4926 Roo.MessageBox.hide();
4929 this.response = response;
4930 this.failureType = Roo.form.Action.CONNECT_FAILURE;
4931 this.form.afterAction(this, false);
4934 handleResponse : function(response){
4935 if(this.form.errorReader){
4936 var rs = this.form.errorReader.read(response);
4939 for(var i = 0, len = rs.records.length; i < len; i++) {
4940 var r = rs.records[i];
4944 if(errors.length < 1){
4948 success : rs.success,
4954 ret = Roo.decode(response.responseText);
4958 errorMsg: "Failed to read server message: " + (response ? response.responseText : ' - no message'),
4968 Roo.form.Action.Load = function(form, options){
4969 Roo.form.Action.Load.superclass.constructor.call(this, form, options);
4970 this.reader = this.form.reader;
4973 Roo.extend(Roo.form.Action.Load, Roo.form.Action, {
4978 Roo.Ajax.request(Roo.apply(
4979 this.createCallback(), {
4980 method:this.getMethod(),
4981 url:this.getUrl(false),
4982 params:this.getParams()
4986 success : function(response){
4988 var result = this.processResponse(response);
4989 if(result === true || !result.success || !result.data){
4990 this.failureType = Roo.form.Action.LOAD_FAILURE;
4991 this.form.afterAction(this, false);
4994 this.form.clearInvalid();
4995 this.form.setValues(result.data);
4996 this.form.afterAction(this, true);
4999 handleResponse : function(response){
5000 if(this.form.reader){
5001 var rs = this.form.reader.read(response);
5002 var data = rs.records && rs.records[0] ? rs.records[0].data : null;
5004 success : rs.success,
5008 return Roo.decode(response.responseText);
5012 Roo.form.Action.ACTION_TYPES = {
5013 'load' : Roo.form.Action.Load,
5014 'submit' : Roo.form.Action.Submit
5023 * @class Roo.bootstrap.Form
5024 * @extends Roo.bootstrap.Component
5025 * Bootstrap Form class
5026 * @cfg {String} method GET | POST (default POST)
5027 * @cfg {String} labelAlign top | left (default top)
5028 * @cfg {String} align left | right - for navbars
5033 * @param {Object} config The config object
5037 Roo.bootstrap.Form = function(config){
5038 Roo.bootstrap.Form.superclass.constructor.call(this, config);
5041 * @event clientvalidation
5042 * If the monitorValid config option is true, this event fires repetitively to notify of valid state
5043 * @param {Form} this
5044 * @param {Boolean} valid true if the form has passed client-side validation
5046 clientvalidation: true,
5048 * @event beforeaction
5049 * Fires before any action is performed. Return false to cancel the action.
5050 * @param {Form} this
5051 * @param {Action} action The action to be performed
5055 * @event actionfailed
5056 * Fires when an action fails.
5057 * @param {Form} this
5058 * @param {Action} action The action that failed
5060 actionfailed : true,
5062 * @event actioncomplete
5063 * Fires when an action is completed.
5064 * @param {Form} this
5065 * @param {Action} action The action that completed
5067 actioncomplete : true
5072 Roo.extend(Roo.bootstrap.Form, Roo.bootstrap.Component, {
5075 * @cfg {String} method
5076 * The request method to use (GET or POST) for form actions if one isn't supplied in the action options.
5081 * The URL to use for form actions if one isn't supplied in the action options.
5084 * @cfg {Boolean} fileUpload
5085 * Set to true if this form is a file upload.
5089 * @cfg {Object} baseParams
5090 * Parameters to pass with all requests. e.g. baseParams: {id: '123', foo: 'bar'}.
5094 * @cfg {Number} timeout Timeout for form actions in seconds (default is 30 seconds).
5098 * @cfg {Sting} align (left|right) for navbar forms
5103 activeAction : null,
5106 * By default wait messages are displayed with Roo.MessageBox.wait. You can target a specific
5107 * element by passing it or its id or mask the form itself by passing in true.
5110 waitMsgTarget : false,
5115 * By default wait messages are displayed with Roo.MessageBox.wait. You can target a specific
5116 * element by passing it or its id or mask the form itself by passing in true.
5120 getAutoCreate : function(){
5124 method : this.method || 'POST',
5125 id : this.id || Roo.id(),
5128 if (this.parent().xtype.match(/^Nav/)) {
5129 cfg.cls = 'navbar-form navbar-' + this.align;
5133 if (this.labelAlign == 'left' ) {
5134 cfg.cls += ' form-horizontal';
5140 initEvents : function()
5142 this.el.on('submit', this.onSubmit, this);
5147 onSubmit : function(e){
5152 * Returns true if client-side validation on the form is successful.
5155 isValid : function(){
5156 var items = this.getItems();
5158 items.each(function(f){
5167 * Returns true if any fields in this form have changed since their original load.
5170 isDirty : function(){
5172 var items = this.getItems();
5173 items.each(function(f){
5183 * Performs a predefined action (submit or load) or custom actions you define on this form.
5184 * @param {String} actionName The name of the action type
5185 * @param {Object} options (optional) The options to pass to the action. All of the config options listed
5186 * below are supported by both the submit and load actions unless otherwise noted (custom actions could also
5187 * accept other config options):
5189 Property Type Description
5190 ---------------- --------------- ----------------------------------------------------------------------------------
5191 url String The url for the action (defaults to the form's url)
5192 method String The form method to use (defaults to the form's method, or POST if not defined)
5193 params String/Object The params to pass (defaults to the form's baseParams, or none if not defined)
5194 clientValidation Boolean Applies to submit only. Pass true to call form.isValid() prior to posting to
5195 validate the form on the client (defaults to false)
5197 * @return {BasicForm} this
5199 doAction : function(action, options){
5200 if(typeof action == 'string'){
5201 action = new Roo.form.Action.ACTION_TYPES[action](this, options);
5203 if(this.fireEvent('beforeaction', this, action) !== false){
5204 this.beforeAction(action);
5205 action.run.defer(100, action);
5211 beforeAction : function(action){
5212 var o = action.options;
5214 // not really supported yet.. ??
5216 //if(this.waitMsgTarget === true){
5217 this.el.mask(o.waitMsg || "Sending", 'x-mask-loading');
5218 //}else if(this.waitMsgTarget){
5219 // this.waitMsgTarget = Roo.get(this.waitMsgTarget);
5220 // this.waitMsgTarget.mask(o.waitMsg || "Sending", 'x-mask-loading');
5222 // Roo.MessageBox.wait(o.waitMsg || "Sending", o.waitTitle || this.waitTitle || 'Please Wait...');
5228 afterAction : function(action, success){
5229 this.activeAction = null;
5230 var o = action.options;
5232 //if(this.waitMsgTarget === true){
5234 //}else if(this.waitMsgTarget){
5235 // this.waitMsgTarget.unmask();
5237 // Roo.MessageBox.updateProgress(1);
5238 // Roo.MessageBox.hide();
5245 Roo.callback(o.success, o.scope, [this, action]);
5246 this.fireEvent('actioncomplete', this, action);
5250 // failure condition..
5251 // we have a scenario where updates need confirming.
5252 // eg. if a locking scenario exists..
5253 // we look for { errors : { needs_confirm : true }} in the response.
5255 (typeof(action.result) != 'undefined') &&
5256 (typeof(action.result.errors) != 'undefined') &&
5257 (typeof(action.result.errors.needs_confirm) != 'undefined')
5260 Roo.log("not supported yet");
5263 Roo.MessageBox.confirm(
5264 "Change requires confirmation",
5265 action.result.errorMsg,
5270 _t.doAction('submit', { params : { _submit_confirmed : 1 } } );
5280 Roo.callback(o.failure, o.scope, [this, action]);
5281 // show an error message if no failed handler is set..
5282 if (!this.hasListener('actionfailed')) {
5283 Roo.log("need to add dialog support");
5285 Roo.MessageBox.alert("Error",
5286 (typeof(action.result) != 'undefined' && typeof(action.result.errorMsg) != 'undefined') ?
5287 action.result.errorMsg :
5288 "Saving Failed, please check your entries or try again"
5293 this.fireEvent('actionfailed', this, action);
5298 * Find a Roo.form.Field in this form by id, dataIndex, name or hiddenName
5299 * @param {String} id The value to search for
5302 findField : function(id){
5303 var items = this.getItems();
5304 var field = items.get(id);
5306 items.each(function(f){
5307 if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
5314 return field || null;
5317 * Mark fields in this form invalid in bulk.
5318 * @param {Array/Object} errors Either an array in the form [{id:'fieldId', msg:'The message'},...] or an object hash of {id: msg, id2: msg2}
5319 * @return {BasicForm} this
5321 markInvalid : function(errors){
5322 if(errors instanceof Array){
5323 for(var i = 0, len = errors.length; i < len; i++){
5324 var fieldError = errors[i];
5325 var f = this.findField(fieldError.id);
5327 f.markInvalid(fieldError.msg);
5333 if(typeof errors[id] != 'function' && (field = this.findField(id))){
5334 field.markInvalid(errors[id]);
5338 //Roo.each(this.childForms || [], function (f) {
5339 // f.markInvalid(errors);
5346 * Set values for fields in this form in bulk.
5347 * @param {Array/Object} values Either an array in the form [{id:'fieldId', value:'foo'},...] or an object hash of {id: value, id2: value2}
5348 * @return {BasicForm} this
5350 setValues : function(values){
5351 if(values instanceof Array){ // array of objects
5352 for(var i = 0, len = values.length; i < len; i++){
5354 var f = this.findField(v.id);
5356 f.setValue(v.value);
5357 if(this.trackResetOnLoad){
5358 f.originalValue = f.getValue();
5362 }else{ // object hash
5365 if(typeof values[id] != 'function' && (field = this.findField(id))){
5367 if (field.setFromData &&
5369 field.displayField &&
5370 // combos' with local stores can
5371 // be queried via setValue()
5372 // to set their value..
5373 (field.store && !field.store.isLocal)
5377 sd[field.valueField] = typeof(values[field.hiddenName]) == 'undefined' ? '' : values[field.hiddenName];
5378 sd[field.displayField] = typeof(values[field.name]) == 'undefined' ? '' : values[field.name];
5379 field.setFromData(sd);
5382 field.setValue(values[id]);
5386 if(this.trackResetOnLoad){
5387 field.originalValue = field.getValue();
5393 //Roo.each(this.childForms || [], function (f) {
5394 // f.setValues(values);
5401 * Returns the fields in this form as an object with key/value pairs. If multiple fields exist with the same name
5402 * they are returned as an array.
5403 * @param {Boolean} asString
5406 getValues : function(asString){
5407 //if (this.childForms) {
5408 // copy values from the child forms
5409 // Roo.each(this.childForms, function (f) {
5410 // this.setValues(f.getValues());
5416 var fs = Roo.lib.Ajax.serializeForm(this.el.dom);
5417 if(asString === true){
5420 return Roo.urlDecode(fs);
5424 * Returns the fields in this form as an object with key/value pairs.
5425 * This differs from getValues as it calls getValue on each child item, rather than using dom data.
5428 getFieldValues : function(with_hidden)
5430 var items = this.getItems();
5432 items.each(function(f){
5436 var v = f.getValue();
5437 if (f.inputType =='radio') {
5438 if (typeof(ret[f.getName()]) == 'undefined') {
5439 ret[f.getName()] = ''; // empty..
5442 if (!f.el.dom.checked) {
5450 // not sure if this supported any more..
5451 if ((typeof(v) == 'object') && f.getRawValue) {
5452 v = f.getRawValue() ; // dates..
5454 // combo boxes where name != hiddenName...
5455 if (f.name != f.getName()) {
5456 ret[f.name] = f.getRawValue();
5458 ret[f.getName()] = v;
5465 * Clears all invalid messages in this form.
5466 * @return {BasicForm} this
5468 clearInvalid : function(){
5469 var items = this.getItems();
5471 items.each(function(f){
5482 * @return {BasicForm} this
5485 var items = this.getItems();
5486 items.each(function(f){
5490 Roo.each(this.childForms || [], function (f) {
5497 getItems : function()
5499 var r=new Roo.util.MixedCollection(false, function(o){
5500 return o.id || (o.id = Roo.id());
5502 var iter = function(el) {
5509 Roo.each(el.items,function(e) {
5528 * Ext JS Library 1.1.1
5529 * Copyright(c) 2006-2007, Ext JS, LLC.
5531 * Originally Released Under LGPL - original licence link has changed is not relivant.
5534 * <script type="text/javascript">
5537 * @class Roo.form.VTypes
5538 * Overridable validation definitions. The validations provided are basic and intended to be easily customizable and extended.
5541 Roo.form.VTypes = function(){
5542 // closure these in so they are only created once.
5543 var alpha = /^[a-zA-Z_]+$/;
5544 var alphanum = /^[a-zA-Z0-9_]+$/;
5545 var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;
5546 var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
5548 // All these messages and functions are configurable
5551 * The function used to validate email addresses
5552 * @param {String} value The email address
5554 'email' : function(v){
5555 return email.test(v);
5558 * The error text to display when the email validation function returns false
5561 'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
5563 * The keystroke filter mask to be applied on email input
5566 'emailMask' : /[a-z0-9_\.\-@]/i,
5569 * The function used to validate URLs
5570 * @param {String} value The URL
5572 'url' : function(v){
5576 * The error text to display when the url validation function returns false
5579 'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
5582 * The function used to validate alpha values
5583 * @param {String} value The value
5585 'alpha' : function(v){
5586 return alpha.test(v);
5589 * The error text to display when the alpha validation function returns false
5592 'alphaText' : 'This field should only contain letters and _',
5594 * The keystroke filter mask to be applied on alpha input
5597 'alphaMask' : /[a-z_]/i,
5600 * The function used to validate alphanumeric values
5601 * @param {String} value The value
5603 'alphanum' : function(v){
5604 return alphanum.test(v);
5607 * The error text to display when the alphanumeric validation function returns false
5610 'alphanumText' : 'This field should only contain letters, numbers and _',
5612 * The keystroke filter mask to be applied on alphanumeric input
5615 'alphanumMask' : /[a-z0-9_]/i
5625 * @class Roo.bootstrap.Input
5626 * @extends Roo.bootstrap.Component
5627 * Bootstrap Input class
5628 * @cfg {Boolean} disabled is it disabled
5629 * @cfg {String} fieldLabel - the label associated
5630 * @cfg {String} inputType button | checkbox | email | file | hidden | image | number | password | radio | range | reset | search | submit | text
5631 * @cfg {String} name name of the input
5632 * @cfg {string} fieldLabel - the label associated
5633 * @cfg {string} inputType - input / file submit ...
5634 * @cfg {string} placeholder - placeholder to put in text.
5635 * @cfg {string} before - input group add on before
5636 * @cfg {string} after - input group add on after
5637 * @cfg {string} size - (lg|sm) or leave empty..
5638 * @cfg {Number} xs colspan out of 12 for mobile-sized screens
5639 * @cfg {Number} sm colspan out of 12 for tablet-sized screens
5640 * @cfg {Number} md colspan out of 12 for computer-sized screens
5641 * @cfg {Number} lg colspan out of 12 for large computer-sized screens
5642 * @cfg {string} value default value of the input
5643 * @cfg {Number} labelWidth set the width of label (0-12)
5644 * @cfg {String} labelAlign (top|left)
5645 * @cfg {Boolean} readOnly Specifies that the field should be read-only
5649 * Create a new Input
5650 * @param {Object} config The config object
5653 Roo.bootstrap.Input = function(config){
5654 Roo.bootstrap.Input.superclass.constructor.call(this, config);
5659 * Fires when this field receives input focus.
5660 * @param {Roo.form.Field} this
5665 * Fires when this field loses input focus.
5666 * @param {Roo.form.Field} this
5671 * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed. You can check
5672 * {@link Roo.EventObject#getKey} to determine which key was pressed.
5673 * @param {Roo.form.Field} this
5674 * @param {Roo.EventObject} e The event object
5679 * Fires just before the field blurs if the field value has changed.
5680 * @param {Roo.form.Field} this
5681 * @param {Mixed} newValue The new value
5682 * @param {Mixed} oldValue The original value
5687 * Fires after the field has been marked as invalid.
5688 * @param {Roo.form.Field} this
5689 * @param {String} msg The validation message
5694 * Fires after the field has been validated with no errors.
5695 * @param {Roo.form.Field} this
5700 * Fires after the key up
5701 * @param {Roo.form.Field} this
5702 * @param {Roo.EventObject} e The event Object
5708 Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component, {
5710 * @cfg {String/Boolean} validationEvent The event that should initiate field validation. Set to false to disable
5711 automatic validation (defaults to "keyup").
5713 validationEvent : "keyup",
5715 * @cfg {Boolean} validateOnBlur Whether the field should validate when it loses focus (defaults to true).
5717 validateOnBlur : true,
5719 * @cfg {Number} validationDelay The length of time in milliseconds after user input begins until validation is initiated (defaults to 250)
5721 validationDelay : 250,
5723 * @cfg {String} focusClass The CSS class to use when the field receives focus (defaults to "x-form-focus")
5725 focusClass : "x-form-focus", // not needed???
5729 * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to "x-form-invalid")
5731 invalidClass : "has-error",
5734 * @cfg {Boolean} selectOnFocus True to automatically select any existing field text when the field receives input focus (defaults to false)
5736 selectOnFocus : false,
5739 * @cfg {String} maskRe An input mask regular expression that will be used to filter keystrokes that don't match (defaults to null)
5743 * @cfg {String} vtype A validation type name as defined in {@link Roo.form.VTypes} (defaults to null)
5748 * @cfg {Boolean} disableKeyFilter True to disable input keystroke filtering (defaults to false)
5750 disableKeyFilter : false,
5753 * @cfg {Boolean} disabled True to disable the field (defaults to false).
5757 * @cfg {Boolean} allowBlank False to validate that the value length > 0 (defaults to true)
5761 * @cfg {String} blankText Error text to display if the allow blank validation fails (defaults to "This field is required")
5763 blankText : "This field is required",
5766 * @cfg {Number} minLength Minimum input field length required (defaults to 0)
5770 * @cfg {Number} maxLength Maximum input field length allowed (defaults to Number.MAX_VALUE)
5772 maxLength : Number.MAX_VALUE,
5774 * @cfg {String} minLengthText Error text to display if the minimum length validation fails (defaults to "The minimum length for this field is {minLength}")
5776 minLengthText : "The minimum length for this field is {0}",
5778 * @cfg {String} maxLengthText Error text to display if the maximum length validation fails (defaults to "The maximum length for this field is {maxLength}")
5780 maxLengthText : "The maximum length for this field is {0}",
5784 * @cfg {Function} validator A custom validation function to be called during field validation (defaults to null).
5785 * If available, this function will be called only after the basic validators all return true, and will be passed the
5786 * current field value and expected to return boolean true if the value is valid or a string error message if invalid.
5790 * @cfg {RegExp} regex A JavaScript RegExp object to be tested against the field value during validation (defaults to null).
5791 * If available, this regex will be evaluated only after the basic validators all return true, and will be passed the
5792 * current field value. If the test fails, the field will be marked invalid using {@link #regexText}.
5796 * @cfg {String} regexText The error text to display if {@link #regex} is used and the test fails during validation (defaults to "")
5819 parentLabelAlign : function()
5822 while (parent.parent()) {
5823 parent = parent.parent();
5824 if (typeof(parent.labelAlign) !='undefined') {
5825 return parent.labelAlign;
5832 getAutoCreate : function(){
5834 var align = (!this.labelAlign) ? this.parentLabelAlign() : this.labelAlign;
5840 if(this.inputType != 'hidden'){
5841 cfg.cls = 'form-group' //input-group
5847 type : this.inputType,
5849 cls : 'form-control',
5850 placeholder : this.placeholder || ''
5854 if(this.maxLength && this.maxLength != Number.MAX_VALUE){
5855 input.maxLength = this.maxLength;
5858 if (this.disabled) {
5859 input.disabled=true;
5862 if (this.readOnly) {
5863 input.readonly=true;
5867 input.name = this.name;
5870 input.cls += ' input-' + this.size;
5873 ['xs','sm','md','lg'].map(function(size){
5874 if (settings[size]) {
5875 cfg.cls += ' col-' + size + '-' + settings[size];
5879 var inputblock = input;
5881 if (this.before || this.after) {
5884 cls : 'input-group',
5887 if (this.before && typeof(this.before) == 'string') {
5889 inputblock.cn.push({
5891 cls : 'roo-input-before input-group-addon',
5895 if (this.before && typeof(this.before) == 'object') {
5896 this.before = Roo.factory(this.before);
5897 Roo.log(this.before);
5898 inputblock.cn.push({
5900 cls : 'roo-input-before input-group-' +
5901 (this.before.xtype == 'Button' ? 'btn' : 'addon'), //?? what about checkboxes - that looks like a bit of a hack thought?
5905 inputblock.cn.push(input);
5907 if (this.after && typeof(this.after) == 'string') {
5908 inputblock.cn.push({
5910 cls : 'roo-input-after input-group-addon',
5914 if (this.after && typeof(this.after) == 'object') {
5915 this.after = Roo.factory(this.after);
5916 Roo.log(this.after);
5917 inputblock.cn.push({
5919 cls : 'roo-input-after input-group-' +
5920 (this.before.xtype == 'Button' ? 'btn' : 'addon'), //?? what about checkboxes - that looks like a bit of a hack thought?
5925 if (align ==='left' && this.fieldLabel.length) {
5926 Roo.log("left and has label");
5932 cls : 'control-label col-sm-' + this.labelWidth,
5933 html : this.fieldLabel
5937 cls : "col-sm-" + (12 - this.labelWidth),
5944 } else if ( this.fieldLabel.length) {
5950 //cls : 'input-group-addon',
5951 html : this.fieldLabel
5961 Roo.log(" no label && no align");
5970 Roo.log('input-parentType: ' + this.parentType);
5972 if (this.parentType === 'Navbar' && this.parent().bar) {
5973 cfg.cls += ' navbar-form';
5981 * return the real input element.
5983 inputEl: function ()
5985 return this.el.select('input.form-control',true).first();
5987 setDisabled : function(v)
5989 var i = this.inputEl().dom;
5991 i.removeAttribute('disabled');
5995 i.setAttribute('disabled','true');
5997 initEvents : function()
6000 this.inputEl().on("keydown" , this.fireKey, this);
6001 this.inputEl().on("focus", this.onFocus, this);
6002 this.inputEl().on("blur", this.onBlur, this);
6004 this.inputEl().relayEvent('keyup', this);
6006 // reference to original value for reset
6007 this.originalValue = this.getValue();
6008 //Roo.form.TextField.superclass.initEvents.call(this);
6009 if(this.validationEvent == 'keyup'){
6010 this.validationTask = new Roo.util.DelayedTask(this.validate, this);
6011 this.inputEl().on('keyup', this.filterValidation, this);
6013 else if(this.validationEvent !== false){
6014 this.inputEl().on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
6017 if(this.selectOnFocus){
6018 this.on("focus", this.preFocus, this);
6021 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Roo.form.VTypes[this.vtype+'Mask']))){
6022 this.inputEl().on("keypress", this.filterKeys, this);
6025 this.el.on("keyup", this.onKeyUp, this, {buffer:50});
6026 this.el.on("click", this.autoSize, this);
6029 if(this.inputEl().is('input[type=password]') && Roo.isSafari){
6030 this.inputEl().on('keydown', this.SafariOnKeyDown, this);
6033 if (typeof(this.before) == 'object') {
6034 this.before.render(this.el.select('.roo-input-before',true).first());
6036 if (typeof(this.after) == 'object') {
6037 this.after.render(this.el.select('.roo-input-after',true).first());
6042 filterValidation : function(e){
6043 if(!e.isNavKeyPress()){
6044 this.validationTask.delay(this.validationDelay);
6048 * Validates the field value
6049 * @return {Boolean} True if the value is valid, else false
6051 validate : function(){
6052 //if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
6053 if(this.disabled || this.validateValue(this.getRawValue())){
6054 this.clearInvalid();
6062 * Validates a value according to the field's validation rules and marks the field as invalid
6063 * if the validation fails
6064 * @param {Mixed} value The value to validate
6065 * @return {Boolean} True if the value is valid, else false
6067 validateValue : function(value){
6068 if(value.length < 1) { // if it's blank
6069 if(this.allowBlank){
6070 this.clearInvalid();
6073 this.markInvalid(this.blankText);
6077 if(value.length < this.minLength){
6078 this.markInvalid(String.format(this.minLengthText, this.minLength));
6081 if(value.length > this.maxLength){
6082 this.markInvalid(String.format(this.maxLengthText, this.maxLength));
6086 var vt = Roo.form.VTypes;
6087 if(!vt[this.vtype](value, this)){
6088 this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
6092 if(typeof this.validator == "function"){
6093 var msg = this.validator(value);
6095 this.markInvalid(msg);
6099 if(this.regex && !this.regex.test(value)){
6100 this.markInvalid(this.regexText);
6109 fireKey : function(e){
6110 //Roo.log('field ' + e.getKey());
6111 if(e.isNavKeyPress()){
6112 this.fireEvent("specialkey", this, e);
6115 focus : function (selectText){
6117 this.inputEl().focus();
6118 if(selectText === true){
6119 this.inputEl().dom.select();
6125 onFocus : function(){
6126 if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
6127 // this.el.addClass(this.focusClass);
6130 this.hasFocus = true;
6131 this.startValue = this.getValue();
6132 this.fireEvent("focus", this);
6136 beforeBlur : Roo.emptyFn,
6140 onBlur : function(){
6142 if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
6143 //this.el.removeClass(this.focusClass);
6145 this.hasFocus = false;
6146 if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
6149 var v = this.getValue();
6150 if(String(v) !== String(this.startValue)){
6151 this.fireEvent('change', this, v, this.startValue);
6153 this.fireEvent("blur", this);
6157 * Resets the current field value to the originally loaded value and clears any validation messages
6160 this.setValue(this.originalValue);
6161 this.clearInvalid();
6164 * Returns the name of the field
6165 * @return {Mixed} name The name field
6167 getName: function(){
6171 * Returns the normalized data value (undefined or emptyText will be returned as ''). To return the raw value see {@link #getRawValue}.
6172 * @return {Mixed} value The field value
6174 getValue : function(){
6175 return this.inputEl().getValue();
6178 * Returns the raw data value which may or may not be a valid, defined value. To return a normalized value see {@link #getValue}.
6179 * @return {Mixed} value The field value
6181 getRawValue : function(){
6182 var v = this.inputEl().getValue();
6188 * Sets the underlying DOM field's value directly, bypassing validation. To set the value with validation see {@link #setValue}.
6189 * @param {Mixed} value The value to set
6191 setRawValue : function(v){
6192 return this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
6195 selectText : function(start, end){
6196 var v = this.getRawValue();
6198 start = start === undefined ? 0 : start;
6199 end = end === undefined ? v.length : end;
6200 var d = this.inputEl().dom;
6201 if(d.setSelectionRange){
6202 d.setSelectionRange(start, end);
6203 }else if(d.createTextRange){
6204 var range = d.createTextRange();
6205 range.moveStart("character", start);
6206 range.moveEnd("character", v.length-end);
6213 * Sets a data value into the field and validates it. To set the value directly without validation see {@link #setRawValue}.
6214 * @param {Mixed} value The value to set
6216 setValue : function(v){
6219 this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
6225 processValue : function(value){
6226 if(this.stripCharsRe){
6227 var newValue = value.replace(this.stripCharsRe, '');
6228 if(newValue !== value){
6229 this.setRawValue(newValue);
6236 preFocus : function(){
6238 if(this.selectOnFocus){
6239 this.inputEl().dom.select();
6242 filterKeys : function(e){
6244 if(!Roo.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
6247 var c = e.getCharCode(), cc = String.fromCharCode(c);
6248 if(Roo.isIE && (e.isSpecialKey() || !cc)){
6251 if(!this.maskRe.test(cc)){
6256 * Clear any invalid styles/messages for this field
6258 clearInvalid : function(){
6260 if(!this.el || this.preventMark){ // not rendered
6263 this.el.removeClass(this.invalidClass);
6265 switch(this.msgTarget){
6267 this.el.dom.qtip = '';
6270 this.el.dom.title = '';
6274 Roo.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
6279 this.errorIcon.dom.qtip = '';
6280 this.errorIcon.hide();
6281 this.un('resize', this.alignErrorIcon, this);
6285 var t = Roo.getDom(this.msgTarget);
6287 t.style.display = 'none';
6291 this.fireEvent('valid', this);
6294 * Mark this field as invalid
6295 * @param {String} msg The validation message
6297 markInvalid : function(msg){
6298 if(!this.el || this.preventMark){ // not rendered
6301 this.el.addClass(this.invalidClass);
6303 msg = msg || this.invalidText;
6304 switch(this.msgTarget){
6306 this.el.dom.qtip = msg;
6307 this.el.dom.qclass = 'x-form-invalid-tip';
6308 if(Roo.QuickTips){ // fix for floating editors interacting with DND
6309 Roo.QuickTips.enable();
6313 this.el.dom.title = msg;
6317 var elp = this.el.findParent('.x-form-element', 5, true);
6318 this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
6319 this.errorEl.setWidth(elp.getWidth(true)-20);
6321 this.errorEl.update(msg);
6322 Roo.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
6325 if(!this.errorIcon){
6326 var elp = this.el.findParent('.x-form-element', 5, true);
6327 this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
6329 this.alignErrorIcon();
6330 this.errorIcon.dom.qtip = msg;
6331 this.errorIcon.dom.qclass = 'x-form-invalid-tip';
6332 this.errorIcon.show();
6333 this.on('resize', this.alignErrorIcon, this);
6336 var t = Roo.getDom(this.msgTarget);
6338 t.style.display = this.msgDisplay;
6342 this.fireEvent('invalid', this, msg);
6345 SafariOnKeyDown : function(event)
6347 // this is a workaround for a password hang bug on chrome/ webkit.
6349 var isSelectAll = false;
6351 if(this.inputEl().dom.selectionEnd > 0){
6352 isSelectAll = (this.inputEl().dom.selectionEnd - this.inputEl().dom.selectionStart - this.getValue().length == 0) ? true : false;
6354 if(((event.getKey() == 8 || event.getKey() == 46) && this.getValue().length ==1)){ // backspace and delete key
6355 event.preventDefault();
6360 if(isSelectAll){ // backspace and delete key
6362 event.preventDefault();
6363 // this is very hacky as keydown always get's upper case.
6365 var cc = String.fromCharCode(event.getCharCode());
6366 this.setValue( event.shiftKey ? cc : cc.toLowerCase());
6370 adjustWidth : function(tag, w){
6371 tag = tag.toLowerCase();
6372 if(typeof w == 'number' && Roo.isStrict && !Roo.isSafari){
6373 if(Roo.isIE && (tag == 'input' || tag == 'textarea')){
6377 if(tag == 'textarea'){
6380 }else if(Roo.isOpera){
6384 if(tag == 'textarea'){