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.)
19 * Do not use directly - it does not do anything..
20 * @param {Object} config The config object
25 Roo.bootstrap.Component = function(config){
26 Roo.bootstrap.Component.superclass.constructor.call(this, config);
29 Roo.extend(Roo.bootstrap.Component, Roo.BoxComponent, {
32 allowDomMove : false, // to stop relocations in parent onRender...
40 initEvents : function() { },
47 // returns the parent component..
48 return Roo.ComponentMgr.get(this.parentId)
54 onRender : function(ct, position)
56 Roo.log("Call onRender: " + this.xtype);
58 Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
61 if (this.el.attr('xtype')) {
62 this.el.dom.removeAttribute('xtype');
71 var cfg = Roo.apply({}, this.getAutoCreate());
74 // fill in the extra attributes
75 if (this.xattr && typeof(this.xattr) =='object') {
76 for (var i in this.xattr) {
77 cfg[i] = this.xattr[i];
82 cfg.cls += ' ' + this.cls;
84 if (this.style) { // fixme needs to support more complex style data.
85 cfg.style = this.style;
87 this.el = ct.createChild(cfg, position);
88 if(this.tabIndex !== undefined){
89 this.el.dom.setAttribute('tabIndex', this.tabIndex);
96 getChildContainer : function()
101 addxtype : function (tree, cntr) {
103 cntr = typeof(cntr == 'undefined' ) ? 'getChildContainer' : cntr;
105 // render the element if it's not BODY.
106 if (tree.xtype != 'Body') {
108 cn = Roo.factory(tree);
110 cn.parentType = this.xtype; //??
111 cn.parentId = this.id;
113 // does the container contain child eleemnts with 'xtype' attributes.
114 // that match this xtype..
115 // note - when we render we create these as well..
116 // so we should check to see if body has xtype set.
117 if (Roo.get(document.body).attr('xtype') == 'Roo.bootstrap.Body') {
119 var echild = Roo.get(this[cntr]()).child('*[xtype]');
121 // Roo.log("found child for " + this.xtype +": " + echild.attr('xtype') );
123 //echild.dom.removeAttribute('xtype');
125 Roo.log("missing child for " + this.xtype);
128 cn.render(this[cntr]());
129 // then add the element..
136 if (typeof (tree.menu) != 'undefined') {
137 tree.menu.parentType = cn.xtype;
138 tree.menu.triggerEl = cn.el;
139 nitems.push(cn.addxtype(Roo.apply({}, tree.menu)));
142 if (typeof (tree.buttons) != 'undefined' && typeof(cn.getButtonContainer) == 'function') {
144 for(var i =0;i < tree.buttons.length;i++) {
145 nitems.push(cn.addxtype(Roo.apply({}, tree.buttons[i]), 'getButtonContainer'));
150 if (!tree.items || !tree.items.length) {
154 var items = tree.items;
157 //Roo.log(items.length);
159 for(var i =0;i < items.length;i++) {
160 nitems.push(cn.addxtype(Roo.apply({}, items[i])));
180 Roo.bootstrap.Body = function(config){
181 Roo.bootstrap.Body.superclass.constructor.call(this, config);
182 this.el = Roo.get(document.body);
185 Roo.extend(Roo.bootstrap.Body, Roo.bootstrap.Component, {
190 onRender : function(ct, position){
193 //this.el.addClass([this.fieldClass, this.cls]);
211 * @class Roo.bootstrap.ButtonGroup
212 * @extends Roo.bootstrap.Component
213 * Bootstrap ButtonGroup class
214 * @cfg {String} size lg | sm | xs (default empty normal)
215 * @cfg {String} align vertical | justified (default none)
216 * @cfg {String} direction up | down (default down)
217 * @cfg {Boolean} toolbar false | true
218 * @cfg {Boolean} btn true | false
223 * @param {Object} config The config object
226 Roo.bootstrap.ButtonGroup = function(config){
227 Roo.bootstrap.ButtonGroup.superclass.constructor.call(this, config);
230 Roo.extend(Roo.bootstrap.ButtonGroup, Roo.bootstrap.Component, {
238 getAutoCreate : function(){
244 cfg.html = this.html || cfg.html;
255 if (['vertical','justified'].indexOf(this.align)!==-1) {
256 cfg.cls = 'btn-group-' + this.align;
258 if (this.align == 'justified') {
259 console.log(this.items);
263 if (['lg','sm','xs'].indexOf(this.size)!==-1) {
264 cfg.cls += ' btn-group-' + this.size;
267 if (this.direction == 'up') {
268 cfg.cls += ' dropup' ;
284 * @class Roo.bootstrap.Button
285 * @extends Roo.bootstrap.Component
286 * Bootstrap Button class
287 * @cfg {String} html The button content
288 * @cfg {String} weight default (or empty) | primary | success | info | warning | danger
289 * @cfg {String} size empty | lg | sm | xs
290 * @cfg {String} tag empty | a | input | submit
291 * @cfg {String} href empty or href
292 * @cfg {Boolean} disabled false | true
293 * @cfg {Boolean} isClose false | true
294 * @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
295 * @cfg {String} badge text for badge
296 * @cfg {String} theme default (or empty) | glow
297 * @cfg {Boolean} inverse false | true
298 * @cfg {Boolean} toggle false | true
299 * @cfg {String} ontext text for on toggle state
300 * @cfg {String} offtext text for off toggle state
301 * @cfg {Boolean} defaulton true | false
304 * Create a new button
305 * @param {Object} config The config object
309 Roo.bootstrap.Button = function(config){
310 Roo.bootstrap.Button.superclass.constructor.call(this, config);
315 * The raw click event for the entire grid.
316 * @param {Roo.EventObject} e
322 Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, {
341 getAutoCreate : function(){
349 if (['a', 'button', 'input', 'submit'].indexOf(this.tag) < 0) {
350 throw "Invalid value for tag: " + this.tag + ". must be a, button, input or submit.";
355 cfg.html = this.html || cfg.html;
357 if (this.toggle===true) {
360 cls: 'slider-frame roo-button',
365 'data-off-text':'OFF',
366 cls: 'slider-button',
372 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
373 cfg.cls += ' '+this.weight;
382 cfg["aria-hidden"] = true;
384 cfg.html = "×";
390 if (this.theme==='default') {
391 cfg.cls = 'btn roo-button';
393 if (this.parentType != 'Navbar') {
394 this.weight = this.weight.length ? this.weight : 'default';
396 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
398 cfg.cls += ' btn-' + this.weight;
400 } else if (this.theme==='glow') {
403 cfg.cls = 'btn-glow roo-button';
405 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
407 cfg.cls += ' ' + this.weight;
413 this.cls += ' inverse';
418 cfg.cls += ' active';
421 cfg.cls += this.size.length ? (' btn-' + this.size) : '';
423 //gsRoo.log(this.parentType);
424 if (this.parentType === 'Navbar') {
432 href : this.href || '#'
435 cfg.cn[0].html = this.html + ' <span class="caret"></span>';
436 cfg.cls += ' dropdown';
441 } else if (this.menu) {
443 cfg.cls += ' dropdown test';
449 cfg.disabled = 'disabled';
453 Roo.log('changing to ul' );
455 this.glyphicon = 'caret';
458 if (this.glyphicon) {
459 cfg.html = ' ' + cfg.html;
464 cls: 'glyphicon glyphicon-' + this.glyphicon
474 cfg.cls='btn roo-button';
490 if (cfg.tag !== 'a' && this.href !== '') {
491 throw "Tag must be a to set href.";
492 } else if (this.href.length > 0) {
493 cfg.href = this.href;
498 initEvents: function() {
499 // Roo.log('init events?');
500 // Roo.log(this.el.dom);
501 if (this.el.hasClass('roo-button')) {
502 this.el.on('click', this.onClick, this);
504 this.el.select('.roo-button').on('click', this.onClick, this);
510 onClick : function(e)
512 Roo.log('button on click ');
514 this.fireEvent('click', this, e);
528 * @class Roo.bootstrap.Column
529 * @extends Roo.bootstrap.Component
530 * Bootstrap Column class
531 * @cfg {Number} xs colspan out of 12 for mobile-sized screens
532 * @cfg {Number} sm colspan out of 12 for tablet-sized screens
533 * @cfg {Number} md colspan out of 12 for computer-sized screens
534 * @cfg {Number} lg colspan out of 12 for large computer-sized screens
535 * @cfg {String} html content of column.
538 * Create a new Column
539 * @param {Object} config The config object
542 Roo.bootstrap.Column = function(config){
543 Roo.bootstrap.Column.superclass.constructor.call(this, config);
546 Roo.extend(Roo.bootstrap.Column, Roo.bootstrap.Component, {
555 getAutoCreate : function(){
556 var cfg = Roo.apply({}, Roo.bootstrap.Column.superclass.getAutoCreate.call(this));
564 ['xs','sm','md','lg'].map(function(size){
565 if (settings[size]) {
566 cfg.cls += ' col-' + size + '-' + settings[size];
569 if (this.html.length) {
570 cfg.html = this.html;
589 * @class Roo.bootstrap.Container
590 * @extends Roo.bootstrap.Component
591 * Bootstrap Container class
592 * @cfg {Boolean} jumbotron is it a jumbotron element
593 * @cfg {String} html content of element
594 * @cfg {String} well (lg|sm|md) a well, large, small or medium.
595 * @cfg {String} panel (primary|success|info|warning|danger) render as a panel.
596 * @cfg {String} header content of header (for panel)
597 * @cfg {String} footer content of footer (for panel)
598 * @cfg {String} sticky (footer|wrap|push) block to use as footer or body- needs css-bootstrap/sticky-footer.css
601 * Create a new Container
602 * @param {Object} config The config object
605 Roo.bootstrap.Container = function(config){
606 Roo.bootstrap.Container.superclass.constructor.call(this, config);
609 Roo.extend(Roo.bootstrap.Container, Roo.bootstrap.Component, {
619 getChildContainer : function() {
620 if (this.panel.length) {
621 return this.el.select('.panel-body',true).first();
628 getAutoCreate : function(){
634 if (this.jumbotron) {
635 cfg.cls = 'jumbotron';
638 cfg.cls = this.cls + '';
641 if (this.sticky.length) {
642 var bd = Roo.get(document.body);
643 if (!bd.hasClass('bootstrap-sticky')) {
644 bd.addClass('bootstrap-sticky');
645 Roo.select('html',true).setStyle('height', '100%');
648 cfg.cls += 'bootstrap-sticky-' + this.sticky;
652 if (this.well.length) {
656 cfg.cls +=' well well-' +this.well;
666 if (this.panel.length) {
667 cfg.cls += 'panel panel-' + this.panel;
669 if (this.header.length) {
672 cls : 'panel-heading',
688 if (this.footer.length) {
690 cls : 'panel-footer',
698 body.html = this.html || cfg.html;
700 if (!cfg.cls.length) {
701 cfg.cls = 'container';
718 * @class Roo.bootstrap.Img
719 * @extends Roo.bootstrap.Component
720 * Bootstrap Img class
721 * @cfg {Boolean} imgResponsive false | true
722 * @cfg {String} border rounded | circle | thumbnail
723 * @cfg {String} src image source
724 * @cfg {String} alt image alternative text
728 * @param {Object} config The config object
731 Roo.bootstrap.Img = function(config){
732 Roo.bootstrap.Img.superclass.constructor.call(this, config);
735 Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component, {
741 getAutoCreate : function(){
745 cls: 'img-responsive',
749 cfg.html = this.html || cfg.html;
751 cfg.src = this.src || cfg.src;
753 if (['rounded','circle','thumbnail'].indexOf(this.border)>-1) {
754 cfg.cls += ' img-' + this.border;
774 * @class Roo.bootstrap.Header
775 * @extends Roo.bootstrap.Component
776 * Bootstrap Header class
777 * @cfg {String} html content of header
778 * @cfg {Number} level (1|2|3|4|5|6) default 1
781 * Create a new Header
782 * @param {Object} config The config object
786 Roo.bootstrap.Header = function(config){
787 Roo.bootstrap.Header.superclass.constructor.call(this, config);
790 Roo.extend(Roo.bootstrap.Header, Roo.bootstrap.Component, {
798 getAutoCreate : function(){
801 tag: 'h' + (1 *this.level),
802 html: this.html || 'fill in html'
820 * @class Roo.bootstrap.Menu
821 * @extends Roo.bootstrap.Component
822 * Bootstrap Menu class - container for MenuItems
823 * @cfg {String} type type of menu
827 * @param {Object} config The config object
831 Roo.bootstrap.Menu = function(config){
832 Roo.bootstrap.Menu.superclass.constructor.call(this, config);
835 Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component, {
843 getChildContainer : function() {
847 getAutoCreate : function(){
849 //if (['right'].indexOf(this.align)!==-1) {
850 // cfg.cn[1].cls += ' pull-right'
854 cls : 'dropdown-menu'
858 if (this.type==='submenu') {
859 cfg.cls='submenu active'
864 initEvents : function() {
865 // Roo.log("ADD event");
866 // Roo.log(this.triggerEl.dom);
867 this.triggerEl.on('click', this.toggle, this);
868 this.triggerEl.addClass('dropdown-toggle');
873 //Roo.log(e.getTarget());
874 // Roo.log(this.triggerEl.dom);
875 if (Roo.get(e.getTarget()).findParent('.dropdown-menu')) {
878 var isActive = this.triggerEl.hasClass('open');
879 // if disabled.. ingore
881 //if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
882 // if mobile we use a backdrop because click events don't delegate
883 // $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
886 //var relatedTarget = { relatedTarget: this }
887 //$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
889 //if (e.isDefaultPrevented()) return;
891 this.triggerEl[isActive ? 'removeClass' : 'addClass']('open');
893 // .trigger('shown.bs.dropdown', relatedTarget)
895 this.triggerEl.focus();
901 clearMenus : function()
903 //$(backdrop).remove()
904 Roo.select('.dropdown-toggle',true).each(function(aa) {
905 if (!aa.hasClass('open')) {
909 aa.removeClass('open');
910 //var parent = getParent($(this))
911 //var relatedTarget = { relatedTarget: this }
913 //$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
914 //if (e.isDefaultPrevented()) return
915 //$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
933 * @class Roo.bootstrap.MenuItem
934 * @extends Roo.bootstrap.Component
935 * Bootstrap MenuItem class
936 * @cfg {String} html the menu label
937 * @cfg {String} href the link
941 * Create a new MenuItem
942 * @param {Object} config The config object
946 Roo.bootstrap.MenuItem = function(config){
947 Roo.bootstrap.MenuItem.superclass.constructor.call(this, config);
950 Roo.extend(Roo.bootstrap.MenuItem, Roo.bootstrap.Component, {
955 getAutoCreate : function(){
967 cfg.cn[0].href = this.href || cfg.cn[0].href ;
968 cfg.cn[0].html = this.html || cfg.cn[0].html ;
985 * @class Roo.bootstrap.MenuSeparator
986 * @extends Roo.bootstrap.Component
987 * Bootstrap MenuSeparator class
990 * Create a new MenuItem
991 * @param {Object} config The config object
995 Roo.bootstrap.MenuSeparator = function(config){
996 Roo.bootstrap.MenuSeparator.superclass.constructor.call(this, config);
999 Roo.extend(Roo.bootstrap.MenuSeparator, Roo.bootstrap.Component, {
1001 getAutoCreate : function(){
1016 <div class="modal fade">
1017 <div class="modal-dialog">
1018 <div class="modal-content">
1019 <div class="modal-header">
1020 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
1021 <h4 class="modal-title">Modal title</h4>
1023 <div class="modal-body">
1024 <p>One fine body…</p>
1026 <div class="modal-footer">
1027 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1028 <button type="button" class="btn btn-primary">Save changes</button>
1030 </div><!-- /.modal-content -->
1031 </div><!-- /.modal-dialog -->
1032 </div><!-- /.modal -->
1042 * @class Roo.bootstrap.Modal
1043 * @extends Roo.bootstrap.Component
1044 * Bootstrap Modal class
1045 * @cfg {String} title Title of dialog
1046 * @cfg {Array} buttons Array of buttons
1049 * Create a new Modal Dialog
1050 * @param {Object} config The config object
1053 Roo.bootstrap.Modal = function(config){
1054 Roo.bootstrap.Modal.superclass.constructor.call(this, config);
1057 Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component, {
1059 title : 'test dialog',
1063 onRender : function(ct, position)
1065 Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
1067 var cfg = Roo.apply({}, this.getAutoCreate());
1070 // cfg.name = typeof(this.name) == 'undefined' ? this.id : this.name;
1072 //if (!cfg.name.length) {
1076 cfg.cls += ' ' + this.cls;
1079 cfg.style = this.style;
1081 this.el = Roo.get(document.body).createChild(cfg, position);
1083 //var type = this.el.dom.type;
1085 if(this.tabIndex !== undefined){
1086 this.el.dom.setAttribute('tabIndex', this.tabIndex);
1089 //this.el.addClass([this.fieldClass, this.cls]);
1092 getAutoCreate : function(){
1098 cls: "modal-dialog",
1101 cls : "modal-content",
1104 cls : 'modal-header',
1113 cls : 'modal-title',
1124 cls : 'modal-footer'
1129 cls : 'btn btn-default',
1134 cls : 'btn btn-primary',
1155 getChildContainer : function() {
1157 return this.el.select('.modal-body',true).first();
1160 getButtonContainer : function() {
1161 return this.el.select('.modal-footer',true).first();
1164 initEvents : function()
1166 this.el.select('.modal-header .close').on('click', this.hide, this);
1169 this.el.addClass('on');
1170 this.el.removeClass('fade');
1171 this.el.setStyle('display', 'block');
1174 this.el.removeClass('on');
1175 this.el.addClass('fade');
1176 this.el.setStyle('display', 'none');
1188 * @class Roo.bootstrap.Navbar
1189 * @extends Roo.bootstrap.Component
1190 * Bootstrap Navbar class
1191 * @cfg {Boolean} sidebar has side bar
1192 * @cfg {Boolean} bar is a bar?
1193 * @cfg {String} position (fixed-top|fixed-bottom|static-top) position
1194 * @cfg {String} brand what is brand
1195 * @cfg {Boolean} inverse is inverted color
1196 * @cfg {String} type (nav | pills | tabs)
1197 * @cfg {Boolean} arrangement stacked | justified
1198 * @cfg {String} align (left | right) alignment
1202 * Create a new Navbar
1203 * @param {Object} config The config object
1207 Roo.bootstrap.Navbar = function(config){
1208 Roo.bootstrap.Navbar.superclass.constructor.call(this, config);
1211 Roo.extend(Roo.bootstrap.Navbar, Roo.bootstrap.Component, {
1223 getAutoCreate : function(){
1228 if (this.sidebar === true) {
1236 if (this.bar === true) {
1244 cls: 'navbar-header',
1249 cls: 'navbar-toggle',
1250 'data-toggle': 'collapse',
1255 html: 'Toggle navigation'
1275 cls: 'collapse navbar-collapse'
1280 cfg.cls += this.inverse ? ' navbar-inverse' : ' navbar-default';
1282 if (['fixed-top','fixed-bottom','static-top'].indexOf(this.position)>-1) {
1283 cfg.cls += ' navbar-' + this.position;
1284 cfg.tag = this.position == 'fixed-bottom' ? 'footer' : 'header';
1287 if (this.brand !== '') {
1291 cls: 'navbar-brand',
1300 } else if (this.bar === false) {
1303 Roo.log('Property \'bar\' in of Navbar must be either true or false')
1313 if (['tabs','pills'].indexOf(this.type)!==-1) {
1314 cfg.cn[0].cls += ' nav-' + this.type
1316 if (this.type!=='nav') {
1317 Roo.log('nav type must be nav/tabs/pills')
1319 cfg.cn[0].cls += ' navbar-nav'
1322 if (['stacked','justified'].indexOf(this.arrangement)!==-1) {
1323 cfg.cn[0].cls += ' nav-' + this.arrangement;
1326 if (this.align === 'right') {
1327 cfg.cn[0].cls += ' navbar-right';
1330 cfg.cls += ' navbar-inverse';
1338 getChildContainer : function() {
1339 if (this.bar === true) {
1340 return this.el.select('.collapse',true).first();
1358 * @class Roo.bootstrap.NavGroup
1359 * @extends Roo.bootstrap.Component
1360 * Bootstrap NavGroup class
1361 * @cfg {String} align left | right
1362 * @cfg {Boolean} inverse false | true
1365 * Create a new nav group
1366 * @param {Object} config The config object
1369 Roo.bootstrap.NavGroup = function(config){
1370 Roo.bootstrap.NavGroup.superclass.constructor.call(this, config);
1373 Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component, {
1379 getAutoCreate : function(){
1380 var cfg = Roo.apply({}, Roo.bootstrap.NavGroup.superclass.getAutoCreate.call(this));
1384 cls: 'nav navbar-nav'
1387 if (this.parent().sidebar === true) {
1390 cls: 'dashboard-menu'
1396 if (this.form === true) {
1402 if (this.align === 'right') {
1403 cfg.cls += ' navbar-right';
1405 cfg.cls += ' navbar-left';
1410 if (this.align === 'right') {
1411 cfg.cls += ' navbar-right';
1415 cfg.cls += ' navbar-inverse';
1434 * @class Roo.bootstrap.Navbar.Button
1435 * @extends Roo.bootstrap.Component
1436 * Bootstrap Navbar.Button class
1437 * @cfg {String} href link to
1438 * @cfg {String} html content of button
1441 * Create a new Navbar Button
1442 * @param {Object} config The config object
1446 Roo.bootstrap.Navbar.Button = function(config){
1447 Roo.bootstrap.Navbar.Button.superclass.constructor.call(this, config);
1450 Roo.extend(Roo.bootstrap.Navbar.Button, Roo.bootstrap.Component, {
1461 getAutoCreate : function(){
1471 html : this.html || ''
1495 * @class Roo.bootstrap.Navbar.Item
1496 * @extends Roo.bootstrap.Component
1497 * Bootstrap Navbar.Button class
1498 * @cfg {String} href link to
1499 * @cfg {String} html content of button
1500 * @cfg {String} badge text inside badge
1501 * @cfg {String} glyphicon name of glyphicon
1504 * Create a new Navbar Button
1505 * @param {Object} config The config object
1507 Roo.bootstrap.Navbar.Item = function(config){
1508 Roo.bootstrap.Navbar.Item.superclass.constructor.call(this, config);
1511 Roo.extend(Roo.bootstrap.Navbar.Item, Roo.bootstrap.Component, {
1519 getAutoCreate : function(){
1521 var cfg = Roo.apply({}, Roo.bootstrap.Navbar.Item.superclass.getAutoCreate.call(this));
1523 if (this.parent().parent().sidebar === true) {
1536 cfg.cn[0].html = this.html;
1540 this.cls += ' active';
1544 cfg.cn[0].cls += ' dropdown-toggle';
1545 cfg.cn[0].html = (cfg.cn[0].html || this.html) + '<span class="glyphicon glyphicon-chevron-down"></span>';
1549 cfg.cn[0].tag = 'a',
1550 cfg.cn[0].href = this.href;
1553 if (this.glyphicon) {
1554 cfg.cn[0].html = '<i class="glyphicon glyphicon-'+this.glyphicon+'"></i><span>' + cfg.cn[0].html || this.html + '</span>'
1570 if (this.glyphicon) {
1571 if(cfg.html){cfg.html = ' ' + this.html};
1575 cls: 'glyphicon glyphicon-' + this.glyphicon
1580 cfg.cn[0].html = this.html || cfg.cn[0].html ;
1584 cfg.cn[0].html += " <span class='caret'></span>";
1585 //}else if (!this.href) {
1586 // cfg.cn[0].tag='p';
1587 // cfg.cn[0].cls='navbar-text';
1590 cfg.cn[0].href=this.href||'#';
1591 cfg.cn[0].html=this.html;
1594 if (this.badge !== '') {
1597 cfg.cn[0].html + ' ',
1610 initEvents: function() {
1611 // Roo.log('init events?');
1612 // Roo.log(this.el.dom);
1613 this.el.select('a',true).on('click',
1615 this.fireEvent('click', this);
1632 * @class Roo.bootstrap.Row
1633 * @extends Roo.bootstrap.Component
1634 * Bootstrap Row class (contains columns...)
1638 * @param {Object} config The config object
1641 Roo.bootstrap.Row = function(config){
1642 Roo.bootstrap.Row.superclass.constructor.call(this, config);
1645 Roo.extend(Roo.bootstrap.Row, Roo.bootstrap.Component, {
1664 * @class Roo.bootstrap.Element
1665 * @extends Roo.bootstrap.Component
1666 * Bootstrap Element class
1667 * @cfg {String} html contents of the element
1668 * @cfg {String} tag tag of the element
1669 * @cfg {String} cls class of the element
1672 * Create a new Element
1673 * @param {Object} config The config object
1676 Roo.bootstrap.Element = function(config){
1677 Roo.bootstrap.Element.superclass.constructor.call(this, config);
1680 Roo.extend(Roo.bootstrap.Element, Roo.bootstrap.Component, {
1688 getAutoCreate : function(){
1689 var cfg = Roo.apply({}, Roo.bootstrap.Element.superclass.getAutoCreate.call(this));
1712 * @class Roo.bootstrap.Pagination
1713 * @extends Roo.bootstrap.Component
1714 * Bootstrap Pagination class
1715 * @cfg {String} size xs | sm | md | lg
1716 * @cfg {Boolean} inverse false | true
1717 * @cfg {Number} from pagination starting number
1718 * @cfg {Number} to pagination ending number
1719 * @cfg {String} align empty or left | right
1720 * @cfg {Number} active active page number
1723 * Create a new Pagination
1724 * @param {Object} config The config object
1727 Roo.bootstrap.Pagination = function(config){
1728 Roo.bootstrap.Pagination.superclass.constructor.call(this, config);
1731 Roo.extend(Roo.bootstrap.Pagination, Roo.bootstrap.Component, {
1741 getAutoCreate : function(){
1748 cfg.cls += ' inverse';
1766 var from=this.from>0?this.from:1;
1767 var to=this.to-from<=10?this.to:from+10;
1768 var active=this.active>=from&&this.active<=to?this.active:null;
1769 for (var i=from;i<=to;i++) {
1773 cls: active===i?'active':'',
1814 * @class Roo.bootstrap.Slider
1815 * @extends Roo.bootstrap.Component
1816 * Bootstrap Slider class
1819 * Create a new Slider
1820 * @param {Object} config The config object
1823 Roo.bootstrap.Slider = function(config){
1824 Roo.bootstrap.Slider.superclass.constructor.call(this, config);
1827 Roo.extend(Roo.bootstrap.Slider, Roo.bootstrap.Component, {
1829 getAutoCreate : function(){
1833 cls: 'slider slider-sample1 vertical-handler ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all',
1837 cls: 'ui-slider-handle ui-state-default ui-corner-all'
1855 * @class Roo.bootstrap.Table
1856 * @extends Roo.bootstrap.Component
1857 * Bootstrap Table class
1860 * Create a new Table
1861 * @param {Object} config The config object
1864 Roo.bootstrap.Table = function(config){
1865 Roo.bootstrap.Table.superclass.constructor.call(this, config);
1868 Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component, {
1873 getAutoCreate : function(){
1874 var cfg = Roo.apply({}, Roo.bootstrap.Table.superclass.getAutoCreate.call(this));
1906 * @class Roo.bootstrap.TableCell
1907 * @extends Roo.bootstrap.Component
1908 * Bootstrap TableCell class
1911 * Create a new TableCell
1912 * @param {Object} config The config object
1915 Roo.bootstrap.TableCell = function(config){
1916 Roo.bootstrap.TableCell.superclass.constructor.call(this, config);
1919 Roo.extend(Roo.bootstrap.TableCell, Roo.bootstrap.Component, {
1921 getAutoCreate : function(){
1922 var cfg = Roo.apply({}, Roo.bootstrap.TableCell.superclass.getAutoCreate.call(this));
1949 * @class Roo.bootstrap.TableRow
1950 * @extends Roo.bootstrap.Component
1951 * Bootstrap TableRow class
1954 * Create a new TableRow
1955 * @param {Object} config The config object
1958 Roo.bootstrap.TableRow = function(config){
1959 Roo.bootstrap.TableRow.superclass.constructor.call(this, config);
1962 Roo.extend(Roo.bootstrap.TableRow, Roo.bootstrap.Component, {
1964 getAutoCreate : function(){
1965 var cfg = Roo.apply({}, Roo.bootstrap.TableRow.superclass.getAutoCreate.call(this));
1986 * @class Roo.bootstrap.Form
1987 * @extends Roo.bootstrap.Component
1988 * Bootstrap Form class
1989 * @cfg {String} method GET | POST (default POST)
1990 * @cfg {String} labelAlign top | left (default top)
1994 * @param {Object} config The config object
1998 Roo.bootstrap.Form = function(config){
1999 Roo.bootstrap.Form.superclass.constructor.call(this, config);
2002 * @event clientvalidation
2003 * If the monitorValid config option is true, this event fires repetitively to notify of valid state
2004 * @param {Form} this
2005 * @param {Boolean} valid true if the form has passed client-side validation
2007 clientvalidation: true,
2009 * @event beforeaction
2010 * Fires before any action is performed. Return false to cancel the action.
2011 * @param {Form} this
2012 * @param {Action} action The action to be performed
2016 * @event actionfailed
2017 * Fires when an action fails.
2018 * @param {Form} this
2019 * @param {Action} action The action that failed
2021 actionfailed : true,
2023 * @event actioncomplete
2024 * Fires when an action is completed.
2025 * @param {Form} this
2026 * @param {Action} action The action that completed
2028 actioncomplete : true
2033 Roo.extend(Roo.bootstrap.Form, Roo.bootstrap.Component, {
2036 * @cfg {String} method
2037 * The request method to use (GET or POST) for form actions if one isn't supplied in the action options.
2042 * The URL to use for form actions if one isn't supplied in the action options.
2045 * @cfg {Boolean} fileUpload
2046 * Set to true if this form is a file upload.
2050 * @cfg {Object} baseParams
2051 * Parameters to pass with all requests. e.g. baseParams: {id: '123', foo: 'bar'}.
2055 * @cfg {Number} timeout Timeout for form actions in seconds (default is 30 seconds).
2060 activeAction : null,
2063 * By default wait messages are displayed with Roo.MessageBox.wait. You can target a specific
2064 * element by passing it or its id or mask the form itself by passing in true.
2067 waitMsgTarget : false,
2072 * By default wait messages are displayed with Roo.MessageBox.wait. You can target a specific
2073 * element by passing it or its id or mask the form itself by passing in true.
2077 getAutoCreate : function(){
2081 method : this.method || 'POST',
2082 id : this.id || Roo.id(),
2086 if (this.labelAlign == 'left' ) {
2087 cfg.cls += ' form-horizontal';
2091 initEvents : function()
2093 this.el.on('submit', this.onSubmit, this);
2098 onSubmit : function(e){
2103 * Returns true if client-side validation on the form is successful.
2106 isValid : function(){
2107 var items = this.getItems();
2109 items.each(function(f){
2118 * Returns true if any fields in this form have changed since their original load.
2121 isDirty : function(){
2123 var items = this.getItems();
2124 items.each(function(f){
2134 * Performs a predefined action (submit or load) or custom actions you define on this form.
2135 * @param {String} actionName The name of the action type
2136 * @param {Object} options (optional) The options to pass to the action. All of the config options listed
2137 * below are supported by both the submit and load actions unless otherwise noted (custom actions could also
2138 * accept other config options):
2140 Property Type Description
2141 ---------------- --------------- ----------------------------------------------------------------------------------
2142 url String The url for the action (defaults to the form's url)
2143 method String The form method to use (defaults to the form's method, or POST if not defined)
2144 params String/Object The params to pass (defaults to the form's baseParams, or none if not defined)
2145 clientValidation Boolean Applies to submit only. Pass true to call form.isValid() prior to posting to
2146 validate the form on the client (defaults to false)
2148 * @return {BasicForm} this
2150 doAction : function(action, options){
2151 if(typeof action == 'string'){
2152 action = new Roo.form.Action.ACTION_TYPES[action](this, options);
2154 if(this.fireEvent('beforeaction', this, action) !== false){
2155 this.beforeAction(action);
2156 action.run.defer(100, action);
2162 beforeAction : function(action){
2163 var o = action.options;
2165 // not really supported yet.. ??
2167 //if(this.waitMsgTarget === true){
2168 this.el.mask(o.waitMsg || "Sending", 'x-mask-loading');
2169 //}else if(this.waitMsgTarget){
2170 // this.waitMsgTarget = Roo.get(this.waitMsgTarget);
2171 // this.waitMsgTarget.mask(o.waitMsg || "Sending", 'x-mask-loading');
2173 // Roo.MessageBox.wait(o.waitMsg || "Sending", o.waitTitle || this.waitTitle || 'Please Wait...');
2179 afterAction : function(action, success){
2180 this.activeAction = null;
2181 var o = action.options;
2183 //if(this.waitMsgTarget === true){
2185 //}else if(this.waitMsgTarget){
2186 // this.waitMsgTarget.unmask();
2188 // Roo.MessageBox.updateProgress(1);
2189 // Roo.MessageBox.hide();
2196 Roo.callback(o.success, o.scope, [this, action]);
2197 this.fireEvent('actioncomplete', this, action);
2201 // failure condition..
2202 // we have a scenario where updates need confirming.
2203 // eg. if a locking scenario exists..
2204 // we look for { errors : { needs_confirm : true }} in the response.
2206 (typeof(action.result) != 'undefined') &&
2207 (typeof(action.result.errors) != 'undefined') &&
2208 (typeof(action.result.errors.needs_confirm) != 'undefined')
2211 Roo.log("not supported yet");
2214 Roo.MessageBox.confirm(
2215 "Change requires confirmation",
2216 action.result.errorMsg,
2221 _t.doAction('submit', { params : { _submit_confirmed : 1 } } );
2231 Roo.callback(o.failure, o.scope, [this, action]);
2232 // show an error message if no failed handler is set..
2233 if (!this.hasListener('actionfailed')) {
2234 Roo.log("need to add dialog support");
2236 Roo.MessageBox.alert("Error",
2237 (typeof(action.result) != 'undefined' && typeof(action.result.errorMsg) != 'undefined') ?
2238 action.result.errorMsg :
2239 "Saving Failed, please check your entries or try again"
2244 this.fireEvent('actionfailed', this, action);
2249 * Find a Roo.form.Field in this form by id, dataIndex, name or hiddenName
2250 * @param {String} id The value to search for
2253 findField : function(id){
2254 var items = this.getItems();
2255 var field = items.get(id);
2257 items.each(function(f){
2258 if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
2265 return field || null;
2268 * Mark fields in this form invalid in bulk.
2269 * @param {Array/Object} errors Either an array in the form [{id:'fieldId', msg:'The message'},...] or an object hash of {id: msg, id2: msg2}
2270 * @return {BasicForm} this
2272 markInvalid : function(errors){
2273 if(errors instanceof Array){
2274 for(var i = 0, len = errors.length; i < len; i++){
2275 var fieldError = errors[i];
2276 var f = this.findField(fieldError.id);
2278 f.markInvalid(fieldError.msg);
2284 if(typeof errors[id] != 'function' && (field = this.findField(id))){
2285 field.markInvalid(errors[id]);
2289 //Roo.each(this.childForms || [], function (f) {
2290 // f.markInvalid(errors);
2297 * Set values for fields in this form in bulk.
2298 * @param {Array/Object} values Either an array in the form [{id:'fieldId', value:'foo'},...] or an object hash of {id: value, id2: value2}
2299 * @return {BasicForm} this
2301 setValues : function(values){
2302 if(values instanceof Array){ // array of objects
2303 for(var i = 0, len = values.length; i < len; i++){
2305 var f = this.findField(v.id);
2307 f.setValue(v.value);
2308 if(this.trackResetOnLoad){
2309 f.originalValue = f.getValue();
2313 }else{ // object hash
2316 if(typeof values[id] != 'function' && (field = this.findField(id))){
2318 if (field.setFromData &&
2320 field.displayField &&
2321 // combos' with local stores can
2322 // be queried via setValue()
2323 // to set their value..
2324 (field.store && !field.store.isLocal)
2328 sd[field.valueField] = typeof(values[field.hiddenName]) == 'undefined' ? '' : values[field.hiddenName];
2329 sd[field.displayField] = typeof(values[field.name]) == 'undefined' ? '' : values[field.name];
2330 field.setFromData(sd);
2333 field.setValue(values[id]);
2337 if(this.trackResetOnLoad){
2338 field.originalValue = field.getValue();
2344 //Roo.each(this.childForms || [], function (f) {
2345 // f.setValues(values);
2352 * Returns the fields in this form as an object with key/value pairs. If multiple fields exist with the same name
2353 * they are returned as an array.
2354 * @param {Boolean} asString
2357 getValues : function(asString){
2358 //if (this.childForms) {
2359 // copy values from the child forms
2360 // Roo.each(this.childForms, function (f) {
2361 // this.setValues(f.getValues());
2367 var fs = Roo.lib.Ajax.serializeForm(this.el.dom);
2368 if(asString === true){
2371 return Roo.urlDecode(fs);
2375 * Returns the fields in this form as an object with key/value pairs.
2376 * This differs from getValues as it calls getValue on each child item, rather than using dom data.
2379 getFieldValues : function(with_hidden)
2381 var items = this.getItems();
2383 items.each(function(f){
2387 var v = f.getValue();
2388 if (f.inputType =='radio') {
2389 if (typeof(ret[f.getName()]) == 'undefined') {
2390 ret[f.getName()] = ''; // empty..
2393 if (!f.el.dom.checked) {
2401 // not sure if this supported any more..
2402 if ((typeof(v) == 'object') && f.getRawValue) {
2403 v = f.getRawValue() ; // dates..
2405 // combo boxes where name != hiddenName...
2406 if (f.name != f.getName()) {
2407 ret[f.name] = f.getRawValue();
2409 ret[f.getName()] = v;
2416 * Clears all invalid messages in this form.
2417 * @return {BasicForm} this
2419 clearInvalid : function(){
2420 var items = this.getItems();
2422 items.each(function(f){
2433 * @return {BasicForm} this
2436 var items = this.getItems();
2437 items.each(function(f){
2441 Roo.each(this.childForms || [], function (f) {
2448 getItems : function()
2451 var iter = function(el) {
2467 * Ext JS Library 1.1.1
2468 * Copyright(c) 2006-2007, Ext JS, LLC.
2470 * Originally Released Under LGPL - original licence link has changed is not relivant.
2473 * <script type="text/javascript">
2476 * @class Roo.form.VTypes
2477 * Overridable validation definitions. The validations provided are basic and intended to be easily customizable and extended.
2480 Roo.form.VTypes = function(){
2481 // closure these in so they are only created once.
2482 var alpha = /^[a-zA-Z_]+$/;
2483 var alphanum = /^[a-zA-Z0-9_]+$/;
2484 var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;
2485 var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
2487 // All these messages and functions are configurable
2490 * The function used to validate email addresses
2491 * @param {String} value The email address
2493 'email' : function(v){
2494 return email.test(v);
2497 * The error text to display when the email validation function returns false
2500 'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
2502 * The keystroke filter mask to be applied on email input
2505 'emailMask' : /[a-z0-9_\.\-@]/i,
2508 * The function used to validate URLs
2509 * @param {String} value The URL
2511 'url' : function(v){
2515 * The error text to display when the url validation function returns false
2518 'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
2521 * The function used to validate alpha values
2522 * @param {String} value The value
2524 'alpha' : function(v){
2525 return alpha.test(v);
2528 * The error text to display when the alpha validation function returns false
2531 'alphaText' : 'This field should only contain letters and _',
2533 * The keystroke filter mask to be applied on alpha input
2536 'alphaMask' : /[a-z_]/i,
2539 * The function used to validate alphanumeric values
2540 * @param {String} value The value
2542 'alphanum' : function(v){
2543 return alphanum.test(v);
2546 * The error text to display when the alphanumeric validation function returns false
2549 'alphanumText' : 'This field should only contain letters, numbers and _',
2551 * The keystroke filter mask to be applied on alphanumeric input
2554 'alphanumMask' : /[a-z0-9_]/i
2564 * @class Roo.bootstrap.Input
2565 * @extends Roo.bootstrap.Component
2566 * Bootstrap Input class
2567 * @cfg {Boolean} disabled is it disabled
2568 * @cfg {String} fieldLabel - the label associated
2569 * @cfg {String} inputType button | checkbox | email | file | hidden | image | number | password | radio | range | reset | search | submit | text
2570 * @cfg {String} name name of the input
2571 * @cfg {string} fieldLabel - the label associated
2572 * @cfg {string} inputType - input / file submit ...
2573 * @cfg {string} placeholder - placeholder to put in text.
2574 * @cfg {string} before - input group add on before
2575 * @cfg {string} after - input group add on after
2579 * Create a new Input
2580 * @param {Object} config The config object
2583 Roo.bootstrap.Input = function(config){
2584 Roo.bootstrap.Input.superclass.constructor.call(this, config);
2589 * Fires when this field receives input focus.
2590 * @param {Roo.form.Field} this
2595 * Fires when this field loses input focus.
2596 * @param {Roo.form.Field} this
2601 * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed. You can check
2602 * {@link Roo.EventObject#getKey} to determine which key was pressed.
2603 * @param {Roo.form.Field} this
2604 * @param {Roo.EventObject} e The event object
2609 * Fires just before the field blurs if the field value has changed.
2610 * @param {Roo.form.Field} this
2611 * @param {Mixed} newValue The new value
2612 * @param {Mixed} oldValue The original value
2617 * Fires after the field has been marked as invalid.
2618 * @param {Roo.form.Field} this
2619 * @param {String} msg The validation message
2624 * Fires after the field has been validated with no errors.
2625 * @param {Roo.form.Field} this
2630 * Fires after the key up
2631 * @param {Roo.form.Field} this
2632 * @param {Roo.EventObject} e The event Object
2638 Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component, {
2640 * @cfg {String/Boolean} validationEvent The event that should initiate field validation. Set to false to disable
2641 automatic validation (defaults to "keyup").
2643 validationEvent : "keyup",
2645 * @cfg {Boolean} validateOnBlur Whether the field should validate when it loses focus (defaults to true).
2647 validateOnBlur : true,
2649 * @cfg {Number} validationDelay The length of time in milliseconds after user input begins until validation is initiated (defaults to 250)
2651 validationDelay : 250,
2653 * @cfg {String} focusClass The CSS class to use when the field receives focus (defaults to "x-form-focus")
2655 focusClass : "x-form-focus", // not needed???
2659 * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to "x-form-invalid")
2661 invalidClass : "has-error",
2664 * @cfg {Boolean} selectOnFocus True to automatically select any existing field text when the field receives input focus (defaults to false)
2666 selectOnFocus : false,
2669 * @cfg {String} maskRe An input mask regular expression that will be used to filter keystrokes that don't match (defaults to null)
2673 * @cfg {String} vtype A validation type name as defined in {@link Roo.form.VTypes} (defaults to null)
2678 * @cfg {Boolean} disableKeyFilter True to disable input keystroke filtering (defaults to false)
2680 disableKeyFilter : false,
2683 * @cfg {Boolean} disabled True to disable the field (defaults to false).
2687 * @cfg {Boolean} allowBlank False to validate that the value length > 0 (defaults to true)
2691 * @cfg {String} blankText Error text to display if the allow blank validation fails (defaults to "This field is required")
2693 blankText : "This field is required",
2696 * @cfg {Number} minLength Minimum input field length required (defaults to 0)
2700 * @cfg {Number} maxLength Maximum input field length allowed (defaults to Number.MAX_VALUE)
2702 maxLength : Number.MAX_VALUE,
2704 * @cfg {String} minLengthText Error text to display if the minimum length validation fails (defaults to "The minimum length for this field is {minLength}")
2706 minLengthText : "The minimum length for this field is {0}",
2708 * @cfg {String} maxLengthText Error text to display if the maximum length validation fails (defaults to "The maximum length for this field is {maxLength}")
2710 maxLengthText : "The maximum length for this field is {0}",
2714 * @cfg {Function} validator A custom validation function to be called during field validation (defaults to null).
2715 * If available, this function will be called only after the basic validators all return true, and will be passed the
2716 * current field value and expected to return boolean true if the value is valid or a string error message if invalid.
2720 * @cfg {RegExp} regex A JavaScript RegExp object to be tested against the field value during validation (defaults to null).
2721 * If available, this regex will be evaluated only after the basic validators all return true, and will be passed the
2722 * current field value. If the test fails, the field will be marked invalid using {@link #regexText}.
2726 * @cfg {String} regexText The error text to display if {@link #regex} is used and the test fails during validation (defaults to "")
2744 getAutoCreate : function(){
2746 var parent = this.parent();
2748 var align = parent.labelAlign;
2753 cls: 'form-group' //input-group
2759 type : this.inputType,
2760 cls : 'form-control',
2761 placeholder : this.placeholder || ''
2768 var inputblock = input;
2770 if (this.before || this.after) {
2773 cls : 'input-group',
2777 inputblock.cn.push({
2779 cls : 'input-group-addon',
2783 inputblock.cn.push(input);
2785 inputblock.cn.push({
2787 cls : 'input-group-addon',
2795 Roo.log(this.fieldLabel.length);
2797 if (align ==='left' && this.fieldLabel.length) {
2798 Roo.log("left and has label");
2804 cls : 'col-sm-2 control-label',
2805 html : this.fieldLabel
2816 } else if ( this.fieldLabel.length) {
2822 //cls : 'input-group-addon',
2823 html : this.fieldLabel
2833 Roo.log(" no label && no align");
2846 if (this.disabled) {
2847 input.disabled=true;
2853 * return the real input element.
2855 inputEl: function ()
2857 return this.el.select('input.form-control',true).first();
2859 setDisabled : function(v)
2861 var i = this.inputEl().dom;
2863 i.removeAttribute('disabled');
2867 i.setAttribute('disabled','true');
2869 initEvents : function()
2872 this.inputEl().on("keydown" , this.fireKey, this);
2873 this.inputEl().on("focus", this.onFocus, this);
2874 this.inputEl().on("blur", this.onBlur, this);
2875 this.inputEl().relayEvent('keyup', this);
2877 // reference to original value for reset
2878 this.originalValue = this.getValue();
2879 //Roo.form.TextField.superclass.initEvents.call(this);
2880 if(this.validationEvent == 'keyup'){
2881 this.validationTask = new Roo.util.DelayedTask(this.validate, this);
2882 this.inputEl().on('keyup', this.filterValidation, this);
2884 else if(this.validationEvent !== false){
2885 this.inputEl().on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
2888 if(this.selectOnFocus){
2889 this.on("focus", this.preFocus, this);
2892 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Roo.form.VTypes[this.vtype+'Mask']))){
2893 this.inputEl().on("keypress", this.filterKeys, this);
2896 this.el.on("keyup", this.onKeyUp, this, {buffer:50});
2897 this.el.on("click", this.autoSize, this);
2900 if(this.inputEl().is('input[type=password]') && Roo.isSafari){
2901 this.inputEl().on('keydown', this.SafariOnKeyDown, this);
2905 filterValidation : function(e){
2906 if(!e.isNavKeyPress()){
2907 this.validationTask.delay(this.validationDelay);
2911 * Validates the field value
2912 * @return {Boolean} True if the value is valid, else false
2914 validate : function(){
2915 //if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
2916 if(this.disabled || this.validateValue(this.getRawValue())){
2917 this.clearInvalid();
2925 * Validates a value according to the field's validation rules and marks the field as invalid
2926 * if the validation fails
2927 * @param {Mixed} value The value to validate
2928 * @return {Boolean} True if the value is valid, else false
2930 validateValue : function(value){
2931 if(value.length < 1) { // if it's blank
2932 if(this.allowBlank){
2933 this.clearInvalid();
2936 this.markInvalid(this.blankText);
2940 if(value.length < this.minLength){
2941 this.markInvalid(String.format(this.minLengthText, this.minLength));
2944 if(value.length > this.maxLength){
2945 this.markInvalid(String.format(this.maxLengthText, this.maxLength));
2949 var vt = Roo.form.VTypes;
2950 if(!vt[this.vtype](value, this)){
2951 this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
2955 if(typeof this.validator == "function"){
2956 var msg = this.validator(value);
2958 this.markInvalid(msg);
2962 if(this.regex && !this.regex.test(value)){
2963 this.markInvalid(this.regexText);
2972 fireKey : function(e){
2973 //Roo.log('field ' + e.getKey());
2974 if(e.isNavKeyPress()){
2975 this.fireEvent("specialkey", this, e);
2978 onFocus : function(){
2979 if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
2980 // this.el.addClass(this.focusClass);
2983 this.hasFocus = true;
2984 this.startValue = this.getValue();
2985 this.fireEvent("focus", this);
2989 beforeBlur : Roo.emptyFn,
2993 onBlur : function(){
2995 if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
2996 //this.el.removeClass(this.focusClass);
2998 this.hasFocus = false;
2999 if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
3002 var v = this.getValue();
3003 if(String(v) !== String(this.startValue)){
3004 this.fireEvent('change', this, v, this.startValue);
3006 this.fireEvent("blur", this);
3009 * Returns the normalized data value (undefined or emptyText will be returned as ''). To return the raw value see {@link #getRawValue}.
3010 * @return {Mixed} value The field value
3012 getValue : function(){
3013 var v = this.inputEl().getValue();
3017 * Returns the raw data value which may or may not be a valid, defined value. To return a normalized value see {@link #getValue}.
3018 * @return {Mixed} value The field value
3020 getRawValue : function(){
3021 var v = this.inputEl().getValue();
3026 * Sets a data value into the field and validates it. To set the value directly without validation see {@link #setRawValue}.
3027 * @param {Mixed} value The value to set
3029 setValue : function(v){
3032 this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
3038 processValue : function(value){
3039 if(this.stripCharsRe){
3040 var newValue = value.replace(this.stripCharsRe, '');
3041 if(newValue !== value){
3042 this.setRawValue(newValue);
3049 preFocus : function(){
3051 if(this.selectOnFocus){
3052 this.inputEl().dom.select();
3055 filterKeys : function(e){
3057 if(!Roo.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
3060 var c = e.getCharCode(), cc = String.fromCharCode(c);
3061 if(Roo.isIE && (e.isSpecialKey() || !cc)){
3064 if(!this.maskRe.test(cc)){
3069 * Clear any invalid styles/messages for this field
3071 clearInvalid : function(){
3073 if(!this.el || this.preventMark){ // not rendered
3076 this.el.removeClass(this.invalidClass);
3078 switch(this.msgTarget){
3080 this.el.dom.qtip = '';
3083 this.el.dom.title = '';
3087 Roo.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
3092 this.errorIcon.dom.qtip = '';
3093 this.errorIcon.hide();
3094 this.un('resize', this.alignErrorIcon, this);
3098 var t = Roo.getDom(this.msgTarget);
3100 t.style.display = 'none';
3104 this.fireEvent('valid', this);
3107 * Mark this field as invalid
3108 * @param {String} msg The validation message
3110 markInvalid : function(msg){
3111 if(!this.el || this.preventMark){ // not rendered
3114 this.el.addClass(this.invalidClass);
3116 msg = msg || this.invalidText;
3117 switch(this.msgTarget){
3119 this.el.dom.qtip = msg;
3120 this.el.dom.qclass = 'x-form-invalid-tip';
3121 if(Roo.QuickTips){ // fix for floating editors interacting with DND
3122 Roo.QuickTips.enable();
3126 this.el.dom.title = msg;
3130 var elp = this.el.findParent('.x-form-element', 5, true);
3131 this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
3132 this.errorEl.setWidth(elp.getWidth(true)-20);
3134 this.errorEl.update(msg);
3135 Roo.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
3138 if(!this.errorIcon){
3139 var elp = this.el.findParent('.x-form-element', 5, true);
3140 this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
3142 this.alignErrorIcon();
3143 this.errorIcon.dom.qtip = msg;
3144 this.errorIcon.dom.qclass = 'x-form-invalid-tip';
3145 this.errorIcon.show();
3146 this.on('resize', this.alignErrorIcon, this);
3149 var t = Roo.getDom(this.msgTarget);
3151 t.style.display = this.msgDisplay;
3155 this.fireEvent('invalid', this, msg);
3158 SafariOnKeyDown : function(event)
3160 // this is a workaround for a password hang bug on chrome/ webkit.
3162 var isSelectAll = false;
3164 if(this.inputEl().dom.selectionEnd > 0){
3165 isSelectAll = (this.inputEl().dom.selectionEnd - this.inputEl().dom.selectionStart - this.getValue().length == 0) ? true : false;
3167 if(((event.getKey() == 8 || event.getKey() == 46) && this.getValue().length ==1)){ // backspace and delete key
3168 event.preventDefault();
3173 if(isSelectAll){ // backspace and delete key
3175 event.preventDefault();
3176 // this is very hacky as keydown always get's upper case.
3178 var cc = String.fromCharCode(event.getCharCode());
3179 this.setValue( event.shiftKey ? cc : cc.toLowerCase());