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..
249 if (typeof (tree.menu) != 'undefined') {
250 tree.menu.parentType = cn.xtype;
251 tree.menu.triggerEl = cn.el;
252 nitems.push(cn.addxtype(Roo.apply({}, tree.menu)));
256 if (!tree.items || !tree.items.length) {
260 var items = tree.items;
263 //Roo.log(items.length);
265 for(var i =0;i < items.length;i++) {
266 nitems.push(cn.addxtype(Roo.apply({}, items[i])));
287 * @class Roo.bootstrap.Body
288 * @extends Roo.bootstrap.Component
289 * Bootstrap Body class
293 * @param {Object} config The config object
296 Roo.bootstrap.Body = function(config){
297 Roo.bootstrap.Body.superclass.constructor.call(this, config);
298 this.el = Roo.get(document.body);
299 if (this.cls && this.cls.length) {
300 Roo.get(document.body).addClass(this.cls);
304 Roo.extend(Roo.bootstrap.Body, Roo.bootstrap.Component, {
309 onRender : function(ct, position)
311 /* Roo.log("Roo.bootstrap.Body - onRender");
312 if (this.cls && this.cls.length) {
313 Roo.get(document.body).addClass(this.cls);
333 * @class Roo.bootstrap.ButtonGroup
334 * @extends Roo.bootstrap.Component
335 * Bootstrap ButtonGroup class
336 * @cfg {String} size lg | sm | xs (default empty normal)
337 * @cfg {String} align vertical | justified (default none)
338 * @cfg {String} direction up | down (default down)
339 * @cfg {Boolean} toolbar false | true
340 * @cfg {Boolean} btn true | false
345 * @param {Object} config The config object
348 Roo.bootstrap.ButtonGroup = function(config){
349 Roo.bootstrap.ButtonGroup.superclass.constructor.call(this, config);
352 Roo.extend(Roo.bootstrap.ButtonGroup, Roo.bootstrap.Component, {
360 getAutoCreate : function(){
366 cfg.html = this.html || cfg.html;
377 if (['vertical','justified'].indexOf(this.align)!==-1) {
378 cfg.cls = 'btn-group-' + this.align;
380 if (this.align == 'justified') {
381 console.log(this.items);
385 if (['lg','sm','xs'].indexOf(this.size)!==-1) {
386 cfg.cls += ' btn-group-' + this.size;
389 if (this.direction == 'up') {
390 cfg.cls += ' dropup' ;
406 * @class Roo.bootstrap.Button
407 * @extends Roo.bootstrap.Component
408 * Bootstrap Button class
409 * @cfg {String} html The button content
410 * @cfg {String} weight default (or empty) | primary | success | info | warning | danger | link
411 * @cfg {String} size empty | lg | sm | xs
412 * @cfg {String} tag empty | a | input | submit
413 * @cfg {String} href empty or href
414 * @cfg {Boolean} disabled false | true
415 * @cfg {Boolean} isClose false | true
416 * @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
417 * @cfg {String} badge text for badge
418 * @cfg {String} theme default (or empty) | glow
419 * @cfg {Boolean} inverse false | true
420 * @cfg {Boolean} toggle false | true
421 * @cfg {String} ontext text for on toggle state
422 * @cfg {String} offtext text for off toggle state
423 * @cfg {Boolean} defaulton true | false
424 * @cfg {Boolean} preventDefault (true | false) default true
425 * @cfg {Boolean} removeClass true | false remove the standard class..
426 * @cfg {String} target (_self|_blank|_parent|_top)target for a href.
429 * Create a new button
430 * @param {Object} config The config object
434 Roo.bootstrap.Button = function(config){
435 Roo.bootstrap.Button.superclass.constructor.call(this, config);
440 * When a butotn is pressed
441 * @param {Roo.EventObject} e
446 * After the button has been toggles
447 * @param {Roo.EventObject} e
448 * @param {boolean} pressed (also available as button.pressed)
454 Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, {
472 preventDefault: true,
481 getAutoCreate : function(){
489 if (['a', 'button', 'input', 'submit'].indexOf(this.tag) < 0) {
490 throw "Invalid value for tag: " + this.tag + ". must be a, button, input or submit.";
495 cfg.html = '<span class="roo-button-text">' + (this.html || cfg.html) + '</span>';
497 if (this.toggle == true) {
500 cls: 'slider-frame roo-button',
505 'data-off-text':'OFF',
506 cls: 'slider-button',
512 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
513 cfg.cls += ' '+this.weight;
522 cfg["aria-hidden"] = true;
524 cfg.html = "×";
530 if (this.theme==='default') {
531 cfg.cls = 'btn roo-button';
533 //if (this.parentType != 'Navbar') {
534 this.weight = this.weight.length ? this.weight : 'default';
536 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
538 cfg.cls += ' btn-' + this.weight;
540 } else if (this.theme==='glow') {
543 cfg.cls = 'btn-glow roo-button';
545 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
547 cfg.cls += ' ' + this.weight;
553 this.cls += ' inverse';
558 cfg.cls += ' active';
562 cfg.disabled = 'disabled';
566 Roo.log('changing to ul' );
568 this.glyphicon = 'caret';
571 cfg.cls += this.size.length ? (' btn-' + this.size) : '';
573 //gsRoo.log(this.parentType);
574 if (this.parentType === 'Navbar' && !this.parent().bar) {
575 Roo.log('changing to li?');
584 href : this.href || '#'
587 cfg.cn[0].html = this.html + ' <span class="caret"></span>';
588 cfg.cls += ' dropdown';
595 cfg.cls += this.parentType === 'Navbar' ? ' navbar-btn' : '';
597 if (this.glyphicon) {
598 cfg.html = ' ' + cfg.html;
603 cls: 'glyphicon glyphicon-' + this.glyphicon
613 // cfg.cls='btn roo-button';
617 var value = cfg.html;
622 cls: 'glyphicon glyphicon-' + this.glyphicon,
641 cfg.cls += ' dropdown';
642 cfg.html = typeof(cfg.html) != 'undefined' ? cfg.html + ' <span class="caret"></span>' : '<span class="caret"></span>';
645 if (cfg.tag !== 'a' && this.href !== '') {
646 throw "Tag must be a to set href.";
647 } else if (this.href.length > 0) {
648 cfg.href = this.href;
651 if(this.removeClass){
656 cfg.target = this.target;
661 initEvents: function() {
662 // Roo.log('init events?');
663 // Roo.log(this.el.dom);
664 if (this.el.hasClass('roo-button')) {
665 this.el.on('click', this.onClick, this);
667 this.el.select('.roo-button').on('click', this.onClick, this);
670 if(this.removeClass){
671 this.el.on('click', this.onClick, this);
674 this.el.enableDisplayMode();
677 onClick : function(e)
683 Roo.log('button on click ');
684 if(this.preventDefault){
687 if (this.pressed === true || this.pressed === false) {
688 this.pressed = !this.pressed;
689 this.el[this.pressed ? 'addClass' : 'removeClass']('active');
690 this.fireEvent('toggle', this, e, this.pressed);
694 this.fireEvent('click', this, e);
698 * Enables this button
702 this.disabled = false;
703 this.el.removeClass('disabled');
707 * Disable this button
711 this.disabled = true;
712 this.el.addClass('disabled');
715 * sets the active state on/off,
716 * @param {Boolean} state (optional) Force a particular state
718 setActive : function(v) {
720 this.el[v ? 'addClass' : 'removeClass']('active');
723 * toggles the current active state
725 toggleActive : function()
727 var active = this.el.hasClass('active');
728 this.setActive(!active);
732 setText : function(str)
734 this.el.select('.roo-button-text',true).first().dom.innerHTML = str;
757 * @class Roo.bootstrap.Column
758 * @extends Roo.bootstrap.Component
759 * Bootstrap Column class
760 * @cfg {Number} xs colspan out of 12 for mobile-sized screens
761 * @cfg {Number} sm colspan out of 12 for tablet-sized screens
762 * @cfg {Number} md colspan out of 12 for computer-sized screens
763 * @cfg {Number} lg colspan out of 12 for large computer-sized screens
764 * @cfg {String} html content of column.
767 * Create a new Column
768 * @param {Object} config The config object
771 Roo.bootstrap.Column = function(config){
772 Roo.bootstrap.Column.superclass.constructor.call(this, config);
775 Roo.extend(Roo.bootstrap.Column, Roo.bootstrap.Component, {
784 getAutoCreate : function(){
785 var cfg = Roo.apply({}, Roo.bootstrap.Column.superclass.getAutoCreate.call(this));
793 ['xs','sm','md','lg'].map(function(size){
794 if (settings[size]) {
795 cfg.cls += ' col-' + size + '-' + settings[size];
798 if (this.html.length) {
799 cfg.html = this.html;
818 * @class Roo.bootstrap.Container
819 * @extends Roo.bootstrap.Component
820 * Bootstrap Container class
821 * @cfg {Boolean} jumbotron is it a jumbotron element
822 * @cfg {String} html content of element
823 * @cfg {String} well (lg|sm|md) a well, large, small or medium.
824 * @cfg {String} panel (primary|success|info|warning|danger) render as a panel.
825 * @cfg {String} header content of header (for panel)
826 * @cfg {String} footer content of footer (for panel)
827 * @cfg {String} sticky (footer|wrap|push) block to use as footer or body- needs css-bootstrap/sticky-footer.css
828 * @cfg {String} tag (header|aside|section) type of HTML tag.
832 * Create a new Container
833 * @param {Object} config The config object
836 Roo.bootstrap.Container = function(config){
837 Roo.bootstrap.Container.superclass.constructor.call(this, config);
840 Roo.extend(Roo.bootstrap.Container, Roo.bootstrap.Component, {
851 getChildContainer : function() {
857 if (this.panel.length) {
858 return this.el.select('.panel-body',true).first();
865 getAutoCreate : function(){
868 tag : this.tag || 'div',
872 if (this.jumbotron) {
873 cfg.cls = 'jumbotron';
875 // - this is applied by the parent..
877 // cfg.cls = this.cls + '';
880 if (this.sticky.length) {
882 var bd = Roo.get(document.body);
883 if (!bd.hasClass('bootstrap-sticky')) {
884 bd.addClass('bootstrap-sticky');
885 Roo.select('html',true).setStyle('height', '100%');
888 cfg.cls += 'bootstrap-sticky-' + this.sticky;
892 if (this.well.length) {
896 cfg.cls +=' well well-' +this.well;
906 if (this.panel.length) {
907 cfg.cls += ' panel panel-' + this.panel;
909 if (this.header.length) {
912 cls : 'panel-heading',
928 if (this.footer.length) {
930 cls : 'panel-footer',
939 body.html = this.html || cfg.html;
941 if ((!this.cls || !this.cls.length) && (!cfg.cls || !cfg.cls.length)) {
942 cfg.cls = 'container';
959 * @class Roo.bootstrap.Img
960 * @extends Roo.bootstrap.Component
961 * Bootstrap Img class
962 * @cfg {Boolean} imgResponsive false | true
963 * @cfg {String} border rounded | circle | thumbnail
964 * @cfg {String} src image source
965 * @cfg {String} alt image alternative text
966 * @cfg {String} href a tag href
967 * @cfg {String} target (_self|_blank|_parent|_top)target for a href.
971 * @param {Object} config The config object
974 Roo.bootstrap.Img = function(config){
975 Roo.bootstrap.Img.superclass.constructor.call(this, config);
981 * The img click event for the img.
982 * @param {Roo.EventObject} e
988 Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component, {
996 getAutoCreate : function(){
1000 cls: (this.imgResponsive) ? 'img-responsive' : '',
1004 cfg.html = this.html || cfg.html;
1006 cfg.src = this.src || cfg.src;
1008 if (['rounded','circle','thumbnail'].indexOf(this.border)>-1) {
1009 cfg.cls += ' img-' + this.border;
1026 a.target = this.target;
1032 return (this.href) ? a : cfg;
1035 initEvents: function() {
1038 this.el.on('click', this.onClick, this);
1042 onClick : function(e)
1044 Roo.log('img onclick');
1045 this.fireEvent('click', this, e);
1059 * @class Roo.bootstrap.Link
1060 * @extends Roo.bootstrap.Component
1061 * Bootstrap Link Class
1062 * @cfg {String} alt image alternative text
1063 * @cfg {String} href a tag href
1064 * @cfg {String} target (_self|_blank|_parent|_top) target for a href.
1065 * @cfg {String} html the content of the link.
1069 * Create a new Input
1070 * @param {Object} config The config object
1073 Roo.bootstrap.Link = function(config){
1074 Roo.bootstrap.Link.superclass.constructor.call(this, config);
1080 * The img click event for the img.
1081 * @param {Roo.EventObject} e
1087 Roo.extend(Roo.bootstrap.Link, Roo.bootstrap.Component, {
1092 getAutoCreate : function(){
1096 html : this.html || 'html-missing'
1103 cfg.href = this.href || '#';
1105 cfg.target = this.target;
1111 initEvents: function() {
1114 this.el.on('click', this.onClick, this);
1118 onClick : function(e)
1120 //Roo.log('img onclick');
1121 this.fireEvent('click', this, e);
1134 * @class Roo.bootstrap.Header
1135 * @extends Roo.bootstrap.Component
1136 * Bootstrap Header class
1137 * @cfg {String} html content of header
1138 * @cfg {Number} level (1|2|3|4|5|6) default 1
1141 * Create a new Header
1142 * @param {Object} config The config object
1146 Roo.bootstrap.Header = function(config){
1147 Roo.bootstrap.Header.superclass.constructor.call(this, config);
1150 Roo.extend(Roo.bootstrap.Header, Roo.bootstrap.Component, {
1158 getAutoCreate : function(){
1161 tag: 'h' + (1 *this.level),
1162 html: this.html || 'fill in html'
1174 * Ext JS Library 1.1.1
1175 * Copyright(c) 2006-2007, Ext JS, LLC.
1177 * Originally Released Under LGPL - original licence link has changed is not relivant.
1180 * <script type="text/javascript">
1184 * @class Roo.bootstrap.MenuMgr
1185 * Provides a common registry of all menu items on a page so that they can be easily accessed by id.
1188 Roo.bootstrap.MenuMgr = function(){
1189 var menus, active, groups = {}, attached = false, lastShow = new Date();
1191 // private - called when first menu is created
1194 active = new Roo.util.MixedCollection();
1195 Roo.get(document).addKeyListener(27, function(){
1196 if(active.length > 0){
1204 if(active && active.length > 0){
1205 var c = active.clone();
1215 if(active.length < 1){
1216 Roo.get(document).un("mouseup", onMouseDown);
1224 var last = active.last();
1225 lastShow = new Date();
1228 Roo.get(document).on("mouseup", onMouseDown);
1233 //m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
1234 m.parentMenu.activeChild = m;
1235 }else if(last && last.isVisible()){
1236 //m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
1241 function onBeforeHide(m){
1243 m.activeChild.hide();
1245 if(m.autoHideTimer){
1246 clearTimeout(m.autoHideTimer);
1247 delete m.autoHideTimer;
1252 function onBeforeShow(m){
1253 var pm = m.parentMenu;
1254 if(!pm && !m.allowOtherMenus){
1256 }else if(pm && pm.activeChild && active != m){
1257 pm.activeChild.hide();
1262 function onMouseDown(e){
1263 Roo.log("on MouseDown");
1264 if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
1272 function onBeforeCheck(mi, state){
1274 var g = groups[mi.group];
1275 for(var i = 0, l = g.length; i < l; i++){
1277 g[i].setChecked(false);
1286 * Hides all menus that are currently visible
1288 hideAll : function(){
1293 register : function(menu){
1297 menus[menu.id] = menu;
1298 menu.on("beforehide", onBeforeHide);
1299 menu.on("hide", onHide);
1300 menu.on("beforeshow", onBeforeShow);
1301 menu.on("show", onShow);
1303 if(g && menu.events["checkchange"]){
1307 groups[g].push(menu);
1308 menu.on("checkchange", onCheck);
1313 * Returns a {@link Roo.menu.Menu} object
1314 * @param {String/Object} menu The string menu id, an existing menu object reference, or a Menu config that will
1315 * be used to generate and return a new Menu instance.
1317 get : function(menu){
1318 if(typeof menu == "string"){ // menu id
1320 }else if(menu.events){ // menu instance
1323 /*else if(typeof menu.length == 'number'){ // array of menu items?
1324 return new Roo.bootstrap.Menu({items:menu});
1325 }else{ // otherwise, must be a config
1326 return new Roo.bootstrap.Menu(menu);
1333 unregister : function(menu){
1334 delete menus[menu.id];
1335 menu.un("beforehide", onBeforeHide);
1336 menu.un("hide", onHide);
1337 menu.un("beforeshow", onBeforeShow);
1338 menu.un("show", onShow);
1340 if(g && menu.events["checkchange"]){
1341 groups[g].remove(menu);
1342 menu.un("checkchange", onCheck);
1347 registerCheckable : function(menuItem){
1348 var g = menuItem.group;
1353 groups[g].push(menuItem);
1354 menuItem.on("beforecheckchange", onBeforeCheck);
1359 unregisterCheckable : function(menuItem){
1360 var g = menuItem.group;
1362 groups[g].remove(menuItem);
1363 menuItem.un("beforecheckchange", onBeforeCheck);
1375 * @class Roo.bootstrap.Menu
1376 * @extends Roo.bootstrap.Component
1377 * Bootstrap Menu class - container for MenuItems
1378 * @cfg {String} type (dropdown|treeview|submenu) type of menu
1382 * @param {Object} config The config object
1386 Roo.bootstrap.Menu = function(config){
1387 Roo.bootstrap.Menu.superclass.constructor.call(this, config);
1388 if (this.registerMenu) {
1389 Roo.bootstrap.MenuMgr.register(this);
1394 * Fires before this menu is displayed
1395 * @param {Roo.menu.Menu} this
1400 * Fires before this menu is hidden
1401 * @param {Roo.menu.Menu} this
1406 * Fires after this menu is displayed
1407 * @param {Roo.menu.Menu} this
1412 * Fires after this menu is hidden
1413 * @param {Roo.menu.Menu} this
1418 * Fires when this menu is clicked (or when the enter key is pressed while it is active)
1419 * @param {Roo.menu.Menu} this
1420 * @param {Roo.menu.Item} menuItem The menu item that was clicked
1421 * @param {Roo.EventObject} e
1426 * Fires when the mouse is hovering over this menu
1427 * @param {Roo.menu.Menu} this
1428 * @param {Roo.EventObject} e
1429 * @param {Roo.menu.Item} menuItem The menu item that was clicked
1434 * Fires when the mouse exits this menu
1435 * @param {Roo.menu.Menu} this
1436 * @param {Roo.EventObject} e
1437 * @param {Roo.menu.Item} menuItem The menu item that was clicked
1442 * Fires when a menu item contained in this menu is clicked
1443 * @param {Roo.menu.BaseItem} baseItem The BaseItem that was clicked
1444 * @param {Roo.EventObject} e
1448 this.menuitems = new Roo.util.MixedCollection(false, function(o) { return o.el.id; });
1451 Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component, {
1455 triggerEl : false, // is this set by component builder? -- it should really be fetched from parent()???
1458 * @cfg {Boolean} registerMenu True (default) - means that clicking on screen etc. hides it.
1460 registerMenu : true,
1462 menuItems :false, // stores the menu items..
1468 getChildContainer : function() {
1472 getAutoCreate : function(){
1474 //if (['right'].indexOf(this.align)!==-1) {
1475 // cfg.cn[1].cls += ' pull-right'
1481 cls : 'dropdown-menu' ,
1482 style : 'z-index:1000'
1486 if (this.type === 'submenu') {
1487 cfg.cls = 'submenu active';
1489 if (this.type === 'treeview') {
1490 cfg.cls = 'treeview-menu';
1495 initEvents : function() {
1497 // Roo.log("ADD event");
1498 // Roo.log(this.triggerEl.dom);
1499 this.triggerEl.on('click', this.onTriggerPress, this);
1500 this.triggerEl.addClass('dropdown-toggle');
1501 this.el.on(Roo.isTouch ? 'touchstart' : 'click' , this.onClick, this);
1503 this.el.on("mouseover", this.onMouseOver, this);
1504 this.el.on("mouseout", this.onMouseOut, this);
1508 findTargetItem : function(e){
1509 var t = e.getTarget(".dropdown-menu-item", this.el, true);
1513 //Roo.log(t); Roo.log(t.id);
1515 //Roo.log(this.menuitems);
1516 return this.menuitems.get(t.id);
1518 //return this.items.get(t.menuItemId);
1523 onClick : function(e){
1524 Roo.log("menu.onClick");
1525 var t = this.findTargetItem(e);
1531 if (Roo.isTouch && e.type == 'touchstart' && t.menu && !t.disabled) {
1532 if(t == this.activeItem && t.shouldDeactivate(e)){
1533 this.activeItem.deactivate();
1534 delete this.activeItem;
1538 this.setActiveItem(t, true);
1545 Roo.log('pass click event');
1549 this.fireEvent("click", this, t, e);
1553 onMouseOver : function(e){
1554 var t = this.findTargetItem(e);
1557 // if(t.canActivate && !t.disabled){
1558 // this.setActiveItem(t, true);
1562 this.fireEvent("mouseover", this, e, t);
1564 isVisible : function(){
1565 return !this.hidden;
1567 onMouseOut : function(e){
1568 var t = this.findTargetItem(e);
1571 // if(t == this.activeItem && t.shouldDeactivate(e)){
1572 // this.activeItem.deactivate();
1573 // delete this.activeItem;
1576 this.fireEvent("mouseout", this, e, t);
1581 * Displays this menu relative to another element
1582 * @param {String/HTMLElement/Roo.Element} element The element to align to
1583 * @param {String} position (optional) The {@link Roo.Element#alignTo} anchor position to use in aligning to
1584 * the element (defaults to this.defaultAlign)
1585 * @param {Roo.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)
1587 show : function(el, pos, parentMenu){
1588 this.parentMenu = parentMenu;
1592 this.fireEvent("beforeshow", this);
1593 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);
1596 * Displays this menu at a specific xy position
1597 * @param {Array} xyPosition Contains X & Y [x, y] values for the position at which to show the menu (coordinates are page-based)
1598 * @param {Roo.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)
1600 showAt : function(xy, parentMenu, /* private: */_e){
1601 this.parentMenu = parentMenu;
1606 this.fireEvent("beforeshow", this);
1608 //xy = this.el.adjustForConstraints(xy);
1610 //this.el.setXY(xy);
1612 this.hideMenuItems();
1613 this.hidden = false;
1614 this.triggerEl.addClass('open');
1616 this.fireEvent("show", this);
1622 this.doFocus.defer(50, this);
1626 doFocus : function(){
1628 this.focusEl.focus();
1633 * Hides this menu and optionally all parent menus
1634 * @param {Boolean} deep (optional) True to hide all parent menus recursively, if any (defaults to false)
1636 hide : function(deep){
1638 this.hideMenuItems();
1639 if(this.el && this.isVisible()){
1640 this.fireEvent("beforehide", this);
1641 if(this.activeItem){
1642 this.activeItem.deactivate();
1643 this.activeItem = null;
1645 this.triggerEl.removeClass('open');;
1647 this.fireEvent("hide", this);
1649 if(deep === true && this.parentMenu){
1650 this.parentMenu.hide(true);
1654 onTriggerPress : function(e)
1657 Roo.log('trigger press');
1658 //Roo.log(e.getTarget());
1659 // Roo.log(this.triggerEl.dom);
1660 if (Roo.get(e.getTarget()).findParent('.dropdown-menu')) {
1663 if (this.isVisible()) {
1667 this.show(this.triggerEl, false, false);
1676 hideMenuItems : function()
1678 //$(backdrop).remove()
1679 Roo.select('.open',true).each(function(aa) {
1681 aa.removeClass('open');
1682 //var parent = getParent($(this))
1683 //var relatedTarget = { relatedTarget: this }
1685 //$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
1686 //if (e.isDefaultPrevented()) return
1687 //$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
1690 addxtypeChild : function (tree, cntr) {
1691 var comp= Roo.bootstrap.Menu.superclass.addxtypeChild.call(this, tree, cntr);
1693 this.menuitems.add(comp);
1714 * @class Roo.bootstrap.MenuItem
1715 * @extends Roo.bootstrap.Component
1716 * Bootstrap MenuItem class
1717 * @cfg {String} html the menu label
1718 * @cfg {String} href the link
1719 * @cfg {Boolean} preventDefault (true | false) default true
1723 * Create a new MenuItem
1724 * @param {Object} config The config object
1728 Roo.bootstrap.MenuItem = function(config){
1729 Roo.bootstrap.MenuItem.superclass.constructor.call(this, config);
1734 * The raw click event for the entire grid.
1735 * @param {Roo.EventObject} e
1741 Roo.extend(Roo.bootstrap.MenuItem, Roo.bootstrap.Component, {
1745 preventDefault: true,
1747 getAutoCreate : function(){
1750 cls: 'dropdown-menu-item',
1759 if (this.parent().type == 'treeview') {
1760 cfg.cls = 'treeview-menu';
1763 cfg.cn[0].href = this.href || cfg.cn[0].href ;
1764 cfg.cn[0].html = this.html || cfg.cn[0].html ;
1768 initEvents: function() {
1770 //this.el.select('a').on('click', this.onClick, this);
1773 onClick : function(e)
1775 Roo.log('item on click ');
1776 //if(this.preventDefault){
1777 // e.preventDefault();
1779 //this.parent().hideMenuItems();
1781 this.fireEvent('click', this, e);
1800 * @class Roo.bootstrap.MenuSeparator
1801 * @extends Roo.bootstrap.Component
1802 * Bootstrap MenuSeparator class
1805 * Create a new MenuItem
1806 * @param {Object} config The config object
1810 Roo.bootstrap.MenuSeparator = function(config){
1811 Roo.bootstrap.MenuSeparator.superclass.constructor.call(this, config);
1814 Roo.extend(Roo.bootstrap.MenuSeparator, Roo.bootstrap.Component, {
1816 getAutoCreate : function(){
1831 <div class="modal fade">
1832 <div class="modal-dialog">
1833 <div class="modal-content">
1834 <div class="modal-header">
1835 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
1836 <h4 class="modal-title">Modal title</h4>
1838 <div class="modal-body">
1839 <p>One fine body…</p>
1841 <div class="modal-footer">
1842 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1843 <button type="button" class="btn btn-primary">Save changes</button>
1845 </div><!-- /.modal-content -->
1846 </div><!-- /.modal-dialog -->
1847 </div><!-- /.modal -->
1857 * @class Roo.bootstrap.Modal
1858 * @extends Roo.bootstrap.Component
1859 * Bootstrap Modal class
1860 * @cfg {String} title Title of dialog
1861 * @cfg {Boolean} specificTitle (true|false) default false
1862 * @cfg {Array} buttons Array of buttons or standard button set..
1863 * @cfg {String} buttonPosition (left|right|center) default right
1866 * Create a new Modal Dialog
1867 * @param {Object} config The config object
1870 Roo.bootstrap.Modal = function(config){
1871 Roo.bootstrap.Modal.superclass.constructor.call(this, config);
1876 * The raw btnclick event for the button
1877 * @param {Roo.EventObject} e
1881 this.buttons = this.buttons || [];
1884 Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component, {
1886 title : 'test dialog',
1893 specificTitle: false,
1895 buttonPosition: 'right',
1897 onRender : function(ct, position)
1899 Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
1902 var cfg = Roo.apply({}, this.getAutoCreate());
1905 // cfg.name = typeof(this.name) == 'undefined' ? this.id : this.name;
1907 //if (!cfg.name.length) {
1911 cfg.cls += ' ' + this.cls;
1914 cfg.style = this.style;
1916 this.el = Roo.get(document.body).createChild(cfg, position);
1918 //var type = this.el.dom.type;
1920 if(this.tabIndex !== undefined){
1921 this.el.dom.setAttribute('tabIndex', this.tabIndex);
1926 this.maskEl = Roo.DomHelper.append(document.body, {tag: "div", cls:"x-dlg-mask"}, true);
1927 this.maskEl.enableDisplayMode("block");
1929 //this.el.addClass("x-dlg-modal");
1931 if (this.buttons.length) {
1932 Roo.each(this.buttons, function(bb) {
1933 b = Roo.apply({}, bb);
1934 b.xns = b.xns || Roo.bootstrap;
1935 b.xtype = b.xtype || 'Button';
1936 if (typeof(b.listeners) == 'undefined') {
1937 b.listeners = { click : this.onButtonClick.createDelegate(this) };
1940 var btn = Roo.factory(b);
1942 btn.onRender(this.el.select('.modal-footer div').first());
1946 // render the children.
1949 if(typeof(this.items) != 'undefined'){
1950 var items = this.items;
1953 for(var i =0;i < items.length;i++) {
1954 nitems.push(this.addxtype(Roo.apply({}, items[i])));
1958 this.items = nitems;
1960 this.body = this.el.select('.modal-body',true).first();
1961 this.close = this.el.select('.modal-header .close', true).first();
1962 this.footer = this.el.select('.modal-footer',true).first();
1964 //this.el.addClass([this.fieldClass, this.cls]);
1967 getAutoCreate : function(){
1972 html : this.html || ''
1977 cls : 'modal-title',
1981 if(this.specificTitle){
1987 style : 'display: none',
1990 cls: "modal-dialog",
1993 cls : "modal-content",
1996 cls : 'modal-header',
2008 cls : 'modal-footer',
2012 cls: 'btn-' + this.buttonPosition
2031 getChildContainer : function() {
2033 return this.el.select('.modal-body',true).first();
2036 getButtonContainer : function() {
2037 return this.el.select('.modal-footer div',true).first();
2040 initEvents : function()
2042 this.el.select('.modal-header .close').on('click', this.hide, this);
2044 // this.addxtype(this);
2048 if (!this.rendered) {
2052 this.el.addClass('on');
2053 this.el.removeClass('fade');
2054 this.el.setStyle('display', 'block');
2055 Roo.get(document.body).addClass("x-body-masked");
2056 this.maskEl.setSize(Roo.lib.Dom.getViewWidth(true), Roo.lib.Dom.getViewHeight(true));
2058 this.el.setStyle('zIndex', '10001');
2059 this.fireEvent('show', this);
2065 Roo.log('Modal hide?!');
2067 Roo.get(document.body).removeClass("x-body-masked");
2068 this.el.removeClass('on');
2069 this.el.addClass('fade');
2070 this.el.setStyle('display', 'none');
2071 this.fireEvent('hide', this);
2074 addButton : function(str, cb)
2078 var b = Roo.apply({}, { html : str } );
2079 b.xns = b.xns || Roo.bootstrap;
2080 b.xtype = b.xtype || 'Button';
2081 if (typeof(b.listeners) == 'undefined') {
2082 b.listeners = { click : cb.createDelegate(this) };
2085 var btn = Roo.factory(b);
2087 btn.onRender(this.el.select('.modal-footer div').first());
2093 setDefaultButton : function(btn)
2095 //this.el.select('.modal-footer').()
2097 resizeTo: function(w,h)
2101 setContentSize : function(w, h)
2105 onButtonClick: function(btn,e)
2108 this.fireEvent('btnclick', btn.name, e);
2110 setTitle: function(str) {
2111 this.el.select('.modal-title',true).first().dom.innerHTML = str;
2117 Roo.apply(Roo.bootstrap.Modal, {
2119 * Button config that displays a single OK button
2128 * Button config that displays Yes and No buttons
2144 * Button config that displays OK and Cancel buttons
2159 * Button config that displays Yes, No and Cancel buttons
2181 * messagebox - can be used as a replace
2185 * @class Roo.MessageBox
2186 * Utility class for generating different styles of message boxes. The alias Roo.Msg can also be used.
2190 Roo.Msg.alert('Status', 'Changes saved successfully.');
2192 // Prompt for user data:
2193 Roo.Msg.prompt('Name', 'Please enter your name:', function(btn, text){
2195 // process text value...
2199 // Show a dialog using config options:
2201 title:'Save Changes?',
2202 msg: 'Your are closing a tab that has unsaved changes. Would you like to save your changes?',
2203 buttons: Roo.Msg.YESNOCANCEL,
2210 Roo.bootstrap.MessageBox = function(){
2211 var dlg, opt, mask, waitTimer;
2212 var bodyEl, msgEl, textboxEl, textareaEl, progressEl, pp;
2213 var buttons, activeTextEl, bwidth;
2217 var handleButton = function(button){
2219 Roo.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value], 1);
2223 var handleHide = function(){
2225 dlg.el.removeClass(opt.cls);
2228 // Roo.TaskMgr.stop(waitTimer);
2229 // waitTimer = null;
2234 var updateButtons = function(b){
2237 buttons["ok"].hide();
2238 buttons["cancel"].hide();
2239 buttons["yes"].hide();
2240 buttons["no"].hide();
2241 //dlg.footer.dom.style.display = 'none';
2244 dlg.footer.dom.style.display = '';
2245 for(var k in buttons){
2246 if(typeof buttons[k] != "function"){
2249 buttons[k].setText(typeof b[k] == "string" ? b[k] : Roo.bootstrap.MessageBox.buttonText[k]);
2250 width += buttons[k].el.getWidth()+15;
2260 var handleEsc = function(d, k, e){
2261 if(opt && opt.closable !== false){
2271 * Returns a reference to the underlying {@link Roo.BasicDialog} element
2272 * @return {Roo.BasicDialog} The BasicDialog element
2274 getDialog : function(){
2276 dlg = new Roo.bootstrap.Modal( {
2279 //constraintoviewport:false,
2281 //collapsible : false,
2286 //buttonAlign:"center",
2287 closeClick : function(){
2288 if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
2291 handleButton("cancel");
2296 dlg.on("hide", handleHide);
2298 //dlg.addKeyListener(27, handleEsc);
2300 this.buttons = buttons;
2301 var bt = this.buttonText;
2302 buttons["ok"] = dlg.addButton(bt["ok"], handleButton.createCallback("ok"));
2303 buttons["yes"] = dlg.addButton(bt["yes"], handleButton.createCallback("yes"));
2304 buttons["no"] = dlg.addButton(bt["no"], handleButton.createCallback("no"));
2305 buttons["cancel"] = dlg.addButton(bt["cancel"], handleButton.createCallback("cancel"));
2307 bodyEl = dlg.body.createChild({
2309 html:'<span class="roo-mb-text"></span><br /><input type="text" class="roo-mb-input" />' +
2310 '<textarea class="roo-mb-textarea"></textarea>' +
2311 '<div class="roo-mb-progress-wrap"><div class="roo-mb-progress"><div class="roo-mb-progress-bar"> </div></div></div>'
2313 msgEl = bodyEl.dom.firstChild;
2314 textboxEl = Roo.get(bodyEl.dom.childNodes[2]);
2315 textboxEl.enableDisplayMode();
2316 textboxEl.addKeyListener([10,13], function(){
2317 if(dlg.isVisible() && opt && opt.buttons){
2320 }else if(opt.buttons.yes){
2321 handleButton("yes");
2325 textareaEl = Roo.get(bodyEl.dom.childNodes[3]);
2326 textareaEl.enableDisplayMode();
2327 progressEl = Roo.get(bodyEl.dom.childNodes[4]);
2328 progressEl.enableDisplayMode();
2329 var pf = progressEl.dom.firstChild;
2331 pp = Roo.get(pf.firstChild);
2332 pp.setHeight(pf.offsetHeight);
2340 * Updates the message box body text
2341 * @param {String} text (optional) Replaces the message box element's innerHTML with the specified string (defaults to
2342 * the XHTML-compliant non-breaking space character '&#160;')
2343 * @return {Roo.MessageBox} This message box
2345 updateText : function(text){
2346 if(!dlg.isVisible() && !opt.width){
2347 dlg.resizeTo(this.maxWidth, 100); // resize first so content is never clipped from previous shows
2349 msgEl.innerHTML = text || ' ';
2351 var cw = Math.max(msgEl.offsetWidth, msgEl.parentNode.scrollWidth);
2352 //Roo.log("guesed size: " + JSON.stringify([cw,msgEl.offsetWidth, msgEl.parentNode.scrollWidth]));
2354 Math.min(opt.width || cw , this.maxWidth),
2355 Math.max(opt.minWidth || this.minWidth, bwidth)
2358 activeTextEl.setWidth(w);
2360 if(dlg.isVisible()){
2361 dlg.fixedcenter = false;
2363 // to big, make it scroll. = But as usual stupid IE does not support
2366 if ( bodyEl.getHeight() > (Roo.lib.Dom.getViewHeight() - 100)) {
2367 bodyEl.setHeight ( Roo.lib.Dom.getViewHeight() - 100 );
2368 bodyEl.dom.style.overflowY = 'auto' + ( Roo.isIE ? '' : ' !important');
2370 bodyEl.dom.style.height = '';
2371 bodyEl.dom.style.overflowY = '';
2374 bodyEl.dom.style.get = 'auto' + ( Roo.isIE ? '' : ' !important');
2376 bodyEl.dom.style.overflowX = '';
2379 dlg.setContentSize(w, bodyEl.getHeight());
2380 if(dlg.isVisible()){
2381 dlg.fixedcenter = true;
2387 * Updates a progress-style message box's text and progress bar. Only relevant on message boxes
2388 * initiated via {@link Roo.MessageBox#progress} or by calling {@link Roo.MessageBox#show} with progress: true.
2389 * @param {Number} value Any number between 0 and 1 (e.g., .5)
2390 * @param {String} text (optional) If defined, the message box's body text is replaced with the specified string (defaults to undefined)
2391 * @return {Roo.MessageBox} This message box
2393 updateProgress : function(value, text){
2395 this.updateText(text);
2397 if (pp) { // weird bug on my firefox - for some reason this is not defined
2398 pp.setWidth(Math.floor(value*progressEl.dom.firstChild.offsetWidth));
2404 * Returns true if the message box is currently displayed
2405 * @return {Boolean} True if the message box is visible, else false
2407 isVisible : function(){
2408 return dlg && dlg.isVisible();
2412 * Hides the message box if it is displayed
2415 if(this.isVisible()){
2421 * Displays a new message box, or reinitializes an existing message box, based on the config options
2422 * passed in. All functions (e.g. prompt, alert, etc) on MessageBox call this function internally.
2423 * The following config object properties are supported:
2425 Property Type Description
2426 ---------- --------------- ------------------------------------------------------------------------------------
2427 animEl String/Element An id or Element from which the message box should animate as it opens and
2428 closes (defaults to undefined)
2429 buttons Object/Boolean A button config object (e.g., Roo.MessageBox.OKCANCEL or {ok:'Foo',
2430 cancel:'Bar'}), or false to not show any buttons (defaults to false)
2431 closable Boolean False to hide the top-right close button (defaults to true). Note that
2432 progress and wait dialogs will ignore this property and always hide the
2433 close button as they can only be closed programmatically.
2434 cls String A custom CSS class to apply to the message box element
2435 defaultTextHeight Number The default height in pixels of the message box's multiline textarea if
2436 displayed (defaults to 75)
2437 fn Function A callback function to execute after closing the dialog. The arguments to the
2438 function will be btn (the name of the button that was clicked, if applicable,
2439 e.g. "ok"), and text (the value of the active text field, if applicable).
2440 Progress and wait dialogs will ignore this option since they do not respond to
2441 user actions and can only be closed programmatically, so any required function
2442 should be called by the same code after it closes the dialog.
2443 icon String A CSS class that provides a background image to be used as an icon for
2444 the dialog (e.g., Roo.MessageBox.WARNING or 'custom-class', defaults to '')
2445 maxWidth Number The maximum width in pixels of the message box (defaults to 600)
2446 minWidth Number The minimum width in pixels of the message box (defaults to 100)
2447 modal Boolean False to allow user interaction with the page while the message box is
2448 displayed (defaults to true)
2449 msg String A string that will replace the existing message box body text (defaults
2450 to the XHTML-compliant non-breaking space character ' ')
2451 multiline Boolean True to prompt the user to enter multi-line text (defaults to false)
2452 progress Boolean True to display a progress bar (defaults to false)
2453 progressText String The text to display inside the progress bar if progress = true (defaults to '')
2454 prompt Boolean True to prompt the user to enter single-line text (defaults to false)
2455 proxyDrag Boolean True to display a lightweight proxy while dragging (defaults to false)
2456 title String The title text
2457 value String The string value to set into the active textbox element if displayed
2458 wait Boolean True to display a progress bar (defaults to false)
2459 width Number The width of the dialog in pixels
2466 msg: 'Please enter your address:',
2468 buttons: Roo.MessageBox.OKCANCEL,
2471 animEl: 'addAddressBtn'
2474 * @param {Object} config Configuration options
2475 * @return {Roo.MessageBox} This message box
2477 show : function(options)
2480 // this causes nightmares if you show one dialog after another
2481 // especially on callbacks..
2483 if(this.isVisible()){
2486 Roo.log("[Roo.Messagebox] Show called while message displayed:" );
2487 Roo.log("Old Dialog Message:" + msgEl.innerHTML );
2488 Roo.log("New Dialog Message:" + options.msg )
2489 //this.alert("ERROR", "Multiple dialogs where displayed at the same time");
2490 //throw "Roo.MessageBox ERROR : Multiple dialogs where displayed at the same time";
2493 var d = this.getDialog();
2495 d.setTitle(opt.title || " ");
2496 d.close.setDisplayed(opt.closable !== false);
2497 activeTextEl = textboxEl;
2498 opt.prompt = opt.prompt || (opt.multiline ? true : false);
2503 textareaEl.setHeight(typeof opt.multiline == "number" ?
2504 opt.multiline : this.defaultTextHeight);
2505 activeTextEl = textareaEl;
2514 progressEl.setDisplayed(opt.progress === true);
2515 this.updateProgress(0);
2516 activeTextEl.dom.value = opt.value || "";
2518 dlg.setDefaultButton(activeTextEl);
2520 var bs = opt.buttons;
2524 }else if(bs && bs.yes){
2525 db = buttons["yes"];
2527 dlg.setDefaultButton(db);
2529 bwidth = updateButtons(opt.buttons);
2530 this.updateText(opt.msg);
2532 d.el.addClass(opt.cls);
2534 d.proxyDrag = opt.proxyDrag === true;
2535 d.modal = opt.modal !== false;
2536 d.mask = opt.modal !== false ? mask : false;
2538 // force it to the end of the z-index stack so it gets a cursor in FF
2539 document.body.appendChild(dlg.el.dom);
2540 d.animateTarget = null;
2541 d.show(options.animEl);
2547 * Displays a message box with a progress bar. This message box has no buttons and is not closeable by
2548 * the user. You are responsible for updating the progress bar as needed via {@link Roo.MessageBox#updateProgress}
2549 * and closing the message box when the process is complete.
2550 * @param {String} title The title bar text
2551 * @param {String} msg The message box body text
2552 * @return {Roo.MessageBox} This message box
2554 progress : function(title, msg){
2561 minWidth: this.minProgressWidth,
2568 * Displays a standard read-only message box with an OK button (comparable to the basic JavaScript Window.alert).
2569 * If a callback function is passed it will be called after the user clicks the button, and the
2570 * id of the button that was clicked will be passed as the only parameter to the callback
2571 * (could also be the top-right close button).
2572 * @param {String} title The title bar text
2573 * @param {String} msg The message box body text
2574 * @param {Function} fn (optional) The callback function invoked after the message box is closed
2575 * @param {Object} scope (optional) The scope of the callback function
2576 * @return {Roo.MessageBox} This message box
2578 alert : function(title, msg, fn, scope){
2591 * Displays a message box with an infinitely auto-updating progress bar. This can be used to block user
2592 * interaction while waiting for a long-running process to complete that does not have defined intervals.
2593 * You are responsible for closing the message box when the process is complete.
2594 * @param {String} msg The message box body text
2595 * @param {String} title (optional) The title bar text
2596 * @return {Roo.MessageBox} This message box
2598 wait : function(msg, title){
2609 waitTimer = Roo.TaskMgr.start({
2611 Roo.MessageBox.updateProgress(((((i+20)%20)+1)*5)*.01);
2619 * Displays a confirmation message box with Yes and No buttons (comparable to JavaScript's Window.confirm).
2620 * If a callback function is passed it will be called after the user clicks either button, and the id of the
2621 * button that was clicked will be passed as the only parameter to the callback (could also be the top-right close button).
2622 * @param {String} title The title bar text
2623 * @param {String} msg The message box body text
2624 * @param {Function} fn (optional) The callback function invoked after the message box is closed
2625 * @param {Object} scope (optional) The scope of the callback function
2626 * @return {Roo.MessageBox} This message box
2628 confirm : function(title, msg, fn, scope){
2632 buttons: this.YESNO,
2641 * Displays a message box with OK and Cancel buttons prompting the user to enter some text (comparable to
2642 * JavaScript's Window.prompt). The prompt can be a single-line or multi-line textbox. If a callback function
2643 * is passed it will be called after the user clicks either button, and the id of the button that was clicked
2644 * (could also be the top-right close button) and the text that was entered will be passed as the two
2645 * parameters to the callback.
2646 * @param {String} title The title bar text
2647 * @param {String} msg The message box body text
2648 * @param {Function} fn (optional) The callback function invoked after the message box is closed
2649 * @param {Object} scope (optional) The scope of the callback function
2650 * @param {Boolean/Number} multiline (optional) True to create a multiline textbox using the defaultTextHeight
2651 * property, or the height in pixels to create the textbox (defaults to false / single-line)
2652 * @return {Roo.MessageBox} This message box
2654 prompt : function(title, msg, fn, scope, multiline){
2658 buttons: this.OKCANCEL,
2663 multiline: multiline,
2670 * Button config that displays a single OK button
2675 * Button config that displays Yes and No buttons
2678 YESNO : {yes:true, no:true},
2680 * Button config that displays OK and Cancel buttons
2683 OKCANCEL : {ok:true, cancel:true},
2685 * Button config that displays Yes, No and Cancel buttons
2688 YESNOCANCEL : {yes:true, no:true, cancel:true},
2691 * The default height in pixels of the message box's multiline textarea if displayed (defaults to 75)
2694 defaultTextHeight : 75,
2696 * The maximum width in pixels of the message box (defaults to 600)
2701 * The minimum width in pixels of the message box (defaults to 100)
2706 * The minimum width in pixels of the message box if it is a progress-style dialog. This is useful
2707 * for setting a different minimum width than text-only dialogs may need (defaults to 250)
2710 minProgressWidth : 250,
2712 * An object containing the default button text strings that can be overriden for localized language support.
2713 * Supported properties are: ok, cancel, yes and no.
2714 * Customize the default text like so: Roo.MessageBox.buttonText.yes = "S?";
2727 * Shorthand for {@link Roo.MessageBox}
2729 Roo.MessageBox = Roo.MessageBox || Roo.bootstrap.MessageBox
2730 Roo.Msg = Roo.Msg || Roo.MessageBox;
2739 * @class Roo.bootstrap.Navbar
2740 * @extends Roo.bootstrap.Component
2741 * Bootstrap Navbar class
2744 * Create a new Navbar
2745 * @param {Object} config The config object
2749 Roo.bootstrap.Navbar = function(config){
2750 Roo.bootstrap.Navbar.superclass.constructor.call(this, config);
2754 Roo.extend(Roo.bootstrap.Navbar, Roo.bootstrap.Component, {
2763 getAutoCreate : function(){
2766 throw { message : "nav bar is now a abstract base class - use NavSimplebar / NavHeaderbar / NavSidebar etc..."};
2770 initEvents :function ()
2772 //Roo.log(this.el.select('.navbar-toggle',true));
2773 this.el.select('.navbar-toggle',true).on('click', function() {
2774 // Roo.log('click');
2775 this.el.select('.navbar-collapse',true).toggleClass('in');
2783 this.maskEl = Roo.DomHelper.append(this.el, mark, true);
2785 var size = this.el.getSize();
2786 this.maskEl.setSize(size.width, size.height);
2787 this.maskEl.enableDisplayMode("block");
2796 getChildContainer : function()
2798 if (this.el.select('.collapse').getCount()) {
2799 return this.el.select('.collapse',true).first();
2831 * @class Roo.bootstrap.NavSimplebar
2832 * @extends Roo.bootstrap.Navbar
2833 * Bootstrap Sidebar class
2835 * @cfg {Boolean} inverse is inverted color
2837 * @cfg {String} type (nav | pills | tabs)
2838 * @cfg {Boolean} arrangement stacked | justified
2839 * @cfg {String} align (left | right) alignment
2841 * @cfg {Boolean} main (true|false) main nav bar? default false
2842 * @cfg {Boolean} loadMask (true|false) loadMask on the bar
2844 * @cfg {String} tag (header|footer|nav|div) default is nav
2850 * Create a new Sidebar
2851 * @param {Object} config The config object
2855 Roo.bootstrap.NavSimplebar = function(config){
2856 Roo.bootstrap.NavSimplebar.superclass.constructor.call(this, config);
2859 Roo.extend(Roo.bootstrap.NavSimplebar, Roo.bootstrap.Navbar, {
2875 getAutoCreate : function(){
2879 tag : this.tag || 'div',
2892 this.type = this.type || 'nav';
2893 if (['tabs','pills'].indexOf(this.type)!==-1) {
2894 cfg.cn[0].cls += ' nav-' + this.type
2898 if (this.type!=='nav') {
2899 Roo.log('nav type must be nav/tabs/pills')
2901 cfg.cn[0].cls += ' navbar-nav'
2907 if (['stacked','justified'].indexOf(this.arrangement)!==-1) {
2908 cfg.cn[0].cls += ' nav-' + this.arrangement;
2912 if (this.align === 'right') {
2913 cfg.cn[0].cls += ' navbar-right';
2917 cfg.cls += ' navbar-inverse';
2944 * @class Roo.bootstrap.NavHeaderbar
2945 * @extends Roo.bootstrap.NavSimplebar
2946 * Bootstrap Sidebar class
2948 * @cfg {String} brand what is brand
2949 * @cfg {String} position (fixed-top|fixed-bottom|static-top) position
2950 * @cfg {String} brand_href href of the brand
2953 * Create a new Sidebar
2954 * @param {Object} config The config object
2958 Roo.bootstrap.NavHeaderbar = function(config){
2959 Roo.bootstrap.NavHeaderbar.superclass.constructor.call(this, config);
2962 Roo.extend(Roo.bootstrap.NavHeaderbar, Roo.bootstrap.NavSimplebar, {
2969 getAutoCreate : function(){
2974 tag: this.nav || 'nav',
2980 cls: 'navbar-header',
2985 cls: 'navbar-toggle',
2986 'data-toggle': 'collapse',
2991 html: 'Toggle navigation'
3011 cls: 'collapse navbar-collapse'
3016 cfg.cls += this.inverse ? ' navbar-inverse' : ' navbar-default';
3018 if (['fixed-top','fixed-bottom','static-top'].indexOf(this.position)>-1) {
3019 cfg.cls += ' navbar-' + this.position;
3021 // tag can override this..
3023 cfg.tag = this.tag || (this.position == 'fixed-bottom' ? 'footer' : 'header');
3026 if (this.brand !== '') {
3029 href: this.brand_href ? this.brand_href : '#',
3030 cls: 'navbar-brand',
3038 cfg.cls += ' main-nav';
3063 * @class Roo.bootstrap.NavSidebar
3064 * @extends Roo.bootstrap.Navbar
3065 * Bootstrap Sidebar class
3068 * Create a new Sidebar
3069 * @param {Object} config The config object
3073 Roo.bootstrap.NavSidebar = function(config){
3074 Roo.bootstrap.NavSidebar.superclass.constructor.call(this, config);
3077 Roo.extend(Roo.bootstrap.NavSidebar, Roo.bootstrap.Navbar, {
3079 sidebar : true, // used by Navbar Item and NavbarGroup at present...
3081 getAutoCreate : function(){
3086 cls: 'sidebar sidebar-nav'
3108 * @class Roo.bootstrap.NavGroup
3109 * @extends Roo.bootstrap.Component
3110 * Bootstrap NavGroup class
3111 * @cfg {String} align left | right
3112 * @cfg {Boolean} inverse false | true
3113 * @cfg {String} type (nav|pills|tab) default nav
3114 * @cfg {String} navId - reference Id for navbar.
3118 * Create a new nav group
3119 * @param {Object} config The config object
3122 Roo.bootstrap.NavGroup = function(config){
3123 Roo.bootstrap.NavGroup.superclass.constructor.call(this, config);
3125 Roo.bootstrap.NavGroup.register(this);
3129 * Fires when the active item changes
3130 * @param {Roo.bootstrap.NavGroup} this
3131 * @param {Roo.bootstrap.Navbar.Item} item The item selected
3132 * @param {Roo.bootstrap.Navbar.Item} item The previously selected item
3139 Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component, {
3150 getAutoCreate : function()
3152 var cfg = Roo.apply({}, Roo.bootstrap.NavGroup.superclass.getAutoCreate.call(this));
3159 if (['tabs','pills'].indexOf(this.type)!==-1) {
3160 cfg.cls += ' nav-' + this.type
3162 if (this.type!=='nav') {
3163 Roo.log('nav type must be nav/tabs/pills')
3165 cfg.cls += ' navbar-nav'
3168 if (this.parent().sidebar) {
3171 cls: 'dashboard-menu sidebar-menu'
3177 if (this.form === true) {
3183 if (this.align === 'right') {
3184 cfg.cls += ' navbar-right';
3186 cfg.cls += ' navbar-left';
3190 if (this.align === 'right') {
3191 cfg.cls += ' navbar-right';
3195 cfg.cls += ' navbar-inverse';
3203 setActiveItem : function(item)
3206 Roo.each(this.navItems, function(v){
3211 v.setActive(false, true);
3218 item.setActive(true, true);
3219 this.fireEvent('changed', this, item, prev);
3225 register : function(item)
3227 this.navItems.push( item);
3228 item.navId = this.navId;
3231 getNavItem: function(tabId)
3234 Roo.each(this.navItems, function(e) {
3235 if (e.tabId == tabId) {
3247 Roo.apply(Roo.bootstrap.NavGroup, {
3251 register : function(navgrp)
3253 this.groups[navgrp.navId] = navgrp;
3256 get: function(navId) {
3257 return this.groups[navId];
3272 * @class Roo.bootstrap.Navbar.Item
3273 * @extends Roo.bootstrap.Component
3274 * Bootstrap Navbar.Button class
3275 * @cfg {String} href link to
3276 * @cfg {String} html content of button
3277 * @cfg {String} badge text inside badge
3278 * @cfg {String} glyphicon name of glyphicon
3279 * @cfg {String} icon name of font awesome icon
3280 * @cfg {Boolean} active Is item active
3281 * @cfg {Boolean} preventDefault (true | false) default false
3282 * @cfg {String} tabId the tab that this item activates.
3285 * Create a new Navbar Button
3286 * @param {Object} config The config object
3288 Roo.bootstrap.Navbar.Item = function(config){
3289 Roo.bootstrap.Navbar.Item.superclass.constructor.call(this, config);
3294 * The raw click event for the entire grid.
3295 * @param {Roo.EventObject} e
3300 * Fires when the active item active state changes
3301 * @param {Roo.bootstrap.Navbar.Item} this
3302 * @param {boolean} state the new state
3310 Roo.extend(Roo.bootstrap.Navbar.Item, Roo.bootstrap.Component, {
3318 preventDefault : false,
3321 getAutoCreate : function(){
3323 var cfg = Roo.apply({}, Roo.bootstrap.Navbar.Item.superclass.getAutoCreate.call(this));
3325 if (this.parent().parent().sidebar === true) {
3338 cfg.cn[0].html = this.html;
3342 this.cls += ' active';
3346 cfg.cn[0].cls += ' dropdown-toggle';
3347 cfg.cn[0].html = (cfg.cn[0].html || this.html) + '<span class="glyphicon glyphicon-chevron-down"></span>';
3351 cfg.cn[0].tag = 'a',
3352 cfg.cn[0].href = this.href;
3355 if (this.glyphicon) {
3356 cfg.cn[0].html = '<i class="glyphicon glyphicon-'+this.glyphicon+'"></i><span>' + cfg.cn[0].html || this.html + '</span>'
3360 cfg.cn[0].html = '<i class="'+this.icon+'"></i><span>' + cfg.cn[0].html || this.html + '</span>'
3372 cfg.cls = typeof(cfg.cls) == 'undefined' ? 'active' : cfg.cls + ' active';
3382 if (this.glyphicon) {
3383 if(cfg.html){cfg.html = ' ' + this.html};
3387 cls: 'glyphicon glyphicon-' + this.glyphicon
3392 cfg.cn[0].html = this.html || cfg.cn[0].html ;
3397 cfg.cn[0].html += " <span class='caret'></span>";
3398 //}else if (!this.href) {
3399 // cfg.cn[0].tag='p';
3400 // cfg.cn[0].cls='navbar-text';
3403 cfg.cn[0].href=this.href||'#';
3404 cfg.cn[0].html=this.html;
3407 if (this.badge !== '') {
3410 cfg.cn[0].html + ' ',
3421 cfg.cn[0].html = '<i class="'+this.icon+'"></i><span>' + cfg.cn[0].html || this.html + '</span>'
3426 initEvents: function() {
3427 // Roo.log('init events?');
3428 // Roo.log(this.el.dom);
3429 this.el.select('a',true).on('click', this.onClick, this);
3430 // at this point parent should be available..
3431 this.parent().register(this);
3434 onClick : function(e)
3436 if(this.preventDefault){
3440 if(this.fireEvent('click', this, e) === false){
3444 if (['tabs','pills'].indexOf(this.parent().type)!==-1) {
3445 if (typeof(this.parent().setActiveItem) !== 'undefined') {
3446 this.parent().setActiveItem(this);
3454 isActive: function () {
3457 setActive : function(state, fire)
3459 this.active = state;
3461 this.el.removeClass('active');
3462 } else if (!this.el.hasClass('active')) {
3463 this.el.addClass('active');
3466 this.fireEvent('changed', this, state);
3471 // this should not be here...
3484 * @class Roo.bootstrap.NavItem
3485 * @extends Roo.bootstrap.Component
3486 * Bootstrap Navbar.NavItem class
3487 * @cfg {String} href link to
3488 * @cfg {String} html content of button
3489 * @cfg {String} badge text inside badge
3490 * @cfg {String} badgecls (bg-green|bg-red|bg-yellow)the extra classes for the badge
3491 * @cfg {String} glyphicon name of glyphicon
3492 * @cfg {String} icon name of font awesome icon
3493 * @cfg {Boolean} active Is item active
3494 * @cfg {Boolean} preventDefault (true | false) default false
3495 * @cfg {String} tabId the tab that this item activates.
3498 * Create a new Navbar Item
3499 * @param {Object} config The config object
3501 Roo.bootstrap.NavItem = function(config){
3502 Roo.bootstrap.NavItem.superclass.constructor.call(this, config);
3507 * The raw click event for the entire grid.
3508 * @param {Roo.EventObject} e
3513 * Fires when the active item active state changes
3514 * @param {Roo.bootstrap.NavItem} this
3515 * @param {boolean} state the new state
3523 Roo.extend(Roo.bootstrap.NavItem, Roo.bootstrap.Component, {
3531 preventDefault : false,
3534 getAutoCreate : function(){
3542 href : this.href || "#",
3543 html: this.html || ''
3549 cfg.cls = typeof(cfg.cls) == 'undefined' ? 'active' : cfg.cls + ' active';
3552 // glyphicon and icon go before content..
3553 if (this.glyphicon || this.icon) {
3555 cfg.cn[0].html = '<i class="'+this.icon+'"></i><span>' + cfg.cn[0].html + '</span>'
3557 cfg.cn[0].html = '<span class="glyphicon glyphicon-' + this.glyphicon + '"></span>' + cfg.cn[0].html;
3565 cfg.cn[0].html += " <span class='caret'></span>";
3569 if (this.badge !== '') {
3571 cfg.cn[0].html += ' <span class="badge">' + this.badge + '</span>';
3578 initEvents: function() {
3579 // Roo.log('init events?');
3580 // Roo.log(this.el.dom);
3581 this.el.select('a',true).on('click', this.onClick, this);
3582 // at this point parent should be available..
3583 this.parent().register(this);
3586 onClick : function(e)
3588 if(this.preventDefault){
3592 if(this.fireEvent('click', this, e) === false){
3596 if (['tabs','pills'].indexOf(this.parent().type)!==-1) {
3597 if (typeof(this.parent().setActiveItem) !== 'undefined') {
3598 this.parent().setActiveItem(this);
3606 isActive: function () {
3609 setActive : function(state, fire)
3611 this.active = state;
3613 this.el.removeClass('active');
3614 } else if (!this.el.hasClass('active')) {
3615 this.el.addClass('active');
3618 this.fireEvent('changed', this, state);
3623 // this should not be here...
3634 * <span> icon </span>
3635 * <span> text </span>
3636 * <span>badge </span>
3640 * @class Roo.bootstrap.NavSidebarItem
3641 * @extends Roo.bootstrap.Component
3642 * Bootstrap Navbar.NavSidebarItem class
3644 * Create a new Navbar Button
3645 * @param {Object} config The config object
3647 Roo.bootstrap.NavSidebarItem = function(config){
3648 Roo.bootstrap.NavSidebarItem.superclass.constructor.call(this, config);
3653 * The raw click event for the entire grid.
3654 * @param {Roo.EventObject} e
3659 * Fires when the active item active state changes
3660 * @param {Roo.bootstrap.Navbar.Item} this
3661 * @param {boolean} state the new state
3669 Roo.extend(Roo.bootstrap.NavSidebarItem, Roo.bootstrap.NavItem, {
3672 getAutoCreate : function(){
3677 href : this.href || '#',
3689 html : this.html || ''
3694 cfg.cls += ' active';
3698 if (this.glyphicon || this.icon) {
3699 var c = this.glyphicon ? ('glyphicon glyphicon-'+this.glyphicon) : this.icon;
3700 a.cn.push({ tag : 'i', cls : c }) ;
3705 if (this.badge !== '') {
3706 a.cn.push({ tag: 'span', cls : 'badge pull-right ' + (this.badgecls || ''), html: this.badge });
3710 a.cn.push({ tag : 'i', cls : 'glyphicon glyphicon-chevron-down pull-right'});
3711 a.cls += 'dropdown-toggle treeview' ;
3735 * @class Roo.bootstrap.Row
3736 * @extends Roo.bootstrap.Component
3737 * Bootstrap Row class (contains columns...)
3741 * @param {Object} config The config object
3744 Roo.bootstrap.Row = function(config){
3745 Roo.bootstrap.Row.superclass.constructor.call(this, config);
3748 Roo.extend(Roo.bootstrap.Row, Roo.bootstrap.Component, {
3750 getAutoCreate : function(){
3769 * @class Roo.bootstrap.Element
3770 * @extends Roo.bootstrap.Component
3771 * Bootstrap Element class
3772 * @cfg {String} html contents of the element
3773 * @cfg {String} tag tag of the element
3774 * @cfg {String} cls class of the element
3777 * Create a new Element
3778 * @param {Object} config The config object
3781 Roo.bootstrap.Element = function(config){
3782 Roo.bootstrap.Element.superclass.constructor.call(this, config);
3785 Roo.extend(Roo.bootstrap.Element, Roo.bootstrap.Component, {
3792 getAutoCreate : function(){
3817 * @class Roo.bootstrap.Pagination
3818 * @extends Roo.bootstrap.Component
3819 * Bootstrap Pagination class
3820 * @cfg {String} size xs | sm | md | lg
3821 * @cfg {Boolean} inverse false | true
3824 * Create a new Pagination
3825 * @param {Object} config The config object
3828 Roo.bootstrap.Pagination = function(config){
3829 Roo.bootstrap.Pagination.superclass.constructor.call(this, config);
3832 Roo.extend(Roo.bootstrap.Pagination, Roo.bootstrap.Component, {
3838 getAutoCreate : function(){
3844 cfg.cls += ' inverse';
3850 cfg.cls += " " + this.cls;
3868 * @class Roo.bootstrap.PaginationItem
3869 * @extends Roo.bootstrap.Component
3870 * Bootstrap PaginationItem class
3871 * @cfg {String} html text
3872 * @cfg {String} href the link
3873 * @cfg {Boolean} preventDefault (true | false) default true
3874 * @cfg {Boolean} active (true | false) default false
3878 * Create a new PaginationItem
3879 * @param {Object} config The config object
3883 Roo.bootstrap.PaginationItem = function(config){
3884 Roo.bootstrap.PaginationItem.superclass.constructor.call(this, config);
3889 * The raw click event for the entire grid.
3890 * @param {Roo.EventObject} e
3896 Roo.extend(Roo.bootstrap.PaginationItem, Roo.bootstrap.Component, {
3900 preventDefault: true,
3904 getAutoCreate : function(){
3910 href : this.href ? this.href : '#',
3911 html : this.html ? this.html : ''
3921 cfg.cls = typeof(cfg.cls) !== 'undefined' ? cfg.cls + ' active' : 'active';
3927 initEvents: function() {
3929 this.el.on('click', this.onClick, this);
3932 onClick : function(e)
3934 Roo.log('PaginationItem on click ');
3935 if(this.preventDefault){
3939 this.fireEvent('click', this, e);
3955 * @class Roo.bootstrap.Slider
3956 * @extends Roo.bootstrap.Component
3957 * Bootstrap Slider class
3960 * Create a new Slider
3961 * @param {Object} config The config object
3964 Roo.bootstrap.Slider = function(config){
3965 Roo.bootstrap.Slider.superclass.constructor.call(this, config);
3968 Roo.extend(Roo.bootstrap.Slider, Roo.bootstrap.Component, {
3970 getAutoCreate : function(){
3974 cls: 'slider slider-sample1 vertical-handler ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all',
3978 cls: 'ui-slider-handle ui-state-default ui-corner-all'
3996 * @class Roo.bootstrap.Table
3997 * @extends Roo.bootstrap.Component
3998 * Bootstrap Table class
3999 * @cfg {String} cls table class
4000 * @cfg {String} align (left|center|right) Specifies the alignment of a table according to surrounding text
4001 * @cfg {String} bgcolor Specifies the background color for a table
4002 * @cfg {Number} border Specifies whether the table cells should have borders or not
4003 * @cfg {Number} cellpadding Specifies the space between the cell wall and the cell content
4004 * @cfg {Number} cellspacing Specifies the space between cells
4005 * @cfg {String} frame Specifies which parts of the outside borders that should be visible
4006 * @cfg {String} rules Specifies which parts of the inside borders that should be visible
4007 * @cfg {String} sortable Specifies that the table should be sortable
4008 * @cfg {String} summary Specifies a summary of the content of a table
4009 * @cfg {Number} width Specifies the width of a table
4011 * @cfg {boolean} striped Should the rows be alternative striped
4012 * @cfg {boolean} bordered Add borders to the table
4013 * @cfg {boolean} hover Add hover highlighting
4014 * @cfg {boolean} condensed Format condensed
4015 * @cfg {boolean} responsive Format condensed
4021 * Create a new Table
4022 * @param {Object} config The config object
4025 Roo.bootstrap.Table = function(config){
4026 Roo.bootstrap.Table.superclass.constructor.call(this, config);
4029 this.selModel = Roo.factory(this.sm, Roo.bootstrap.Table);
4030 this.sm = this.selModel;
4031 this.sm.xmodule = this.xmodule || false;
4033 if (this.cm && typeof(this.cm.config) == 'undefined') {
4034 this.colModel = new Roo.bootstrap.Table.ColumnModel(this.cm);
4035 this.cm = this.colModel;
4036 this.cm.xmodule = this.xmodule || false;
4039 this.store= Roo.factory(this.store, Roo.data);
4040 this.ds = this.store;
4041 this.ds.xmodule = this.xmodule || false;
4046 Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component, {
4068 getAutoCreate : function(){
4069 var cfg = Roo.apply({}, Roo.bootstrap.Table.superclass.getAutoCreate.call(this));
4078 cfg.cls += ' table-striped';
4081 cfg.cls += ' table-hover';
4083 if (this.bordered) {
4084 cfg.cls += ' table-bordered';
4086 if (this.condensed) {
4087 cfg.cls += ' table-condensed';
4089 if (this.responsive) {
4090 cfg.cls += ' table-responsive';
4097 cfg.cls+= ' ' +this.cls;
4100 // this lot should be simplifed...
4103 cfg.align=this.align;
4106 cfg.bgcolor=this.bgcolor;
4109 cfg.border=this.border;
4111 if (this.cellpadding) {
4112 cfg.cellpadding=this.cellpadding;
4114 if (this.cellspacing) {
4115 cfg.cellspacing=this.cellspacing;
4118 cfg.frame=this.frame;
4121 cfg.rules=this.rules;
4123 if (this.sortable) {
4124 cfg.sortable=this.sortable;
4127 cfg.summary=this.summary;
4130 cfg.width=this.width;
4133 if(this.store || this.cm){
4134 cfg.cn.push(this.renderHeader());
4135 cfg.cn.push(this.renderBody());
4136 cfg.cn.push(this.renderFooter());
4138 cfg.cls+= ' TableGrid';
4144 // initTableGrid : function()
4153 // var cm = this.cm;
4155 // for(var i = 0, len = cm.getColumnCount(); i < len; i++){
4158 // html: cm.getColumnHeader(i)
4162 // cfg.push(header);
4169 initEvents : function()
4171 if(!this.store || !this.cm){
4175 Roo.log('initEvents with ds!!!!');
4179 Roo.each(this.el.select('thead th.sortable', true).elements, function(e){
4180 e.on('click', _this.sort, _this);
4182 // this.maskEl = Roo.DomHelper.append(this.el.select('.TableGrid', true).first(), {tag: "div", cls:"x-dlg-mask"}, true);
4183 // this.maskEl.enableDisplayMode("block");
4184 // this.maskEl.show();
4186 this.store.on('load', this.onLoad, this);
4187 this.store.on('beforeload', this.onBeforeLoad, this);
4195 sort : function(e,el)
4197 var col = Roo.get(el)
4199 if(!col.hasClass('sortable')){
4203 var sort = col.attr('sort');
4206 if(col.hasClass('glyphicon-arrow-up')){
4210 this.store.sortInfo = {field : sort, direction : dir};
4215 renderHeader : function()
4224 for(var i = 0, len = cm.getColumnCount(); i < len; i++){
4226 var config = cm.config[i];
4230 html: cm.getColumnHeader(i)
4233 if(typeof(config.dataIndex) != 'undefined'){
4234 c.sort = config.dataIndex;
4237 if(typeof(config.sortable) != 'undefined' && config.sortable){
4241 if(typeof(config.width) != 'undefined'){
4242 c.style = 'width:' + config.width + 'px';
4251 renderBody : function()
4261 renderFooter : function()
4273 Roo.log('ds onload');
4278 Roo.each(this.el.select('thead th.sortable', true).elements, function(e){
4279 e.removeClass(['glyphicon', 'glyphicon-arrow-up', 'glyphicon-arrow-down']);
4281 if(e.hasClass('sortable') && e.attr('sort') == _this.store.sortInfo.field && _this.store.sortInfo.direction.toUpperCase() == 'ASC'){
4282 e.addClass(['glyphicon', 'glyphicon-arrow-up']);
4285 if(e.hasClass('sortable') && e.attr('sort') == _this.store.sortInfo.field && _this.store.sortInfo.direction.toUpperCase() == 'DESC'){
4286 e.addClass(['glyphicon', 'glyphicon-arrow-down']);
4290 var tbody = this.el.select('tbody', true).first();
4294 if(this.store.getCount() > 0){
4295 this.store.data.each(function(d){
4301 for(var i = 0, len = cm.getColumnCount(); i < len; i++){
4302 var renderer = cm.getRenderer(i);
4303 var config = cm.config[i];
4307 if(typeof(renderer) !== 'undefined'){
4308 value = renderer(d.data[cm.getDataIndex(i)], false, d);
4311 if(typeof(value) === 'object'){
4321 html: (typeof(value) === 'object') ? '' : value
4324 if(typeof(config.width) != 'undefined'){
4325 td.style = 'width:' + config.width + 'px';
4332 tbody.createChild(row);
4340 Roo.each(renders, function(r){
4341 _this.renderColumn(r);
4345 // if(this.loadMask){
4346 // this.maskEl.hide();
4350 onBeforeLoad : function()
4352 Roo.log('ds onBeforeLoad');
4356 // if(this.loadMask){
4357 // this.maskEl.show();
4363 this.el.select('tbody', true).first().dom.innerHTML = '';
4366 getSelectionModel : function(){
4368 this.selModel = new Roo.bootstrap.Table.RowSelectionModel();
4370 return this.selModel;
4373 renderColumn : function(r)
4376 r.cfg.render(Roo.get(r.id));
4379 Roo.each(r.cfg.cn, function(c){
4384 _this.renderColumn(child);
4401 * @class Roo.bootstrap.TableCell
4402 * @extends Roo.bootstrap.Component
4403 * Bootstrap TableCell class
4404 * @cfg {String} html cell contain text
4405 * @cfg {String} cls cell class
4406 * @cfg {String} tag cell tag (td|th) default td
4407 * @cfg {String} abbr Specifies an abbreviated version of the content in a cell
4408 * @cfg {String} align Aligns the content in a cell
4409 * @cfg {String} axis Categorizes cells
4410 * @cfg {String} bgcolor Specifies the background color of a cell
4411 * @cfg {Number} charoff Sets the number of characters the content will be aligned from the character specified by the char attribute
4412 * @cfg {Number} colspan Specifies the number of columns a cell should span
4413 * @cfg {String} headers Specifies one or more header cells a cell is related to
4414 * @cfg {Number} height Sets the height of a cell
4415 * @cfg {String} nowrap Specifies that the content inside a cell should not wrap
4416 * @cfg {Number} rowspan Sets the number of rows a cell should span
4417 * @cfg {String} scope Defines a way to associate header cells and data cells in a table
4418 * @cfg {String} valign Vertical aligns the content in a cell
4419 * @cfg {Number} width Specifies the width of a cell
4422 * Create a new TableCell
4423 * @param {Object} config The config object
4426 Roo.bootstrap.TableCell = function(config){
4427 Roo.bootstrap.TableCell.superclass.constructor.call(this, config);
4430 Roo.extend(Roo.bootstrap.TableCell, Roo.bootstrap.Component, {
4450 getAutoCreate : function(){
4451 var cfg = Roo.apply({}, Roo.bootstrap.TableCell.superclass.getAutoCreate.call(this));
4471 cfg.align=this.align
4477 cfg.bgcolor=this.bgcolor
4480 cfg.charoff=this.charoff
4483 cfg.colspan=this.colspan
4486 cfg.headers=this.headers
4489 cfg.height=this.height
4492 cfg.nowrap=this.nowrap
4495 cfg.rowspan=this.rowspan
4498 cfg.scope=this.scope
4501 cfg.valign=this.valign
4504 cfg.width=this.width
4523 * @class Roo.bootstrap.TableRow
4524 * @extends Roo.bootstrap.Component
4525 * Bootstrap TableRow class
4526 * @cfg {String} cls row class
4527 * @cfg {String} align Aligns the content in a table row
4528 * @cfg {String} bgcolor Specifies a background color for a table row
4529 * @cfg {Number} charoff Sets the number of characters the content will be aligned from the character specified by the char attribute
4530 * @cfg {String} valign Vertical aligns the content in a table row
4533 * Create a new TableRow
4534 * @param {Object} config The config object
4537 Roo.bootstrap.TableRow = function(config){
4538 Roo.bootstrap.TableRow.superclass.constructor.call(this, config);
4541 Roo.extend(Roo.bootstrap.TableRow, Roo.bootstrap.Component, {
4549 getAutoCreate : function(){
4550 var cfg = Roo.apply({}, Roo.bootstrap.TableRow.superclass.getAutoCreate.call(this));
4560 cfg.align = this.align;
4563 cfg.bgcolor = this.bgcolor;
4566 cfg.charoff = this.charoff;
4569 cfg.valign = this.valign;
4587 * @class Roo.bootstrap.TableBody
4588 * @extends Roo.bootstrap.Component
4589 * Bootstrap TableBody class
4590 * @cfg {String} cls element class
4591 * @cfg {String} tag element tag (thead|tbody|tfoot) default tbody
4592 * @cfg {String} align Aligns the content inside the element
4593 * @cfg {Number} charoff Sets the number of characters the content inside the element will be aligned from the character specified by the char attribute
4594 * @cfg {String} valign Vertical aligns the content inside the <tbody> element
4597 * Create a new TableBody
4598 * @param {Object} config The config object
4601 Roo.bootstrap.TableBody = function(config){
4602 Roo.bootstrap.TableBody.superclass.constructor.call(this, config);
4605 Roo.extend(Roo.bootstrap.TableBody, Roo.bootstrap.Component, {
4613 getAutoCreate : function(){
4614 var cfg = Roo.apply({}, Roo.bootstrap.TableBody.superclass.getAutoCreate.call(this));
4628 cfg.align = this.align;
4631 cfg.charoff = this.charoff;
4634 cfg.valign = this.valign;
4641 // initEvents : function()
4648 // this.store = Roo.factory(this.store, Roo.data);
4649 // this.store.on('load', this.onLoad, this);
4651 // this.store.load();
4655 // onLoad: function ()
4657 // this.fireEvent('load', this);
4667 * Ext JS Library 1.1.1
4668 * Copyright(c) 2006-2007, Ext JS, LLC.
4670 * Originally Released Under LGPL - original licence link has changed is not relivant.
4673 * <script type="text/javascript">
4676 // as we use this in bootstrap.
4677 Roo.namespace('Roo.form');
4679 * @class Roo.form.Action
4680 * Internal Class used to handle form actions
4682 * @param {Roo.form.BasicForm} el The form element or its id
4683 * @param {Object} config Configuration options
4688 // define the action interface
4689 Roo.form.Action = function(form, options){
4691 this.options = options || {};
4694 * Client Validation Failed
4697 Roo.form.Action.CLIENT_INVALID = 'client';
4699 * Server Validation Failed
4702 Roo.form.Action.SERVER_INVALID = 'server';
4704 * Connect to Server Failed
4707 Roo.form.Action.CONNECT_FAILURE = 'connect';
4709 * Reading Data from Server Failed
4712 Roo.form.Action.LOAD_FAILURE = 'load';
4714 Roo.form.Action.prototype = {
4716 failureType : undefined,
4717 response : undefined,
4721 run : function(options){
4726 success : function(response){
4731 handleResponse : function(response){
4735 // default connection failure
4736 failure : function(response){
4738 this.response = response;
4739 this.failureType = Roo.form.Action.CONNECT_FAILURE;
4740 this.form.afterAction(this, false);
4743 processResponse : function(response){
4744 this.response = response;
4745 if(!response.responseText){
4748 this.result = this.handleResponse(response);
4752 // utility functions used internally
4753 getUrl : function(appendParams){
4754 var url = this.options.url || this.form.url || this.form.el.dom.action;
4756 var p = this.getParams();
4758 url += (url.indexOf('?') != -1 ? '&' : '?') + p;
4764 getMethod : function(){
4765 return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
4768 getParams : function(){
4769 var bp = this.form.baseParams;
4770 var p = this.options.params;
4772 if(typeof p == "object"){
4773 p = Roo.urlEncode(Roo.applyIf(p, bp));
4774 }else if(typeof p == 'string' && bp){
4775 p += '&' + Roo.urlEncode(bp);
4778 p = Roo.urlEncode(bp);
4783 createCallback : function(){
4785 success: this.success,
4786 failure: this.failure,
4788 timeout: (this.form.timeout*1000),
4789 upload: this.form.fileUpload ? this.success : undefined
4794 Roo.form.Action.Submit = function(form, options){
4795 Roo.form.Action.Submit.superclass.constructor.call(this, form, options);
4798 Roo.extend(Roo.form.Action.Submit, Roo.form.Action, {
4801 haveProgress : false,
4802 uploadComplete : false,
4804 // uploadProgress indicator.
4805 uploadProgress : function()
4807 if (!this.form.progressUrl) {
4811 if (!this.haveProgress) {
4812 Roo.MessageBox.progress("Uploading", "Uploading");
4814 if (this.uploadComplete) {
4815 Roo.MessageBox.hide();
4819 this.haveProgress = true;
4821 var uid = this.form.findField('UPLOAD_IDENTIFIER').getValue();
4823 var c = new Roo.data.Connection();
4825 url : this.form.progressUrl,
4830 success : function(req){
4831 //console.log(data);
4835 rdata = Roo.decode(req.responseText)
4837 Roo.log("Invalid data from server..");
4841 if (!rdata || !rdata.success) {
4843 Roo.MessageBox.alert(Roo.encode(rdata));
4846 var data = rdata.data;
4848 if (this.uploadComplete) {
4849 Roo.MessageBox.hide();
4854 Roo.MessageBox.updateProgress(data.bytes_uploaded/data.bytes_total,
4855 Math.floor((data.bytes_total - data.bytes_uploaded)/1000) + 'k remaining'
4858 this.uploadProgress.defer(2000,this);
4861 failure: function(data) {
4862 Roo.log('progress url failed ');
4873 // run get Values on the form, so it syncs any secondary forms.
4874 this.form.getValues();
4876 var o = this.options;
4877 var method = this.getMethod();
4878 var isPost = method == 'POST';
4879 if(o.clientValidation === false || this.form.isValid()){
4881 if (this.form.progressUrl) {
4882 this.form.findField('UPLOAD_IDENTIFIER').setValue(
4883 (new Date() * 1) + '' + Math.random());
4888 Roo.Ajax.request(Roo.apply(this.createCallback(), {
4889 form:this.form.el.dom,
4890 url:this.getUrl(!isPost),
4892 params:isPost ? this.getParams() : null,
4893 isUpload: this.form.fileUpload
4896 this.uploadProgress();
4898 }else if (o.clientValidation !== false){ // client validation failed
4899 this.failureType = Roo.form.Action.CLIENT_INVALID;
4900 this.form.afterAction(this, false);
4904 success : function(response)
4906 this.uploadComplete= true;
4907 if (this.haveProgress) {
4908 Roo.MessageBox.hide();
4912 var result = this.processResponse(response);
4913 if(result === true || result.success){
4914 this.form.afterAction(this, true);
4918 this.form.markInvalid(result.errors);
4919 this.failureType = Roo.form.Action.SERVER_INVALID;
4921 this.form.afterAction(this, false);
4923 failure : function(response)
4925 this.uploadComplete= true;
4926 if (this.haveProgress) {
4927 Roo.MessageBox.hide();
4930 this.response = response;
4931 this.failureType = Roo.form.Action.CONNECT_FAILURE;
4932 this.form.afterAction(this, false);
4935 handleResponse : function(response){
4936 if(this.form.errorReader){
4937 var rs = this.form.errorReader.read(response);
4940 for(var i = 0, len = rs.records.length; i < len; i++) {
4941 var r = rs.records[i];
4945 if(errors.length < 1){
4949 success : rs.success,
4955 ret = Roo.decode(response.responseText);
4959 errorMsg: "Failed to read server message: " + (response ? response.responseText : ' - no message'),
4969 Roo.form.Action.Load = function(form, options){
4970 Roo.form.Action.Load.superclass.constructor.call(this, form, options);
4971 this.reader = this.form.reader;
4974 Roo.extend(Roo.form.Action.Load, Roo.form.Action, {
4979 Roo.Ajax.request(Roo.apply(
4980 this.createCallback(), {
4981 method:this.getMethod(),
4982 url:this.getUrl(false),
4983 params:this.getParams()
4987 success : function(response){
4989 var result = this.processResponse(response);
4990 if(result === true || !result.success || !result.data){
4991 this.failureType = Roo.form.Action.LOAD_FAILURE;
4992 this.form.afterAction(this, false);
4995 this.form.clearInvalid();
4996 this.form.setValues(result.data);
4997 this.form.afterAction(this, true);
5000 handleResponse : function(response){
5001 if(this.form.reader){
5002 var rs = this.form.reader.read(response);
5003 var data = rs.records && rs.records[0] ? rs.records[0].data : null;
5005 success : rs.success,
5009 return Roo.decode(response.responseText);
5013 Roo.form.Action.ACTION_TYPES = {
5014 'load' : Roo.form.Action.Load,
5015 'submit' : Roo.form.Action.Submit
5024 * @class Roo.bootstrap.Form
5025 * @extends Roo.bootstrap.Component
5026 * Bootstrap Form class
5027 * @cfg {String} method GET | POST (default POST)
5028 * @cfg {String} labelAlign top | left (default top)
5029 * @cfg {String} align left | right - for navbars
5034 * @param {Object} config The config object
5038 Roo.bootstrap.Form = function(config){
5039 Roo.bootstrap.Form.superclass.constructor.call(this, config);
5042 * @event clientvalidation
5043 * If the monitorValid config option is true, this event fires repetitively to notify of valid state
5044 * @param {Form} this
5045 * @param {Boolean} valid true if the form has passed client-side validation
5047 clientvalidation: true,
5049 * @event beforeaction
5050 * Fires before any action is performed. Return false to cancel the action.
5051 * @param {Form} this
5052 * @param {Action} action The action to be performed
5056 * @event actionfailed
5057 * Fires when an action fails.
5058 * @param {Form} this
5059 * @param {Action} action The action that failed
5061 actionfailed : true,
5063 * @event actioncomplete
5064 * Fires when an action is completed.
5065 * @param {Form} this
5066 * @param {Action} action The action that completed
5068 actioncomplete : true
5073 Roo.extend(Roo.bootstrap.Form, Roo.bootstrap.Component, {
5076 * @cfg {String} method
5077 * The request method to use (GET or POST) for form actions if one isn't supplied in the action options.
5082 * The URL to use for form actions if one isn't supplied in the action options.
5085 * @cfg {Boolean} fileUpload
5086 * Set to true if this form is a file upload.
5090 * @cfg {Object} baseParams
5091 * Parameters to pass with all requests. e.g. baseParams: {id: '123', foo: 'bar'}.
5095 * @cfg {Number} timeout Timeout for form actions in seconds (default is 30 seconds).
5099 * @cfg {Sting} align (left|right) for navbar forms
5104 activeAction : null,
5107 * By default wait messages are displayed with Roo.MessageBox.wait. You can target a specific
5108 * element by passing it or its id or mask the form itself by passing in true.
5111 waitMsgTarget : false,
5116 * By default wait messages are displayed with Roo.MessageBox.wait. You can target a specific
5117 * element by passing it or its id or mask the form itself by passing in true.
5121 getAutoCreate : function(){
5125 method : this.method || 'POST',
5126 id : this.id || Roo.id(),
5129 if (this.parent().xtype.match(/^Nav/)) {
5130 cfg.cls = 'navbar-form navbar-' + this.align;
5134 if (this.labelAlign == 'left' ) {
5135 cfg.cls += ' form-horizontal';
5141 initEvents : function()
5143 this.el.on('submit', this.onSubmit, this);
5148 onSubmit : function(e){
5153 * Returns true if client-side validation on the form is successful.
5156 isValid : function(){
5157 var items = this.getItems();
5159 items.each(function(f){
5168 * Returns true if any fields in this form have changed since their original load.
5171 isDirty : function(){
5173 var items = this.getItems();
5174 items.each(function(f){
5184 * Performs a predefined action (submit or load) or custom actions you define on this form.
5185 * @param {String} actionName The name of the action type
5186 * @param {Object} options (optional) The options to pass to the action. All of the config options listed
5187 * below are supported by both the submit and load actions unless otherwise noted (custom actions could also
5188 * accept other config options):
5190 Property Type Description
5191 ---------------- --------------- ----------------------------------------------------------------------------------
5192 url String The url for the action (defaults to the form's url)
5193 method String The form method to use (defaults to the form's method, or POST if not defined)
5194 params String/Object The params to pass (defaults to the form's baseParams, or none if not defined)
5195 clientValidation Boolean Applies to submit only. Pass true to call form.isValid() prior to posting to
5196 validate the form on the client (defaults to false)
5198 * @return {BasicForm} this
5200 doAction : function(action, options){
5201 if(typeof action == 'string'){
5202 action = new Roo.form.Action.ACTION_TYPES[action](this, options);
5204 if(this.fireEvent('beforeaction', this, action) !== false){
5205 this.beforeAction(action);
5206 action.run.defer(100, action);
5212 beforeAction : function(action){
5213 var o = action.options;
5215 // not really supported yet.. ??
5217 //if(this.waitMsgTarget === true){
5218 this.el.mask(o.waitMsg || "Sending", 'x-mask-loading');
5219 //}else if(this.waitMsgTarget){
5220 // this.waitMsgTarget = Roo.get(this.waitMsgTarget);
5221 // this.waitMsgTarget.mask(o.waitMsg || "Sending", 'x-mask-loading');
5223 // Roo.MessageBox.wait(o.waitMsg || "Sending", o.waitTitle || this.waitTitle || 'Please Wait...');
5229 afterAction : function(action, success){
5230 this.activeAction = null;
5231 var o = action.options;
5233 //if(this.waitMsgTarget === true){
5235 //}else if(this.waitMsgTarget){
5236 // this.waitMsgTarget.unmask();
5238 // Roo.MessageBox.updateProgress(1);
5239 // Roo.MessageBox.hide();
5246 Roo.callback(o.success, o.scope, [this, action]);
5247 this.fireEvent('actioncomplete', this, action);
5251 // failure condition..
5252 // we have a scenario where updates need confirming.
5253 // eg. if a locking scenario exists..
5254 // we look for { errors : { needs_confirm : true }} in the response.
5256 (typeof(action.result) != 'undefined') &&
5257 (typeof(action.result.errors) != 'undefined') &&
5258 (typeof(action.result.errors.needs_confirm) != 'undefined')
5261 Roo.log("not supported yet");
5264 Roo.MessageBox.confirm(
5265 "Change requires confirmation",
5266 action.result.errorMsg,
5271 _t.doAction('submit', { params : { _submit_confirmed : 1 } } );
5281 Roo.callback(o.failure, o.scope, [this, action]);
5282 // show an error message if no failed handler is set..
5283 if (!this.hasListener('actionfailed')) {
5284 Roo.log("need to add dialog support");
5286 Roo.MessageBox.alert("Error",
5287 (typeof(action.result) != 'undefined' && typeof(action.result.errorMsg) != 'undefined') ?
5288 action.result.errorMsg :
5289 "Saving Failed, please check your entries or try again"
5294 this.fireEvent('actionfailed', this, action);
5299 * Find a Roo.form.Field in this form by id, dataIndex, name or hiddenName
5300 * @param {String} id The value to search for
5303 findField : function(id){
5304 var items = this.getItems();
5305 var field = items.get(id);
5307 items.each(function(f){
5308 if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
5315 return field || null;
5318 * Mark fields in this form invalid in bulk.
5319 * @param {Array/Object} errors Either an array in the form [{id:'fieldId', msg:'The message'},...] or an object hash of {id: msg, id2: msg2}
5320 * @return {BasicForm} this
5322 markInvalid : function(errors){
5323 if(errors instanceof Array){
5324 for(var i = 0, len = errors.length; i < len; i++){
5325 var fieldError = errors[i];
5326 var f = this.findField(fieldError.id);
5328 f.markInvalid(fieldError.msg);
5334 if(typeof errors[id] != 'function' && (field = this.findField(id))){
5335 field.markInvalid(errors[id]);
5339 //Roo.each(this.childForms || [], function (f) {
5340 // f.markInvalid(errors);
5347 * Set values for fields in this form in bulk.
5348 * @param {Array/Object} values Either an array in the form [{id:'fieldId', value:'foo'},...] or an object hash of {id: value, id2: value2}
5349 * @return {BasicForm} this
5351 setValues : function(values){
5352 if(values instanceof Array){ // array of objects
5353 for(var i = 0, len = values.length; i < len; i++){
5355 var f = this.findField(v.id);
5357 f.setValue(v.value);
5358 if(this.trackResetOnLoad){
5359 f.originalValue = f.getValue();
5363 }else{ // object hash
5366 if(typeof values[id] != 'function' && (field = this.findField(id))){
5368 if (field.setFromData &&
5370 field.displayField &&
5371 // combos' with local stores can
5372 // be queried via setValue()
5373 // to set their value..
5374 (field.store && !field.store.isLocal)
5378 sd[field.valueField] = typeof(values[field.hiddenName]) == 'undefined' ? '' : values[field.hiddenName];
5379 sd[field.displayField] = typeof(values[field.name]) == 'undefined' ? '' : values[field.name];
5380 field.setFromData(sd);
5383 field.setValue(values[id]);
5387 if(this.trackResetOnLoad){
5388 field.originalValue = field.getValue();
5394 //Roo.each(this.childForms || [], function (f) {
5395 // f.setValues(values);
5402 * Returns the fields in this form as an object with key/value pairs. If multiple fields exist with the same name
5403 * they are returned as an array.
5404 * @param {Boolean} asString
5407 getValues : function(asString){
5408 //if (this.childForms) {
5409 // copy values from the child forms
5410 // Roo.each(this.childForms, function (f) {
5411 // this.setValues(f.getValues());
5417 var fs = Roo.lib.Ajax.serializeForm(this.el.dom);
5418 if(asString === true){
5421 return Roo.urlDecode(fs);
5425 * Returns the fields in this form as an object with key/value pairs.
5426 * This differs from getValues as it calls getValue on each child item, rather than using dom data.
5429 getFieldValues : function(with_hidden)
5431 var items = this.getItems();
5433 items.each(function(f){
5437 var v = f.getValue();
5438 if (f.inputType =='radio') {
5439 if (typeof(ret[f.getName()]) == 'undefined') {
5440 ret[f.getName()] = ''; // empty..
5443 if (!f.el.dom.checked) {
5451 // not sure if this supported any more..
5452 if ((typeof(v) == 'object') && f.getRawValue) {
5453 v = f.getRawValue() ; // dates..
5455 // combo boxes where name != hiddenName...
5456 if (f.name != f.getName()) {
5457 ret[f.name] = f.getRawValue();
5459 ret[f.getName()] = v;
5466 * Clears all invalid messages in this form.
5467 * @return {BasicForm} this
5469 clearInvalid : function(){
5470 var items = this.getItems();
5472 items.each(function(f){
5483 * @return {BasicForm} this
5486 var items = this.getItems();
5487 items.each(function(f){
5491 Roo.each(this.childForms || [], function (f) {
5498 getItems : function()
5500 var r=new Roo.util.MixedCollection(false, function(o){
5501 return o.id || (o.id = Roo.id());
5503 var iter = function(el) {
5510 Roo.each(el.items,function(e) {
5529 * Ext JS Library 1.1.1
5530 * Copyright(c) 2006-2007, Ext JS, LLC.
5532 * Originally Released Under LGPL - original licence link has changed is not relivant.
5535 * <script type="text/javascript">
5538 * @class Roo.form.VTypes
5539 * Overridable validation definitions. The validations provided are basic and intended to be easily customizable and extended.
5542 Roo.form.VTypes = function(){
5543 // closure these in so they are only created once.
5544 var alpha = /^[a-zA-Z_]+$/;
5545 var alphanum = /^[a-zA-Z0-9_]+$/;
5546 var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;
5547 var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
5549 // All these messages and functions are configurable
5552 * The function used to validate email addresses
5553 * @param {String} value The email address
5555 'email' : function(v){
5556 return email.test(v);
5559 * The error text to display when the email validation function returns false
5562 'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
5564 * The keystroke filter mask to be applied on email input
5567 'emailMask' : /[a-z0-9_\.\-@]/i,
5570 * The function used to validate URLs
5571 * @param {String} value The URL
5573 'url' : function(v){
5577 * The error text to display when the url validation function returns false
5580 'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
5583 * The function used to validate alpha values
5584 * @param {String} value The value
5586 'alpha' : function(v){
5587 return alpha.test(v);
5590 * The error text to display when the alpha validation function returns false
5593 'alphaText' : 'This field should only contain letters and _',
5595 * The keystroke filter mask to be applied on alpha input
5598 'alphaMask' : /[a-z_]/i,
5601 * The function used to validate alphanumeric values
5602 * @param {String} value The value
5604 'alphanum' : function(v){
5605 return alphanum.test(v);
5608 * The error text to display when the alphanumeric validation function returns false
5611 'alphanumText' : 'This field should only contain letters, numbers and _',
5613 * The keystroke filter mask to be applied on alphanumeric input
5616 'alphanumMask' : /[a-z0-9_]/i
5626 * @class Roo.bootstrap.Input
5627 * @extends Roo.bootstrap.Component
5628 * Bootstrap Input class
5629 * @cfg {Boolean} disabled is it disabled
5630 * @cfg {String} fieldLabel - the label associated
5631 * @cfg {String} inputType button | checkbox | email | file | hidden | image | number | password | radio | range | reset | search | submit | text
5632 * @cfg {String} name name of the input
5633 * @cfg {string} fieldLabel - the label associated
5634 * @cfg {string} inputType - input / file submit ...
5635 * @cfg {string} placeholder - placeholder to put in text.
5636 * @cfg {string} before - input group add on before
5637 * @cfg {string} after - input group add on after
5638 * @cfg {string} size - (lg|sm) or leave empty..
5639 * @cfg {Number} xs colspan out of 12 for mobile-sized screens
5640 * @cfg {Number} sm colspan out of 12 for tablet-sized screens
5641 * @cfg {Number} md colspan out of 12 for computer-sized screens
5642 * @cfg {Number} lg colspan out of 12 for large computer-sized screens
5643 * @cfg {string} value default value of the input
5644 * @cfg {Number} labelWidth set the width of label (0-12)
5645 * @cfg {String} labelAlign (top|left)
5646 * @cfg {Boolean} readOnly Specifies that the field should be read-only
5650 * Create a new Input
5651 * @param {Object} config The config object
5654 Roo.bootstrap.Input = function(config){
5655 Roo.bootstrap.Input.superclass.constructor.call(this, config);
5660 * Fires when this field receives input focus.
5661 * @param {Roo.form.Field} this
5666 * Fires when this field loses input focus.
5667 * @param {Roo.form.Field} this
5672 * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed. You can check
5673 * {@link Roo.EventObject#getKey} to determine which key was pressed.
5674 * @param {Roo.form.Field} this
5675 * @param {Roo.EventObject} e The event object
5680 * Fires just before the field blurs if the field value has changed.
5681 * @param {Roo.form.Field} this
5682 * @param {Mixed} newValue The new value
5683 * @param {Mixed} oldValue The original value
5688 * Fires after the field has been marked as invalid.
5689 * @param {Roo.form.Field} this
5690 * @param {String} msg The validation message
5695 * Fires after the field has been validated with no errors.
5696 * @param {Roo.form.Field} this
5701 * Fires after the key up
5702 * @param {Roo.form.Field} this
5703 * @param {Roo.EventObject} e The event Object
5709 Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component, {
5711 * @cfg {String/Boolean} validationEvent The event that should initiate field validation. Set to false to disable
5712 automatic validation (defaults to "keyup").
5714 validationEvent : "keyup",
5716 * @cfg {Boolean} validateOnBlur Whether the field should validate when it loses focus (defaults to true).
5718 validateOnBlur : true,
5720 * @cfg {Number} validationDelay The length of time in milliseconds after user input begins until validation is initiated (defaults to 250)
5722 validationDelay : 250,
5724 * @cfg {String} focusClass The CSS class to use when the field receives focus (defaults to "x-form-focus")
5726 focusClass : "x-form-focus", // not needed???
5730 * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to "x-form-invalid")
5732 invalidClass : "has-error",
5735 * @cfg {Boolean} selectOnFocus True to automatically select any existing field text when the field receives input focus (defaults to false)
5737 selectOnFocus : false,
5740 * @cfg {String} maskRe An input mask regular expression that will be used to filter keystrokes that don't match (defaults to null)
5744 * @cfg {String} vtype A validation type name as defined in {@link Roo.form.VTypes} (defaults to null)
5749 * @cfg {Boolean} disableKeyFilter True to disable input keystroke filtering (defaults to false)
5751 disableKeyFilter : false,
5754 * @cfg {Boolean} disabled True to disable the field (defaults to false).
5758 * @cfg {Boolean} allowBlank False to validate that the value length > 0 (defaults to true)
5762 * @cfg {String} blankText Error text to display if the allow blank validation fails (defaults to "This field is required")
5764 blankText : "This field is required",
5767 * @cfg {Number} minLength Minimum input field length required (defaults to 0)
5771 * @cfg {Number} maxLength Maximum input field length allowed (defaults to Number.MAX_VALUE)
5773 maxLength : Number.MAX_VALUE,
5775 * @cfg {String} minLengthText Error text to display if the minimum length validation fails (defaults to "The minimum length for this field is {minLength}")
5777 minLengthText : "The minimum length for this field is {0}",
5779 * @cfg {String} maxLengthText Error text to display if the maximum length validation fails (defaults to "The maximum length for this field is {maxLength}")
5781 maxLengthText : "The maximum length for this field is {0}",
5785 * @cfg {Function} validator A custom validation function to be called during field validation (defaults to null).
5786 * If available, this function will be called only after the basic validators all return true, and will be passed the
5787 * current field value and expected to return boolean true if the value is valid or a string error message if invalid.
5791 * @cfg {RegExp} regex A JavaScript RegExp object to be tested against the field value during validation (defaults to null).
5792 * If available, this regex will be evaluated only after the basic validators all return true, and will be passed the
5793 * current field value. If the test fails, the field will be marked invalid using {@link #regexText}.
5797 * @cfg {String} regexText The error text to display if {@link #regex} is used and the test fails during validation (defaults to "")
5820 parentLabelAlign : function()
5823 while (parent.parent()) {
5824 parent = parent.parent();
5825 if (typeof(parent.labelAlign) !='undefined') {
5826 return parent.labelAlign;
5833 getAutoCreate : function(){
5835 var align = (!this.labelAlign) ? this.parentLabelAlign() : this.labelAlign;
5841 if(this.inputType != 'hidden'){
5842 cfg.cls = 'form-group' //input-group
5848 type : this.inputType,
5850 cls : 'form-control',
5851 placeholder : this.placeholder || ''
5855 if(this.maxLength && this.maxLength != Number.MAX_VALUE){
5856 input.maxLength = this.maxLength;
5859 if (this.disabled) {
5860 input.disabled=true;
5863 if (this.readOnly) {
5864 input.readonly=true;
5868 input.name = this.name;
5871 input.cls += ' input-' + this.size;
5874 ['xs','sm','md','lg'].map(function(size){
5875 if (settings[size]) {
5876 cfg.cls += ' col-' + size + '-' + settings[size];
5880 var inputblock = input;
5882 if (this.before || this.after) {
5885 cls : 'input-group',
5888 if (this.before && typeof(this.before) == 'string') {
5890 inputblock.cn.push({
5892 cls : 'roo-input-before input-group-addon',
5896 if (this.before && typeof(this.before) == 'object') {
5897 this.before = Roo.factory(this.before);
5898 Roo.log(this.before);
5899 inputblock.cn.push({
5901 cls : 'roo-input-before input-group-' +
5902 (this.before.xtype == 'Button' ? 'btn' : 'addon'), //?? what about checkboxes - that looks like a bit of a hack thought?
5906 inputblock.cn.push(input);
5908 if (this.after && typeof(this.after) == 'string') {
5909 inputblock.cn.push({
5911 cls : 'roo-input-after input-group-addon',
5915 if (this.after && typeof(this.after) == 'object') {
5916 this.after = Roo.factory(this.after);
5917 Roo.log(this.after);
5918 inputblock.cn.push({
5920 cls : 'roo-input-after input-group-' +
5921 (this.before.xtype == 'Button' ? 'btn' : 'addon'), //?? what about checkboxes - that looks like a bit of a hack thought?
5926 if (align ==='left' && this.fieldLabel.length) {
5927 Roo.log("left and has label");
5933 cls : 'control-label col-sm-' + this.labelWidth,
5934 html : this.fieldLabel
5938 cls : "col-sm-" + (12 - this.labelWidth),
5945 } else if ( this.fieldLabel.length) {
5951 //cls : 'input-group-addon',
5952 html : this.fieldLabel
5962 Roo.log(" no label && no align");
5971 Roo.log('input-parentType: ' + this.parentType);
5973 if (this.parentType === 'Navbar' && this.parent().bar) {
5974 cfg.cls += ' navbar-form';
5982 * return the real input element.
5984 inputEl: function ()
5986 return this.el.select('input.form-control',true).first();
5988 setDisabled : function(v)
5990 var i = this.inputEl().dom;
5992 i.removeAttribute('disabled');
5996 i.setAttribute('disabled','true');
5998 initEvents : function()
6001 this.inputEl().on("keydown" , this.fireKey, this);
6002 this.inputEl().on("focus", this.onFocus, this);
6003 this.inputEl().on("blur", this.onBlur, this);
6005 this.inputEl().relayEvent('keyup', this);
6007 // reference to original value for reset
6008 this.originalValue = this.getValue();
6009 //Roo.form.TextField.superclass.initEvents.call(this);
6010 if(this.validationEvent == 'keyup'){
6011 this.validationTask = new Roo.util.DelayedTask(this.validate, this);
6012 this.inputEl().on('keyup', this.filterValidation, this);
6014 else if(this.validationEvent !== false){
6015 this.inputEl().on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
6018 if(this.selectOnFocus){
6019 this.on("focus", this.preFocus, this);
6022 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Roo.form.VTypes[this.vtype+'Mask']))){
6023 this.inputEl().on("keypress", this.filterKeys, this);
6026 this.el.on("keyup", this.onKeyUp, this, {buffer:50});
6027 this.el.on("click", this.autoSize, this);
6030 if(this.inputEl().is('input[type=password]') && Roo.isSafari){
6031 this.inputEl().on('keydown', this.SafariOnKeyDown, this);
6034 if (typeof(this.before) == 'object') {
6035 this.before.render(this.el.select('.roo-input-before',true).first());
6037 if (typeof(this.after) == 'object') {
6038 this.after.render(this.el.select('.roo-input-after',true).first());
6043 filterValidation : function(e){
6044 if(!e.isNavKeyPress()){
6045 this.validationTask.delay(this.validationDelay);
6049 * Validates the field value
6050 * @return {Boolean} True if the value is valid, else false
6052 validate : function(){
6053 //if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
6054 if(this.disabled || this.validateValue(this.getRawValue())){
6055 this.clearInvalid();
6063 * Validates a value according to the field's validation rules and marks the field as invalid
6064 * if the validation fails
6065 * @param {Mixed} value The value to validate
6066 * @return {Boolean} True if the value is valid, else false
6068 validateValue : function(value){
6069 if(value.length < 1) { // if it's blank
6070 if(this.allowBlank){
6071 this.clearInvalid();
6074 this.markInvalid(this.blankText);
6078 if(value.length < this.minLength){
6079 this.markInvalid(String.format(this.minLengthText, this.minLength));
6082 if(value.length > this.maxLength){
6083 this.markInvalid(String.format(this.maxLengthText, this.maxLength));
6087 var vt = Roo.form.VTypes;
6088 if(!vt[this.vtype](value, this)){
6089 this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
6093 if(typeof this.validator == "function"){
6094 var msg = this.validator(value);
6096 this.markInvalid(msg);
6100 if(this.regex && !this.regex.test(value)){
6101 this.markInvalid(this.regexText);
6110 fireKey : function(e){
6111 //Roo.log('field ' + e.getKey());
6112 if(e.isNavKeyPress()){
6113 this.fireEvent("specialkey", this, e);
6116 focus : function (selectText){
6118 this.inputEl().focus();
6119 if(selectText === true){
6120 this.inputEl().dom.select();
6126 onFocus : function(){
6127 if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
6128 // this.el.addClass(this.focusClass);
6131 this.hasFocus = true;
6132 this.startValue = this.getValue();
6133 this.fireEvent("focus", this);
6137 beforeBlur : Roo.emptyFn,
6141 onBlur : function(){
6143 if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
6144 //this.el.removeClass(this.focusClass);
6146 this.hasFocus = false;
6147 if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
6150 var v = this.getValue();
6151 if(String(v) !== String(this.startValue)){
6152 this.fireEvent('change', this, v, this.startValue);
6154 this.fireEvent("blur", this);
6158 * Resets the current field value to the originally loaded value and clears any validation messages
6161 this.setValue(this.originalValue);
6162 this.clearInvalid();
6165 * Returns the name of the field
6166 * @return {Mixed} name The name field
6168 getName: function(){
6172 * Returns the normalized data value (undefined or emptyText will be returned as ''). To return the raw value see {@link #getRawValue}.
6173 * @return {Mixed} value The field value
6175 getValue : function(){
6176 return this.inputEl().getValue();
6179 * Returns the raw data value which may or may not be a valid, defined value. To return a normalized value see {@link #getValue}.
6180 * @return {Mixed} value The field value
6182 getRawValue : function(){
6183 var v = this.inputEl().getValue();
6189 * Sets the underlying DOM field's value directly, bypassing validation. To set the value with validation see {@link #setValue}.
6190 * @param {Mixed} value The value to set
6192 setRawValue : function(v){
6193 return this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
6196 selectText : function(start, end){
6197 var v = this.getRawValue();
6199 start = start === undefined ? 0 : start;
6200 end = end === undefined ? v.length : end;
6201 var d = this.inputEl().dom;
6202 if(d.setSelectionRange){
6203 d.setSelectionRange(start, end);
6204 }else if(d.createTextRange){
6205 var range = d.createTextRange();
6206 range.moveStart("character", start);
6207 range.moveEnd("character", v.length-end);
6214 * Sets a data value into the field and validates it. To set the value directly without validation see {@link #setRawValue}.
6215 * @param {Mixed} value The value to set
6217 setValue : function(v){
6220 this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
6226 processValue : function(value){
6227 if(this.stripCharsRe){
6228 var newValue = value.replace(this.stripCharsRe, '');
6229 if(newValue !== value){
6230 this.setRawValue(newValue);
6237 preFocus : function(){
6239 if(this.selectOnFocus){
6240 this.inputEl().dom.select();
6243 filterKeys : function(e){
6245 if(!Roo.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
6248 var c = e.getCharCode(), cc = String.fromCharCode(c);
6249 if(Roo.isIE && (e.isSpecialKey() || !cc)){
6252 if(!this.maskRe.test(cc)){
6257 * Clear any invalid styles/messages for this field
6259 clearInvalid : function(){
6261 if(!this.el || this.preventMark){ // not rendered
6264 this.el.removeClass(this.invalidClass);
6266 switch(this.msgTarget){
6268 this.el.dom.qtip = '';
6271 this.el.dom.title = '';
6275 Roo.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
6280 this.errorIcon.dom.qtip = '';
6281 this.errorIcon.hide();
6282 this.un('resize', this.alignErrorIcon, this);
6286 var t = Roo.getDom(this.msgTarget);
6288 t.style.display = 'none';
6292 this.fireEvent('valid', this);
6295 * Mark this field as invalid
6296 * @param {String} msg The validation message
6298 markInvalid : function(msg){
6299 if(!this.el || this.preventMark){ // not rendered
6302 this.el.addClass(this.invalidClass);
6304 msg = msg || this.invalidText;
6305 switch(this.msgTarget){
6307 this.el.dom.qtip = msg;
6308 this.el.dom.qclass = 'x-form-invalid-tip';
6309 if(Roo.QuickTips){ // fix for floating editors interacting with DND
6310 Roo.QuickTips.enable();
6314 this.el.dom.title = msg;
6318 var elp = this.el.findParent('.x-form-element', 5, true);
6319 this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
6320 this.errorEl.setWidth(elp.getWidth(true)-20);
6322 this.errorEl.update(msg);
6323 Roo.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
6326 if(!this.errorIcon){
6327 var elp = this.el.findParent('.x-form-element', 5, true);
6328 this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
6330 this.alignErrorIcon();
6331 this.errorIcon.dom.qtip = msg;
6332 this.errorIcon.dom.qclass = 'x-form-invalid-tip';
6333 this.errorIcon.show();
6334 this.on('resize', this.alignErrorIcon, this);
6337 var t = Roo.getDom(this.msgTarget);
6339 t.style.display = this.msgDisplay;
6343 this.fireEvent('invalid', this, msg);
6346 SafariOnKeyDown : function(event)
6348 // this is a workaround for a password hang bug on chrome/ webkit.
6350 var isSelectAll = false;
6352 if(this.inputEl().dom.selectionEnd > 0){
6353 isSelectAll = (this.inputEl().dom.selectionEnd - this.inputEl().dom.selectionStart - this.getValue().length == 0) ? true : false;
6355 if(((event.getKey() == 8 || event.getKey() == 46) && this.getValue().length ==1)){ // backspace and delete key
6356 event.preventDefault();
6361 if(isSelectAll){ // backspace and delete key
6363 event.preventDefault();
6364 // this is very hacky as keydown always get's upper case.
6366 var cc = String.fromCharCode(event.getCharCode());
6367 this.setValue( event.shiftKey ? cc : cc.toLowerCase());
6371 adjustWidth : function(tag, w){
6372 tag = tag.toLowerCase();
6373 if(typeof w == 'number' && Roo.isStrict && !Roo.isSafari){
6374 if(Roo.isIE && (tag == 'input' || tag == 'textarea')){
6378 if(tag == 'textarea'){
6381 }else if(Roo.isOpera){
6385 if(tag == 'textarea'){