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()
2450 var r=new Roo.util.MixedCollection(false, function(o){
2451 return o.id || (o.id = Roo.id());
2453 var iter = function(el) {
2460 Roo.each(el.items,function(e) {
2479 * Ext JS Library 1.1.1
2480 * Copyright(c) 2006-2007, Ext JS, LLC.
2482 * Originally Released Under LGPL - original licence link has changed is not relivant.
2485 * <script type="text/javascript">
2488 * @class Roo.form.VTypes
2489 * Overridable validation definitions. The validations provided are basic and intended to be easily customizable and extended.
2492 Roo.form.VTypes = function(){
2493 // closure these in so they are only created once.
2494 var alpha = /^[a-zA-Z_]+$/;
2495 var alphanum = /^[a-zA-Z0-9_]+$/;
2496 var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;
2497 var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
2499 // All these messages and functions are configurable
2502 * The function used to validate email addresses
2503 * @param {String} value The email address
2505 'email' : function(v){
2506 return email.test(v);
2509 * The error text to display when the email validation function returns false
2512 'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
2514 * The keystroke filter mask to be applied on email input
2517 'emailMask' : /[a-z0-9_\.\-@]/i,
2520 * The function used to validate URLs
2521 * @param {String} value The URL
2523 'url' : function(v){
2527 * The error text to display when the url validation function returns false
2530 'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
2533 * The function used to validate alpha values
2534 * @param {String} value The value
2536 'alpha' : function(v){
2537 return alpha.test(v);
2540 * The error text to display when the alpha validation function returns false
2543 'alphaText' : 'This field should only contain letters and _',
2545 * The keystroke filter mask to be applied on alpha input
2548 'alphaMask' : /[a-z_]/i,
2551 * The function used to validate alphanumeric values
2552 * @param {String} value The value
2554 'alphanum' : function(v){
2555 return alphanum.test(v);
2558 * The error text to display when the alphanumeric validation function returns false
2561 'alphanumText' : 'This field should only contain letters, numbers and _',
2563 * The keystroke filter mask to be applied on alphanumeric input
2566 'alphanumMask' : /[a-z0-9_]/i
2576 * @class Roo.bootstrap.Input
2577 * @extends Roo.bootstrap.Component
2578 * Bootstrap Input class
2579 * @cfg {Boolean} disabled is it disabled
2580 * @cfg {String} fieldLabel - the label associated
2581 * @cfg {String} inputType button | checkbox | email | file | hidden | image | number | password | radio | range | reset | search | submit | text
2582 * @cfg {String} name name of the input
2583 * @cfg {string} fieldLabel - the label associated
2584 * @cfg {string} inputType - input / file submit ...
2585 * @cfg {string} placeholder - placeholder to put in text.
2586 * @cfg {string} before - input group add on before
2587 * @cfg {string} after - input group add on after
2591 * Create a new Input
2592 * @param {Object} config The config object
2595 Roo.bootstrap.Input = function(config){
2596 Roo.bootstrap.Input.superclass.constructor.call(this, config);
2601 * Fires when this field receives input focus.
2602 * @param {Roo.form.Field} this
2607 * Fires when this field loses input focus.
2608 * @param {Roo.form.Field} this
2613 * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed. You can check
2614 * {@link Roo.EventObject#getKey} to determine which key was pressed.
2615 * @param {Roo.form.Field} this
2616 * @param {Roo.EventObject} e The event object
2621 * Fires just before the field blurs if the field value has changed.
2622 * @param {Roo.form.Field} this
2623 * @param {Mixed} newValue The new value
2624 * @param {Mixed} oldValue The original value
2629 * Fires after the field has been marked as invalid.
2630 * @param {Roo.form.Field} this
2631 * @param {String} msg The validation message
2636 * Fires after the field has been validated with no errors.
2637 * @param {Roo.form.Field} this
2642 * Fires after the key up
2643 * @param {Roo.form.Field} this
2644 * @param {Roo.EventObject} e The event Object
2650 Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component, {
2652 * @cfg {String/Boolean} validationEvent The event that should initiate field validation. Set to false to disable
2653 automatic validation (defaults to "keyup").
2655 validationEvent : "keyup",
2657 * @cfg {Boolean} validateOnBlur Whether the field should validate when it loses focus (defaults to true).
2659 validateOnBlur : true,
2661 * @cfg {Number} validationDelay The length of time in milliseconds after user input begins until validation is initiated (defaults to 250)
2663 validationDelay : 250,
2665 * @cfg {String} focusClass The CSS class to use when the field receives focus (defaults to "x-form-focus")
2667 focusClass : "x-form-focus", // not needed???
2671 * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to "x-form-invalid")
2673 invalidClass : "has-error",
2676 * @cfg {Boolean} selectOnFocus True to automatically select any existing field text when the field receives input focus (defaults to false)
2678 selectOnFocus : false,
2681 * @cfg {String} maskRe An input mask regular expression that will be used to filter keystrokes that don't match (defaults to null)
2685 * @cfg {String} vtype A validation type name as defined in {@link Roo.form.VTypes} (defaults to null)
2690 * @cfg {Boolean} disableKeyFilter True to disable input keystroke filtering (defaults to false)
2692 disableKeyFilter : false,
2695 * @cfg {Boolean} disabled True to disable the field (defaults to false).
2699 * @cfg {Boolean} allowBlank False to validate that the value length > 0 (defaults to true)
2703 * @cfg {String} blankText Error text to display if the allow blank validation fails (defaults to "This field is required")
2705 blankText : "This field is required",
2708 * @cfg {Number} minLength Minimum input field length required (defaults to 0)
2712 * @cfg {Number} maxLength Maximum input field length allowed (defaults to Number.MAX_VALUE)
2714 maxLength : Number.MAX_VALUE,
2716 * @cfg {String} minLengthText Error text to display if the minimum length validation fails (defaults to "The minimum length for this field is {minLength}")
2718 minLengthText : "The minimum length for this field is {0}",
2720 * @cfg {String} maxLengthText Error text to display if the maximum length validation fails (defaults to "The maximum length for this field is {maxLength}")
2722 maxLengthText : "The maximum length for this field is {0}",
2726 * @cfg {Function} validator A custom validation function to be called during field validation (defaults to null).
2727 * If available, this function will be called only after the basic validators all return true, and will be passed the
2728 * current field value and expected to return boolean true if the value is valid or a string error message if invalid.
2732 * @cfg {RegExp} regex A JavaScript RegExp object to be tested against the field value during validation (defaults to null).
2733 * If available, this regex will be evaluated only after the basic validators all return true, and will be passed the
2734 * current field value. If the test fails, the field will be marked invalid using {@link #regexText}.
2738 * @cfg {String} regexText The error text to display if {@link #regex} is used and the test fails during validation (defaults to "")
2756 getAutoCreate : function(){
2758 var parent = this.parent();
2760 var align = parent.labelAlign;
2765 cls: 'form-group' //input-group
2771 type : this.inputType,
2772 cls : 'form-control',
2773 placeholder : this.placeholder || ''
2780 var inputblock = input;
2782 if (this.before || this.after) {
2785 cls : 'input-group',
2789 inputblock.cn.push({
2791 cls : 'input-group-addon',
2795 inputblock.cn.push(input);
2797 inputblock.cn.push({
2799 cls : 'input-group-addon',
2807 Roo.log(this.fieldLabel.length);
2809 if (align ==='left' && this.fieldLabel.length) {
2810 Roo.log("left and has label");
2816 cls : 'col-sm-2 control-label',
2817 html : this.fieldLabel
2828 } else if ( this.fieldLabel.length) {
2834 //cls : 'input-group-addon',
2835 html : this.fieldLabel
2845 Roo.log(" no label && no align");
2858 if (this.disabled) {
2859 input.disabled=true;
2865 * return the real input element.
2867 inputEl: function ()
2869 return this.el.select('input.form-control',true).first();
2871 setDisabled : function(v)
2873 var i = this.inputEl().dom;
2875 i.removeAttribute('disabled');
2879 i.setAttribute('disabled','true');
2881 initEvents : function()
2884 this.inputEl().on("keydown" , this.fireKey, this);
2885 this.inputEl().on("focus", this.onFocus, this);
2886 this.inputEl().on("blur", this.onBlur, this);
2887 this.inputEl().relayEvent('keyup', this);
2889 // reference to original value for reset
2890 this.originalValue = this.getValue();
2891 //Roo.form.TextField.superclass.initEvents.call(this);
2892 if(this.validationEvent == 'keyup'){
2893 this.validationTask = new Roo.util.DelayedTask(this.validate, this);
2894 this.inputEl().on('keyup', this.filterValidation, this);
2896 else if(this.validationEvent !== false){
2897 this.inputEl().on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
2900 if(this.selectOnFocus){
2901 this.on("focus", this.preFocus, this);
2904 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Roo.form.VTypes[this.vtype+'Mask']))){
2905 this.inputEl().on("keypress", this.filterKeys, this);
2908 this.el.on("keyup", this.onKeyUp, this, {buffer:50});
2909 this.el.on("click", this.autoSize, this);
2912 if(this.inputEl().is('input[type=password]') && Roo.isSafari){
2913 this.inputEl().on('keydown', this.SafariOnKeyDown, this);
2917 filterValidation : function(e){
2918 if(!e.isNavKeyPress()){
2919 this.validationTask.delay(this.validationDelay);
2923 * Validates the field value
2924 * @return {Boolean} True if the value is valid, else false
2926 validate : function(){
2927 //if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
2928 if(this.disabled || this.validateValue(this.getRawValue())){
2929 this.clearInvalid();
2937 * Validates a value according to the field's validation rules and marks the field as invalid
2938 * if the validation fails
2939 * @param {Mixed} value The value to validate
2940 * @return {Boolean} True if the value is valid, else false
2942 validateValue : function(value){
2943 if(value.length < 1) { // if it's blank
2944 if(this.allowBlank){
2945 this.clearInvalid();
2948 this.markInvalid(this.blankText);
2952 if(value.length < this.minLength){
2953 this.markInvalid(String.format(this.minLengthText, this.minLength));
2956 if(value.length > this.maxLength){
2957 this.markInvalid(String.format(this.maxLengthText, this.maxLength));
2961 var vt = Roo.form.VTypes;
2962 if(!vt[this.vtype](value, this)){
2963 this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
2967 if(typeof this.validator == "function"){
2968 var msg = this.validator(value);
2970 this.markInvalid(msg);
2974 if(this.regex && !this.regex.test(value)){
2975 this.markInvalid(this.regexText);
2984 fireKey : function(e){
2985 //Roo.log('field ' + e.getKey());
2986 if(e.isNavKeyPress()){
2987 this.fireEvent("specialkey", this, e);
2990 onFocus : function(){
2991 if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
2992 // this.el.addClass(this.focusClass);
2995 this.hasFocus = true;
2996 this.startValue = this.getValue();
2997 this.fireEvent("focus", this);
3001 beforeBlur : Roo.emptyFn,
3005 onBlur : function(){
3007 if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
3008 //this.el.removeClass(this.focusClass);
3010 this.hasFocus = false;
3011 if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
3014 var v = this.getValue();
3015 if(String(v) !== String(this.startValue)){
3016 this.fireEvent('change', this, v, this.startValue);
3018 this.fireEvent("blur", this);
3021 * Returns the normalized data value (undefined or emptyText will be returned as ''). To return the raw value see {@link #getRawValue}.
3022 * @return {Mixed} value The field value
3024 getValue : function(){
3025 var v = this.inputEl().getValue();
3029 * Returns the raw data value which may or may not be a valid, defined value. To return a normalized value see {@link #getValue}.
3030 * @return {Mixed} value The field value
3032 getRawValue : function(){
3033 var v = this.inputEl().getValue();
3038 * Sets a data value into the field and validates it. To set the value directly without validation see {@link #setRawValue}.
3039 * @param {Mixed} value The value to set
3041 setValue : function(v){
3044 this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
3050 processValue : function(value){
3051 if(this.stripCharsRe){
3052 var newValue = value.replace(this.stripCharsRe, '');
3053 if(newValue !== value){
3054 this.setRawValue(newValue);
3061 preFocus : function(){
3063 if(this.selectOnFocus){
3064 this.inputEl().dom.select();
3067 filterKeys : function(e){
3069 if(!Roo.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
3072 var c = e.getCharCode(), cc = String.fromCharCode(c);
3073 if(Roo.isIE && (e.isSpecialKey() || !cc)){
3076 if(!this.maskRe.test(cc)){
3081 * Clear any invalid styles/messages for this field
3083 clearInvalid : function(){
3085 if(!this.el || this.preventMark){ // not rendered
3088 this.el.removeClass(this.invalidClass);
3090 switch(this.msgTarget){
3092 this.el.dom.qtip = '';
3095 this.el.dom.title = '';
3099 Roo.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
3104 this.errorIcon.dom.qtip = '';
3105 this.errorIcon.hide();
3106 this.un('resize', this.alignErrorIcon, this);
3110 var t = Roo.getDom(this.msgTarget);
3112 t.style.display = 'none';
3116 this.fireEvent('valid', this);
3119 * Mark this field as invalid
3120 * @param {String} msg The validation message
3122 markInvalid : function(msg){
3123 if(!this.el || this.preventMark){ // not rendered
3126 this.el.addClass(this.invalidClass);
3128 msg = msg || this.invalidText;
3129 switch(this.msgTarget){
3131 this.el.dom.qtip = msg;
3132 this.el.dom.qclass = 'x-form-invalid-tip';
3133 if(Roo.QuickTips){ // fix for floating editors interacting with DND
3134 Roo.QuickTips.enable();
3138 this.el.dom.title = msg;
3142 var elp = this.el.findParent('.x-form-element', 5, true);
3143 this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
3144 this.errorEl.setWidth(elp.getWidth(true)-20);
3146 this.errorEl.update(msg);
3147 Roo.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
3150 if(!this.errorIcon){
3151 var elp = this.el.findParent('.x-form-element', 5, true);
3152 this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
3154 this.alignErrorIcon();
3155 this.errorIcon.dom.qtip = msg;
3156 this.errorIcon.dom.qclass = 'x-form-invalid-tip';
3157 this.errorIcon.show();
3158 this.on('resize', this.alignErrorIcon, this);
3161 var t = Roo.getDom(this.msgTarget);
3163 t.style.display = this.msgDisplay;
3167 this.fireEvent('invalid', this, msg);
3170 SafariOnKeyDown : function(event)
3172 // this is a workaround for a password hang bug on chrome/ webkit.
3174 var isSelectAll = false;
3176 if(this.inputEl().dom.selectionEnd > 0){
3177 isSelectAll = (this.inputEl().dom.selectionEnd - this.inputEl().dom.selectionStart - this.getValue().length == 0) ? true : false;
3179 if(((event.getKey() == 8 || event.getKey() == 46) && this.getValue().length ==1)){ // backspace and delete key
3180 event.preventDefault();
3185 if(isSelectAll){ // backspace and delete key
3187 event.preventDefault();
3188 // this is very hacky as keydown always get's upper case.
3190 var cc = String.fromCharCode(event.getCharCode());
3191 this.setValue( event.shiftKey ? cc : cc.toLowerCase());