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)));
143 if (!tree.items || !tree.items.length) {
147 var items = tree.items;
150 //Roo.log(items.length);
152 for(var i =0;i < items.length;i++) {
153 nitems.push(cn.addxtype(Roo.apply({}, items[i])));
173 Roo.bootstrap.Body = function(config){
174 Roo.bootstrap.Body.superclass.constructor.call(this, config);
175 this.el = Roo.get(document.body);
178 Roo.extend(Roo.bootstrap.Body, Roo.bootstrap.Component, {
183 onRender : function(ct, position){
186 //this.el.addClass([this.fieldClass, this.cls]);
204 * @class Roo.bootstrap.ButtonGroup
205 * @extends Roo.bootstrap.Component
206 * Bootstrap ButtonGroup class
207 * @cfg {String} size lg | sm | xs (default empty normal)
208 * @cfg {String} align vertical | justified (default none)
209 * @cfg {String} direction up | down (default down)
210 * @cfg {Boolean} toolbar false | true
211 * @cfg {Boolean} btn true | false
216 * @param {Object} config The config object
219 Roo.bootstrap.ButtonGroup = function(config){
220 Roo.bootstrap.ButtonGroup.superclass.constructor.call(this, config);
223 Roo.extend(Roo.bootstrap.ButtonGroup, Roo.bootstrap.Component, {
231 getAutoCreate : function(){
237 cfg.html = this.html || cfg.html;
248 if (['vertical','justified'].indexOf(this.align)!==-1) {
249 cfg.cls = 'btn-group-' + this.align;
251 if (this.align == 'justified') {
252 console.log(this.items);
256 if (['lg','sm','xs'].indexOf(this.size)!==-1) {
257 cfg.cls += ' btn-group-' + this.size;
260 if (this.direction == 'up') {
261 cfg.cls += ' dropup' ;
277 * @class Roo.bootstrap.Button
278 * @extends Roo.bootstrap.Component
279 * Bootstrap Button class
280 * @cfg {String} html The button content
281 * @cfg {String} weight default (or empty) | primary | success | info | warning | danger
282 * @cfg {String} size empty | lg | sm | xs
283 * @cfg {String} tag empty | a | input | submit
284 * @cfg {String} href empty or href
285 * @cfg {Boolean} disabled false | true
286 * @cfg {Boolean} isClose false | true
287 * @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
288 * @cfg {String} badge text for badge
289 * @cfg {String} theme default (or empty) | glow
290 * @cfg {Boolean} inverse false | true
291 * @cfg {Boolean} toggle false | true
292 * @cfg {String} ontext text for on toggle state
293 * @cfg {String} offtext text for off toggle state
294 * @cfg {Boolean} defaulton true | false
297 * Create a new button
298 * @param {Object} config The config object
302 Roo.bootstrap.Button = function(config){
303 Roo.bootstrap.Button.superclass.constructor.call(this, config);
308 * The raw click event for the entire grid.
309 * @param {Roo.EventObject} e
315 Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, {
334 getAutoCreate : function(){
342 if (['a', 'button', 'input', 'submit'].indexOf(this.tag) < 0) {
343 throw "Invalid value for tag: " + this.tag + ". must be a, button, input or submit.";
348 cfg.html = this.html || cfg.html;
350 if (this.toggle===true) {
353 cls: 'slider-frame roo-button',
358 'data-off-text':'OFF',
359 cls: 'slider-button',
365 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
366 cfg.cls += ' '+this.weight;
375 cfg["aria-hidden"] = true;
377 cfg.html = "×";
383 if (this.theme==='default') {
384 cfg.cls = 'btn roo-button';
386 if (this.parentType != 'Navbar') {
387 this.weight = this.weight.length ? this.weight : 'default';
389 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
391 cfg.cls += ' btn-' + this.weight;
393 } else if (this.theme==='glow') {
396 cfg.cls = 'btn-glow roo-button';
398 if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
400 cfg.cls += ' ' + this.weight;
406 this.cls += ' inverse';
411 cfg.cls += ' active';
414 cfg.cls += this.size.length ? (' btn-' + this.size) : '';
416 //gsRoo.log(this.parentType);
417 if (this.parentType === 'Navbar') {
425 href : this.href || '#'
428 cfg.cn[0].html = this.html + ' <span class="caret"></span>';
429 cfg.cls += ' dropdown';
434 } else if (this.menu) {
436 cfg.cls += ' dropdown test';
442 cfg.disabled = 'disabled';
446 Roo.log('changing to ul' );
448 this.glyphicon = 'caret';
451 if (this.glyphicon) {
452 cfg.html = ' ' + cfg.html;
457 cls: 'glyphicon glyphicon-' + this.glyphicon
467 cfg.cls='btn roo-button';
483 if (cfg.tag !== 'a' && this.href !== '') {
484 throw "Tag must be a to set href.";
485 } else if (this.href.length > 0) {
486 cfg.href = this.href;
491 initEvents: function() {
492 // Roo.log('init events?');
493 // Roo.log(this.el.dom);
494 if (this.el.hasClass('roo-button')) {
495 this.el.on('click', this.onClick, this);
497 this.el.select('.roo-button').on('click', this.onClick, this);
503 onClick : function(e)
505 Roo.log('button on click ');
507 this.fireEvent('click', this, e);
521 * @class Roo.bootstrap.Column
522 * @extends Roo.bootstrap.Component
523 * Bootstrap Column class
524 * @cfg {Number} xs colspan out of 12 for mobile-sized screens
525 * @cfg {Number} sm colspan out of 12 for tablet-sized screens
526 * @cfg {Number} md colspan out of 12 for computer-sized screens
527 * @cfg {Number} lg colspan out of 12 for large computer-sized screens
528 * @cfg {String} html content of column.
531 * Create a new Column
532 * @param {Object} config The config object
535 Roo.bootstrap.Column = function(config){
536 Roo.bootstrap.Column.superclass.constructor.call(this, config);
539 Roo.extend(Roo.bootstrap.Column, Roo.bootstrap.Component, {
548 getAutoCreate : function(){
549 var cfg = Roo.apply({}, Roo.bootstrap.Column.superclass.getAutoCreate.call(this));
557 ['xs','sm','md','lg'].map(function(size){
558 if (settings[size]) {
559 cfg.cls += ' col-' + size + '-' + settings[size];
562 if (this.html.length) {
563 cfg.html = this.html;
582 * @class Roo.bootstrap.Container
583 * @extends Roo.bootstrap.Component
584 * Bootstrap Container class
585 * @cfg {Boolean} jumbotron is it a jumbotron element
586 * @cfg {String} html content of element
587 * @cfg {String} well (lg|sm|md) a well, large, small or medium.
588 * @cfg {String} panel (primary|success|info|warning|danger) render as a panel.
589 * @cfg {String} header content of header (for panel)
590 * @cfg {String} footer content of footer (for panel)
591 * @cfg {String} sticky (footer|wrap|push) block to use as footer or body- needs css-bootstrap/sticky-footer.css
594 * Create a new Container
595 * @param {Object} config The config object
598 Roo.bootstrap.Container = function(config){
599 Roo.bootstrap.Container.superclass.constructor.call(this, config);
602 Roo.extend(Roo.bootstrap.Container, Roo.bootstrap.Component, {
612 getChildContainer : function() {
613 if (this.panel.length) {
614 return this.el.select('.panel-body',true).first();
621 getAutoCreate : function(){
627 if (this.jumbotron) {
628 cfg.cls = 'jumbotron';
631 cfg.cls = this.cls + '';
634 if (this.sticky.length) {
635 var bd = Roo.get(document.body);
636 if (!bd.hasClass('bootstrap-sticky')) {
637 bd.addClass('bootstrap-sticky');
638 Roo.select('html',true).setStyle('height', '100%');
641 cfg.cls += 'bootstrap-sticky-' + this.sticky;
645 if (this.well.length) {
649 cfg.cls +=' well well-' +this.well;
659 if (this.panel.length) {
660 cfg.cls += 'panel panel-' + this.panel;
662 if (this.header.length) {
665 cls : 'panel-heading',
681 if (this.footer.length) {
683 cls : 'panel-footer',
691 body.html = this.html || cfg.html;
693 if (!cfg.cls.length) {
694 cfg.cls = 'container';
711 * @class Roo.bootstrap.Img
712 * @extends Roo.bootstrap.Component
713 * Bootstrap Img class
714 * @cfg {Boolean} imgResponsive false | true
715 * @cfg {String} border rounded | circle | thumbnail
716 * @cfg {String} src image source
717 * @cfg {String} alt image alternative text
721 * @param {Object} config The config object
724 Roo.bootstrap.Img = function(config){
725 Roo.bootstrap.Img.superclass.constructor.call(this, config);
728 Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component, {
734 getAutoCreate : function(){
738 cls: 'img-responsive',
742 cfg.html = this.html || cfg.html;
744 cfg.src = this.src || cfg.src;
746 if (['rounded','circle','thumbnail'].indexOf(this.border)>-1) {
747 cfg.cls += ' img-' + this.border;
767 * @class Roo.bootstrap.Header
768 * @extends Roo.bootstrap.Component
769 * Bootstrap Header class
770 * @cfg {String} html content of header
771 * @cfg {Number} level (1|2|3|4|5|6) default 1
774 * Create a new Header
775 * @param {Object} config The config object
779 Roo.bootstrap.Header = function(config){
780 Roo.bootstrap.Header.superclass.constructor.call(this, config);
783 Roo.extend(Roo.bootstrap.Header, Roo.bootstrap.Component, {
791 getAutoCreate : function(){
794 tag: 'h' + (1 *this.level),
795 html: this.html || 'fill in html'
813 * @class Roo.bootstrap.Menu
814 * @extends Roo.bootstrap.Component
815 * Bootstrap Menu class - container for MenuItems
816 * @cfg {String} type type of menu
820 * @param {Object} config The config object
824 Roo.bootstrap.Menu = function(config){
825 Roo.bootstrap.Menu.superclass.constructor.call(this, config);
828 Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component, {
836 getChildContainer : function() {
840 getAutoCreate : function(){
842 //if (['right'].indexOf(this.align)!==-1) {
843 // cfg.cn[1].cls += ' pull-right'
847 cls : 'dropdown-menu'
851 if (this.type==='submenu') {
852 cfg.cls='submenu active'
857 initEvents : function() {
858 // Roo.log("ADD event");
859 // Roo.log(this.triggerEl.dom);
860 this.triggerEl.on('click', this.toggle, this);
861 this.triggerEl.addClass('dropdown-toggle');
866 //Roo.log(e.getTarget());
867 // Roo.log(this.triggerEl.dom);
868 if (Roo.get(e.getTarget()).findParent('.dropdown-menu')) {
871 var isActive = this.triggerEl.hasClass('open');
872 // if disabled.. ingore
874 //if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
875 // if mobile we use a backdrop because click events don't delegate
876 // $('<div class="dropdown-backdrop"/>').insertAfter($(this)).on('click', clearMenus)
879 //var relatedTarget = { relatedTarget: this }
880 //$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
882 //if (e.isDefaultPrevented()) return;
884 this.triggerEl[isActive ? 'removeClass' : 'addClass']('open');
886 // .trigger('shown.bs.dropdown', relatedTarget)
888 this.triggerEl.focus();
894 clearMenus : function()
896 //$(backdrop).remove()
897 Roo.select('.dropdown-toggle',true).each(function(aa) {
898 if (!aa.hasClass('open')) {
902 aa.removeClass('open');
903 //var parent = getParent($(this))
904 //var relatedTarget = { relatedTarget: this }
906 //$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
907 //if (e.isDefaultPrevented()) return
908 //$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget)
926 * @class Roo.bootstrap.MenuItem
927 * @extends Roo.bootstrap.Component
928 * Bootstrap MenuItem class
929 * @cfg {String} html the menu label
930 * @cfg {String} href the link
934 * Create a new MenuItem
935 * @param {Object} config The config object
939 Roo.bootstrap.MenuItem = function(config){
940 Roo.bootstrap.MenuItem.superclass.constructor.call(this, config);
943 Roo.extend(Roo.bootstrap.MenuItem, Roo.bootstrap.Component, {
948 getAutoCreate : function(){
960 cfg.cn[0].href = this.href || cfg.cn[0].href ;
961 cfg.cn[0].html = this.html || cfg.cn[0].html ;
978 * @class Roo.bootstrap.MenuSeparator
979 * @extends Roo.bootstrap.Component
980 * Bootstrap MenuSeparator class
983 * Create a new MenuItem
984 * @param {Object} config The config object
988 Roo.bootstrap.MenuSeparator = function(config){
989 Roo.bootstrap.MenuSeparator.superclass.constructor.call(this, config);
992 Roo.extend(Roo.bootstrap.MenuSeparator, Roo.bootstrap.Component, {
994 getAutoCreate : function(){
1009 <div class="modal fade">
1010 <div class="modal-dialog">
1011 <div class="modal-content">
1012 <div class="modal-header">
1013 <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
1014 <h4 class="modal-title">Modal title</h4>
1016 <div class="modal-body">
1017 <p>One fine body…</p>
1019 <div class="modal-footer">
1020 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1021 <button type="button" class="btn btn-primary">Save changes</button>
1023 </div><!-- /.modal-content -->
1024 </div><!-- /.modal-dialog -->
1025 </div><!-- /.modal -->
1035 * @class Roo.bootstrap.Modal
1036 * @extends Roo.bootstrap.Component
1037 * Bootstrap Modal class
1038 * @cfg {String} title Title of dialog
1039 * @cfg {Array} buttons Array of buttons or standard button set..
1042 * Create a new Modal Dialog
1043 * @param {Object} config The config object
1046 Roo.bootstrap.Modal = function(config){
1047 Roo.bootstrap.Modal.superclass.constructor.call(this, config);
1052 * The raw click event for the entire grid.
1053 * @param {Roo.EventObject} e
1059 Roo.extend(Roo.bootstrap.Modal, Roo.bootstrap.Component, {
1061 title : 'test dialog',
1065 onRender : function(ct, position)
1067 Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
1069 var cfg = Roo.apply({}, this.getAutoCreate());
1072 // cfg.name = typeof(this.name) == 'undefined' ? this.id : this.name;
1074 //if (!cfg.name.length) {
1078 cfg.cls += ' ' + this.cls;
1081 cfg.style = this.style;
1083 this.el = Roo.get(document.body).createChild(cfg, position);
1085 //var type = this.el.dom.type;
1087 if(this.tabIndex !== undefined){
1088 this.el.dom.setAttribute('tabIndex', this.tabIndex);
1093 this.maskEl = Roo.DomHelper.append(document.body, {tag: "div", cls:"x-dlg-mask"}, true);
1094 this.maskEl.enableDisplayMode("block");
1096 //this.el.addClass("x-dlg-modal");
1100 Roo.each(this.buttons, function(bb) {
1101 b = Roo.apply({}, bb);
1102 b.xns = b.xns || Roo.bootstrap;
1103 b.xtype = b.xtype || 'Button';
1104 if (typeof(b.listeners) == 'undefined') {
1105 b.listeners = { click : this.onButtonClick };
1108 var btn = Roo.factory(b);
1110 btn.onRender(this.el.select('.modal-footer').first());
1118 //this.el.addClass([this.fieldClass, this.cls]);
1121 getAutoCreate : function(){
1126 html : this.html || ''
1134 cls: "modal-dialog",
1137 cls : "modal-content",
1140 cls : 'modal-header',
1149 cls : 'modal-title',
1157 cls : 'modal-footer'
1173 getChildContainer : function() {
1175 return this.el.select('.modal-body',true).first();
1178 getButtonContainer : function() {
1179 return this.el.select('.modal-footer',true).first();
1182 initEvents : function()
1184 this.el.select('.modal-header .close').on('click', this.hide, this);
1187 if (!this.rendered) {
1191 this.el.addClass('on');
1192 this.el.removeClass('fade');
1193 this.el.setStyle('display', 'block');
1194 Roo.get(document.body).addClass("x-body-masked");
1195 this.maskEl.setSize(Roo.lib.Dom.getViewWidth(true), Roo.lib.Dom.getViewHeight(true));
1197 this.el.setStyle('zIndex', '10001');
1204 this.el.removeClass('on');
1205 this.el.addClass('fade');
1206 this.el.setStyle('display', 'none');
1208 onButtonClick: function(btn,e)
1211 this.fireEvent('btnclick', btn.name, e);
1216 Roo.apply(Roo.bootstrap.Modal, {
1218 * Button config that displays a single OK button
1227 * Button config that displays Yes and No buttons
1243 * Button config that displays OK and Cancel buttons
1258 * Button config that displays Yes, No and Cancel buttons
1286 * @class Roo.bootstrap.Navbar
1287 * @extends Roo.bootstrap.Component
1288 * Bootstrap Navbar class
1289 * @cfg {Boolean} sidebar has side bar
1290 * @cfg {Boolean} bar is a bar?
1291 * @cfg {String} position (fixed-top|fixed-bottom|static-top) position
1292 * @cfg {String} brand what is brand
1293 * @cfg {Boolean} inverse is inverted color
1294 * @cfg {String} type (nav | pills | tabs)
1295 * @cfg {Boolean} arrangement stacked | justified
1296 * @cfg {String} align (left | right) alignment
1300 * Create a new Navbar
1301 * @param {Object} config The config object
1305 Roo.bootstrap.Navbar = function(config){
1306 Roo.bootstrap.Navbar.superclass.constructor.call(this, config);
1309 Roo.extend(Roo.bootstrap.Navbar, Roo.bootstrap.Component, {
1321 getAutoCreate : function(){
1326 if (this.sidebar === true) {
1334 if (this.bar === true) {
1342 cls: 'navbar-header',
1347 cls: 'navbar-toggle',
1348 'data-toggle': 'collapse',
1353 html: 'Toggle navigation'
1373 cls: 'collapse navbar-collapse'
1378 cfg.cls += this.inverse ? ' navbar-inverse' : ' navbar-default';
1380 if (['fixed-top','fixed-bottom','static-top'].indexOf(this.position)>-1) {
1381 cfg.cls += ' navbar-' + this.position;
1382 cfg.tag = this.position == 'fixed-bottom' ? 'footer' : 'header';
1385 if (this.brand !== '') {
1389 cls: 'navbar-brand',
1398 } else if (this.bar === false) {
1401 Roo.log('Property \'bar\' in of Navbar must be either true or false')
1411 if (['tabs','pills'].indexOf(this.type)!==-1) {
1412 cfg.cn[0].cls += ' nav-' + this.type
1414 if (this.type!=='nav') {
1415 Roo.log('nav type must be nav/tabs/pills')
1417 cfg.cn[0].cls += ' navbar-nav'
1420 if (['stacked','justified'].indexOf(this.arrangement)!==-1) {
1421 cfg.cn[0].cls += ' nav-' + this.arrangement;
1424 if (this.align === 'right') {
1425 cfg.cn[0].cls += ' navbar-right';
1428 cfg.cls += ' navbar-inverse';
1436 getChildContainer : function() {
1437 if (this.bar === true) {
1438 return this.el.select('.collapse',true).first();
1456 * @class Roo.bootstrap.NavGroup
1457 * @extends Roo.bootstrap.Component
1458 * Bootstrap NavGroup class
1459 * @cfg {String} align left | right
1460 * @cfg {Boolean} inverse false | true
1463 * Create a new nav group
1464 * @param {Object} config The config object
1467 Roo.bootstrap.NavGroup = function(config){
1468 Roo.bootstrap.NavGroup.superclass.constructor.call(this, config);
1471 Roo.extend(Roo.bootstrap.NavGroup, Roo.bootstrap.Component, {
1477 getAutoCreate : function(){
1478 var cfg = Roo.apply({}, Roo.bootstrap.NavGroup.superclass.getAutoCreate.call(this));
1482 cls: 'nav navbar-nav'
1485 if (this.parent().sidebar === true) {
1488 cls: 'dashboard-menu'
1494 if (this.form === true) {
1500 if (this.align === 'right') {
1501 cfg.cls += ' navbar-right';
1503 cfg.cls += ' navbar-left';
1508 if (this.align === 'right') {
1509 cfg.cls += ' navbar-right';
1513 cfg.cls += ' navbar-inverse';
1532 * @class Roo.bootstrap.Navbar.Button
1533 * @extends Roo.bootstrap.Component
1534 * Bootstrap Navbar.Button class
1535 * @cfg {String} href link to
1536 * @cfg {String} html content of button
1539 * Create a new Navbar Button
1540 * @param {Object} config The config object
1544 Roo.bootstrap.Navbar.Button = function(config){
1545 Roo.bootstrap.Navbar.Button.superclass.constructor.call(this, config);
1548 Roo.extend(Roo.bootstrap.Navbar.Button, Roo.bootstrap.Component, {
1559 getAutoCreate : function(){
1569 html : this.html || ''
1593 * @class Roo.bootstrap.Navbar.Item
1594 * @extends Roo.bootstrap.Component
1595 * Bootstrap Navbar.Button class
1596 * @cfg {String} href link to
1597 * @cfg {String} html content of button
1598 * @cfg {String} badge text inside badge
1599 * @cfg {String} glyphicon name of glyphicon
1602 * Create a new Navbar Button
1603 * @param {Object} config The config object
1605 Roo.bootstrap.Navbar.Item = function(config){
1606 Roo.bootstrap.Navbar.Item.superclass.constructor.call(this, config);
1609 Roo.extend(Roo.bootstrap.Navbar.Item, Roo.bootstrap.Component, {
1617 getAutoCreate : function(){
1619 var cfg = Roo.apply({}, Roo.bootstrap.Navbar.Item.superclass.getAutoCreate.call(this));
1621 if (this.parent().parent().sidebar === true) {
1634 cfg.cn[0].html = this.html;
1638 this.cls += ' active';
1642 cfg.cn[0].cls += ' dropdown-toggle';
1643 cfg.cn[0].html = (cfg.cn[0].html || this.html) + '<span class="glyphicon glyphicon-chevron-down"></span>';
1647 cfg.cn[0].tag = 'a',
1648 cfg.cn[0].href = this.href;
1651 if (this.glyphicon) {
1652 cfg.cn[0].html = '<i class="glyphicon glyphicon-'+this.glyphicon+'"></i><span>' + cfg.cn[0].html || this.html + '</span>'
1668 if (this.glyphicon) {
1669 if(cfg.html){cfg.html = ' ' + this.html};
1673 cls: 'glyphicon glyphicon-' + this.glyphicon
1678 cfg.cn[0].html = this.html || cfg.cn[0].html ;
1682 cfg.cn[0].html += " <span class='caret'></span>";
1683 //}else if (!this.href) {
1684 // cfg.cn[0].tag='p';
1685 // cfg.cn[0].cls='navbar-text';
1688 cfg.cn[0].href=this.href||'#';
1689 cfg.cn[0].html=this.html;
1692 if (this.badge !== '') {
1695 cfg.cn[0].html + ' ',
1708 initEvents: function() {
1709 // Roo.log('init events?');
1710 // Roo.log(this.el.dom);
1711 this.el.select('a',true).on('click',
1713 this.fireEvent('click', this);
1730 * @class Roo.bootstrap.Row
1731 * @extends Roo.bootstrap.Component
1732 * Bootstrap Row class (contains columns...)
1736 * @param {Object} config The config object
1739 Roo.bootstrap.Row = function(config){
1740 Roo.bootstrap.Row.superclass.constructor.call(this, config);
1743 Roo.extend(Roo.bootstrap.Row, Roo.bootstrap.Component, {
1762 * @class Roo.bootstrap.Element
1763 * @extends Roo.bootstrap.Component
1764 * Bootstrap Element class
1765 * @cfg {String} html contents of the element
1766 * @cfg {String} tag tag of the element
1767 * @cfg {String} cls class of the element
1770 * Create a new Element
1771 * @param {Object} config The config object
1774 Roo.bootstrap.Element = function(config){
1775 Roo.bootstrap.Element.superclass.constructor.call(this, config);
1778 Roo.extend(Roo.bootstrap.Element, Roo.bootstrap.Component, {
1786 getAutoCreate : function(){
1787 var cfg = Roo.apply({}, Roo.bootstrap.Element.superclass.getAutoCreate.call(this));
1810 * @class Roo.bootstrap.Pagination
1811 * @extends Roo.bootstrap.Component
1812 * Bootstrap Pagination class
1813 * @cfg {String} size xs | sm | md | lg
1814 * @cfg {Boolean} inverse false | true
1815 * @cfg {Number} from pagination starting number
1816 * @cfg {Number} to pagination ending number
1817 * @cfg {String} align empty or left | right
1818 * @cfg {Number} active active page number
1821 * Create a new Pagination
1822 * @param {Object} config The config object
1825 Roo.bootstrap.Pagination = function(config){
1826 Roo.bootstrap.Pagination.superclass.constructor.call(this, config);
1829 Roo.extend(Roo.bootstrap.Pagination, Roo.bootstrap.Component, {
1839 getAutoCreate : function(){
1846 cfg.cls += ' inverse';
1864 var from=this.from>0?this.from:1;
1865 var to=this.to-from<=10?this.to:from+10;
1866 var active=this.active>=from&&this.active<=to?this.active:null;
1867 for (var i=from;i<=to;i++) {
1871 cls: active===i?'active':'',
1912 * @class Roo.bootstrap.Slider
1913 * @extends Roo.bootstrap.Component
1914 * Bootstrap Slider class
1917 * Create a new Slider
1918 * @param {Object} config The config object
1921 Roo.bootstrap.Slider = function(config){
1922 Roo.bootstrap.Slider.superclass.constructor.call(this, config);
1925 Roo.extend(Roo.bootstrap.Slider, Roo.bootstrap.Component, {
1927 getAutoCreate : function(){
1931 cls: 'slider slider-sample1 vertical-handler ui-slider ui-slider-horizontal ui-widget ui-widget-content ui-corner-all',
1935 cls: 'ui-slider-handle ui-state-default ui-corner-all'
1953 * @class Roo.bootstrap.Table
1954 * @extends Roo.bootstrap.Component
1955 * Bootstrap Table class
1958 * Create a new Table
1959 * @param {Object} config The config object
1962 Roo.bootstrap.Table = function(config){
1963 Roo.bootstrap.Table.superclass.constructor.call(this, config);
1966 Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component, {
1971 getAutoCreate : function(){
1972 var cfg = Roo.apply({}, Roo.bootstrap.Table.superclass.getAutoCreate.call(this));
2004 * @class Roo.bootstrap.TableCell
2005 * @extends Roo.bootstrap.Component
2006 * Bootstrap TableCell class
2009 * Create a new TableCell
2010 * @param {Object} config The config object
2013 Roo.bootstrap.TableCell = function(config){
2014 Roo.bootstrap.TableCell.superclass.constructor.call(this, config);
2017 Roo.extend(Roo.bootstrap.TableCell, Roo.bootstrap.Component, {
2019 getAutoCreate : function(){
2020 var cfg = Roo.apply({}, Roo.bootstrap.TableCell.superclass.getAutoCreate.call(this));
2047 * @class Roo.bootstrap.TableRow
2048 * @extends Roo.bootstrap.Component
2049 * Bootstrap TableRow class
2052 * Create a new TableRow
2053 * @param {Object} config The config object
2056 Roo.bootstrap.TableRow = function(config){
2057 Roo.bootstrap.TableRow.superclass.constructor.call(this, config);
2060 Roo.extend(Roo.bootstrap.TableRow, Roo.bootstrap.Component, {
2062 getAutoCreate : function(){
2063 var cfg = Roo.apply({}, Roo.bootstrap.TableRow.superclass.getAutoCreate.call(this));
2078 * Ext JS Library 1.1.1
2079 * Copyright(c) 2006-2007, Ext JS, LLC.
2081 * Originally Released Under LGPL - original licence link has changed is not relivant.
2084 * <script type="text/javascript">
2087 // as we use this in bootstrap.
2088 Roo.namespace('Roo.form');
2090 * @class Roo.form.Action
2091 * Internal Class used to handle form actions
2093 * @param {Roo.form.BasicForm} el The form element or its id
2094 * @param {Object} config Configuration options
2099 // define the action interface
2100 Roo.form.Action = function(form, options){
2102 this.options = options || {};
2105 * Client Validation Failed
2108 Roo.form.Action.CLIENT_INVALID = 'client';
2110 * Server Validation Failed
2113 Roo.form.Action.SERVER_INVALID = 'server';
2115 * Connect to Server Failed
2118 Roo.form.Action.CONNECT_FAILURE = 'connect';
2120 * Reading Data from Server Failed
2123 Roo.form.Action.LOAD_FAILURE = 'load';
2125 Roo.form.Action.prototype = {
2127 failureType : undefined,
2128 response : undefined,
2132 run : function(options){
2137 success : function(response){
2142 handleResponse : function(response){
2146 // default connection failure
2147 failure : function(response){
2149 this.response = response;
2150 this.failureType = Roo.form.Action.CONNECT_FAILURE;
2151 this.form.afterAction(this, false);
2154 processResponse : function(response){
2155 this.response = response;
2156 if(!response.responseText){
2159 this.result = this.handleResponse(response);
2163 // utility functions used internally
2164 getUrl : function(appendParams){
2165 var url = this.options.url || this.form.url || this.form.el.dom.action;
2167 var p = this.getParams();
2169 url += (url.indexOf('?') != -1 ? '&' : '?') + p;
2175 getMethod : function(){
2176 return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
2179 getParams : function(){
2180 var bp = this.form.baseParams;
2181 var p = this.options.params;
2183 if(typeof p == "object"){
2184 p = Roo.urlEncode(Roo.applyIf(p, bp));
2185 }else if(typeof p == 'string' && bp){
2186 p += '&' + Roo.urlEncode(bp);
2189 p = Roo.urlEncode(bp);
2194 createCallback : function(){
2196 success: this.success,
2197 failure: this.failure,
2199 timeout: (this.form.timeout*1000),
2200 upload: this.form.fileUpload ? this.success : undefined
2205 Roo.form.Action.Submit = function(form, options){
2206 Roo.form.Action.Submit.superclass.constructor.call(this, form, options);
2209 Roo.extend(Roo.form.Action.Submit, Roo.form.Action, {
2212 haveProgress : false,
2213 uploadComplete : false,
2215 // uploadProgress indicator.
2216 uploadProgress : function()
2218 if (!this.form.progressUrl) {
2222 if (!this.haveProgress) {
2223 Roo.MessageBox.progress("Uploading", "Uploading");
2225 if (this.uploadComplete) {
2226 Roo.MessageBox.hide();
2230 this.haveProgress = true;
2232 var uid = this.form.findField('UPLOAD_IDENTIFIER').getValue();
2234 var c = new Roo.data.Connection();
2236 url : this.form.progressUrl,
2241 success : function(req){
2242 //console.log(data);
2246 rdata = Roo.decode(req.responseText)
2248 Roo.log("Invalid data from server..");
2252 if (!rdata || !rdata.success) {
2254 Roo.MessageBox.alert(Roo.encode(rdata));
2257 var data = rdata.data;
2259 if (this.uploadComplete) {
2260 Roo.MessageBox.hide();
2265 Roo.MessageBox.updateProgress(data.bytes_uploaded/data.bytes_total,
2266 Math.floor((data.bytes_total - data.bytes_uploaded)/1000) + 'k remaining'
2269 this.uploadProgress.defer(2000,this);
2272 failure: function(data) {
2273 Roo.log('progress url failed ');
2284 // run get Values on the form, so it syncs any secondary forms.
2285 this.form.getValues();
2287 var o = this.options;
2288 var method = this.getMethod();
2289 var isPost = method == 'POST';
2290 if(o.clientValidation === false || this.form.isValid()){
2292 if (this.form.progressUrl) {
2293 this.form.findField('UPLOAD_IDENTIFIER').setValue(
2294 (new Date() * 1) + '' + Math.random());
2299 Roo.Ajax.request(Roo.apply(this.createCallback(), {
2300 form:this.form.el.dom,
2301 url:this.getUrl(!isPost),
2303 params:isPost ? this.getParams() : null,
2304 isUpload: this.form.fileUpload
2307 this.uploadProgress();
2309 }else if (o.clientValidation !== false){ // client validation failed
2310 this.failureType = Roo.form.Action.CLIENT_INVALID;
2311 this.form.afterAction(this, false);
2315 success : function(response)
2317 this.uploadComplete= true;
2318 if (this.haveProgress) {
2319 Roo.MessageBox.hide();
2323 var result = this.processResponse(response);
2324 if(result === true || result.success){
2325 this.form.afterAction(this, true);
2329 this.form.markInvalid(result.errors);
2330 this.failureType = Roo.form.Action.SERVER_INVALID;
2332 this.form.afterAction(this, false);
2334 failure : function(response)
2336 this.uploadComplete= true;
2337 if (this.haveProgress) {
2338 Roo.MessageBox.hide();
2341 this.response = response;
2342 this.failureType = Roo.form.Action.CONNECT_FAILURE;
2343 this.form.afterAction(this, false);
2346 handleResponse : function(response){
2347 if(this.form.errorReader){
2348 var rs = this.form.errorReader.read(response);
2351 for(var i = 0, len = rs.records.length; i < len; i++) {
2352 var r = rs.records[i];
2356 if(errors.length < 1){
2360 success : rs.success,
2366 ret = Roo.decode(response.responseText);
2370 errorMsg: "Failed to read server message: " + (response ? response.responseText : ' - no message'),
2380 Roo.form.Action.Load = function(form, options){
2381 Roo.form.Action.Load.superclass.constructor.call(this, form, options);
2382 this.reader = this.form.reader;
2385 Roo.extend(Roo.form.Action.Load, Roo.form.Action, {
2390 Roo.Ajax.request(Roo.apply(
2391 this.createCallback(), {
2392 method:this.getMethod(),
2393 url:this.getUrl(false),
2394 params:this.getParams()
2398 success : function(response){
2400 var result = this.processResponse(response);
2401 if(result === true || !result.success || !result.data){
2402 this.failureType = Roo.form.Action.LOAD_FAILURE;
2403 this.form.afterAction(this, false);
2406 this.form.clearInvalid();
2407 this.form.setValues(result.data);
2408 this.form.afterAction(this, true);
2411 handleResponse : function(response){
2412 if(this.form.reader){
2413 var rs = this.form.reader.read(response);
2414 var data = rs.records && rs.records[0] ? rs.records[0].data : null;
2416 success : rs.success,
2420 return Roo.decode(response.responseText);
2424 Roo.form.Action.ACTION_TYPES = {
2425 'load' : Roo.form.Action.Load,
2426 'submit' : Roo.form.Action.Submit
2435 * @class Roo.bootstrap.Form
2436 * @extends Roo.bootstrap.Component
2437 * Bootstrap Form class
2438 * @cfg {String} method GET | POST (default POST)
2439 * @cfg {String} labelAlign top | left (default top)
2443 * @param {Object} config The config object
2447 Roo.bootstrap.Form = function(config){
2448 Roo.bootstrap.Form.superclass.constructor.call(this, config);
2451 * @event clientvalidation
2452 * If the monitorValid config option is true, this event fires repetitively to notify of valid state
2453 * @param {Form} this
2454 * @param {Boolean} valid true if the form has passed client-side validation
2456 clientvalidation: true,
2458 * @event beforeaction
2459 * Fires before any action is performed. Return false to cancel the action.
2460 * @param {Form} this
2461 * @param {Action} action The action to be performed
2465 * @event actionfailed
2466 * Fires when an action fails.
2467 * @param {Form} this
2468 * @param {Action} action The action that failed
2470 actionfailed : true,
2472 * @event actioncomplete
2473 * Fires when an action is completed.
2474 * @param {Form} this
2475 * @param {Action} action The action that completed
2477 actioncomplete : true
2482 Roo.extend(Roo.bootstrap.Form, Roo.bootstrap.Component, {
2485 * @cfg {String} method
2486 * The request method to use (GET or POST) for form actions if one isn't supplied in the action options.
2491 * The URL to use for form actions if one isn't supplied in the action options.
2494 * @cfg {Boolean} fileUpload
2495 * Set to true if this form is a file upload.
2499 * @cfg {Object} baseParams
2500 * Parameters to pass with all requests. e.g. baseParams: {id: '123', foo: 'bar'}.
2504 * @cfg {Number} timeout Timeout for form actions in seconds (default is 30 seconds).
2509 activeAction : null,
2512 * By default wait messages are displayed with Roo.MessageBox.wait. You can target a specific
2513 * element by passing it or its id or mask the form itself by passing in true.
2516 waitMsgTarget : false,
2521 * By default wait messages are displayed with Roo.MessageBox.wait. You can target a specific
2522 * element by passing it or its id or mask the form itself by passing in true.
2526 getAutoCreate : function(){
2530 method : this.method || 'POST',
2531 id : this.id || Roo.id(),
2535 if (this.labelAlign == 'left' ) {
2536 cfg.cls += ' form-horizontal';
2540 initEvents : function()
2542 this.el.on('submit', this.onSubmit, this);
2547 onSubmit : function(e){
2552 * Returns true if client-side validation on the form is successful.
2555 isValid : function(){
2556 var items = this.getItems();
2558 items.each(function(f){
2567 * Returns true if any fields in this form have changed since their original load.
2570 isDirty : function(){
2572 var items = this.getItems();
2573 items.each(function(f){
2583 * Performs a predefined action (submit or load) or custom actions you define on this form.
2584 * @param {String} actionName The name of the action type
2585 * @param {Object} options (optional) The options to pass to the action. All of the config options listed
2586 * below are supported by both the submit and load actions unless otherwise noted (custom actions could also
2587 * accept other config options):
2589 Property Type Description
2590 ---------------- --------------- ----------------------------------------------------------------------------------
2591 url String The url for the action (defaults to the form's url)
2592 method String The form method to use (defaults to the form's method, or POST if not defined)
2593 params String/Object The params to pass (defaults to the form's baseParams, or none if not defined)
2594 clientValidation Boolean Applies to submit only. Pass true to call form.isValid() prior to posting to
2595 validate the form on the client (defaults to false)
2597 * @return {BasicForm} this
2599 doAction : function(action, options){
2600 if(typeof action == 'string'){
2601 action = new Roo.form.Action.ACTION_TYPES[action](this, options);
2603 if(this.fireEvent('beforeaction', this, action) !== false){
2604 this.beforeAction(action);
2605 action.run.defer(100, action);
2611 beforeAction : function(action){
2612 var o = action.options;
2614 // not really supported yet.. ??
2616 //if(this.waitMsgTarget === true){
2617 this.el.mask(o.waitMsg || "Sending", 'x-mask-loading');
2618 //}else if(this.waitMsgTarget){
2619 // this.waitMsgTarget = Roo.get(this.waitMsgTarget);
2620 // this.waitMsgTarget.mask(o.waitMsg || "Sending", 'x-mask-loading');
2622 // Roo.MessageBox.wait(o.waitMsg || "Sending", o.waitTitle || this.waitTitle || 'Please Wait...');
2628 afterAction : function(action, success){
2629 this.activeAction = null;
2630 var o = action.options;
2632 //if(this.waitMsgTarget === true){
2634 //}else if(this.waitMsgTarget){
2635 // this.waitMsgTarget.unmask();
2637 // Roo.MessageBox.updateProgress(1);
2638 // Roo.MessageBox.hide();
2645 Roo.callback(o.success, o.scope, [this, action]);
2646 this.fireEvent('actioncomplete', this, action);
2650 // failure condition..
2651 // we have a scenario where updates need confirming.
2652 // eg. if a locking scenario exists..
2653 // we look for { errors : { needs_confirm : true }} in the response.
2655 (typeof(action.result) != 'undefined') &&
2656 (typeof(action.result.errors) != 'undefined') &&
2657 (typeof(action.result.errors.needs_confirm) != 'undefined')
2660 Roo.log("not supported yet");
2663 Roo.MessageBox.confirm(
2664 "Change requires confirmation",
2665 action.result.errorMsg,
2670 _t.doAction('submit', { params : { _submit_confirmed : 1 } } );
2680 Roo.callback(o.failure, o.scope, [this, action]);
2681 // show an error message if no failed handler is set..
2682 if (!this.hasListener('actionfailed')) {
2683 Roo.log("need to add dialog support");
2685 Roo.MessageBox.alert("Error",
2686 (typeof(action.result) != 'undefined' && typeof(action.result.errorMsg) != 'undefined') ?
2687 action.result.errorMsg :
2688 "Saving Failed, please check your entries or try again"
2693 this.fireEvent('actionfailed', this, action);
2698 * Find a Roo.form.Field in this form by id, dataIndex, name or hiddenName
2699 * @param {String} id The value to search for
2702 findField : function(id){
2703 var items = this.getItems();
2704 var field = items.get(id);
2706 items.each(function(f){
2707 if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
2714 return field || null;
2717 * Mark fields in this form invalid in bulk.
2718 * @param {Array/Object} errors Either an array in the form [{id:'fieldId', msg:'The message'},...] or an object hash of {id: msg, id2: msg2}
2719 * @return {BasicForm} this
2721 markInvalid : function(errors){
2722 if(errors instanceof Array){
2723 for(var i = 0, len = errors.length; i < len; i++){
2724 var fieldError = errors[i];
2725 var f = this.findField(fieldError.id);
2727 f.markInvalid(fieldError.msg);
2733 if(typeof errors[id] != 'function' && (field = this.findField(id))){
2734 field.markInvalid(errors[id]);
2738 //Roo.each(this.childForms || [], function (f) {
2739 // f.markInvalid(errors);
2746 * Set values for fields in this form in bulk.
2747 * @param {Array/Object} values Either an array in the form [{id:'fieldId', value:'foo'},...] or an object hash of {id: value, id2: value2}
2748 * @return {BasicForm} this
2750 setValues : function(values){
2751 if(values instanceof Array){ // array of objects
2752 for(var i = 0, len = values.length; i < len; i++){
2754 var f = this.findField(v.id);
2756 f.setValue(v.value);
2757 if(this.trackResetOnLoad){
2758 f.originalValue = f.getValue();
2762 }else{ // object hash
2765 if(typeof values[id] != 'function' && (field = this.findField(id))){
2767 if (field.setFromData &&
2769 field.displayField &&
2770 // combos' with local stores can
2771 // be queried via setValue()
2772 // to set their value..
2773 (field.store && !field.store.isLocal)
2777 sd[field.valueField] = typeof(values[field.hiddenName]) == 'undefined' ? '' : values[field.hiddenName];
2778 sd[field.displayField] = typeof(values[field.name]) == 'undefined' ? '' : values[field.name];
2779 field.setFromData(sd);
2782 field.setValue(values[id]);
2786 if(this.trackResetOnLoad){
2787 field.originalValue = field.getValue();
2793 //Roo.each(this.childForms || [], function (f) {
2794 // f.setValues(values);
2801 * Returns the fields in this form as an object with key/value pairs. If multiple fields exist with the same name
2802 * they are returned as an array.
2803 * @param {Boolean} asString
2806 getValues : function(asString){
2807 //if (this.childForms) {
2808 // copy values from the child forms
2809 // Roo.each(this.childForms, function (f) {
2810 // this.setValues(f.getValues());
2816 var fs = Roo.lib.Ajax.serializeForm(this.el.dom);
2817 if(asString === true){
2820 return Roo.urlDecode(fs);
2824 * Returns the fields in this form as an object with key/value pairs.
2825 * This differs from getValues as it calls getValue on each child item, rather than using dom data.
2828 getFieldValues : function(with_hidden)
2830 var items = this.getItems();
2832 items.each(function(f){
2836 var v = f.getValue();
2837 if (f.inputType =='radio') {
2838 if (typeof(ret[f.getName()]) == 'undefined') {
2839 ret[f.getName()] = ''; // empty..
2842 if (!f.el.dom.checked) {
2850 // not sure if this supported any more..
2851 if ((typeof(v) == 'object') && f.getRawValue) {
2852 v = f.getRawValue() ; // dates..
2854 // combo boxes where name != hiddenName...
2855 if (f.name != f.getName()) {
2856 ret[f.name] = f.getRawValue();
2858 ret[f.getName()] = v;
2865 * Clears all invalid messages in this form.
2866 * @return {BasicForm} this
2868 clearInvalid : function(){
2869 var items = this.getItems();
2871 items.each(function(f){
2882 * @return {BasicForm} this
2885 var items = this.getItems();
2886 items.each(function(f){
2890 Roo.each(this.childForms || [], function (f) {
2897 getItems : function()
2899 var r=new Roo.util.MixedCollection(false, function(o){
2900 return o.id || (o.id = Roo.id());
2902 var iter = function(el) {
2909 Roo.each(el.items,function(e) {
2928 * Ext JS Library 1.1.1
2929 * Copyright(c) 2006-2007, Ext JS, LLC.
2931 * Originally Released Under LGPL - original licence link has changed is not relivant.
2934 * <script type="text/javascript">
2937 * @class Roo.form.VTypes
2938 * Overridable validation definitions. The validations provided are basic and intended to be easily customizable and extended.
2941 Roo.form.VTypes = function(){
2942 // closure these in so they are only created once.
2943 var alpha = /^[a-zA-Z_]+$/;
2944 var alphanum = /^[a-zA-Z0-9_]+$/;
2945 var email = /^([\w]+)(.[\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/;
2946 var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
2948 // All these messages and functions are configurable
2951 * The function used to validate email addresses
2952 * @param {String} value The email address
2954 'email' : function(v){
2955 return email.test(v);
2958 * The error text to display when the email validation function returns false
2961 'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
2963 * The keystroke filter mask to be applied on email input
2966 'emailMask' : /[a-z0-9_\.\-@]/i,
2969 * The function used to validate URLs
2970 * @param {String} value The URL
2972 'url' : function(v){
2976 * The error text to display when the url validation function returns false
2979 'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
2982 * The function used to validate alpha values
2983 * @param {String} value The value
2985 'alpha' : function(v){
2986 return alpha.test(v);
2989 * The error text to display when the alpha validation function returns false
2992 'alphaText' : 'This field should only contain letters and _',
2994 * The keystroke filter mask to be applied on alpha input
2997 'alphaMask' : /[a-z_]/i,
3000 * The function used to validate alphanumeric values
3001 * @param {String} value The value
3003 'alphanum' : function(v){
3004 return alphanum.test(v);
3007 * The error text to display when the alphanumeric validation function returns false
3010 'alphanumText' : 'This field should only contain letters, numbers and _',
3012 * The keystroke filter mask to be applied on alphanumeric input
3015 'alphanumMask' : /[a-z0-9_]/i
3025 * @class Roo.bootstrap.Input
3026 * @extends Roo.bootstrap.Component
3027 * Bootstrap Input class
3028 * @cfg {Boolean} disabled is it disabled
3029 * @cfg {String} fieldLabel - the label associated
3030 * @cfg {String} inputType button | checkbox | email | file | hidden | image | number | password | radio | range | reset | search | submit | text
3031 * @cfg {String} name name of the input
3032 * @cfg {string} fieldLabel - the label associated
3033 * @cfg {string} inputType - input / file submit ...
3034 * @cfg {string} placeholder - placeholder to put in text.
3035 * @cfg {string} before - input group add on before
3036 * @cfg {string} after - input group add on after
3040 * Create a new Input
3041 * @param {Object} config The config object
3044 Roo.bootstrap.Input = function(config){
3045 Roo.bootstrap.Input.superclass.constructor.call(this, config);
3050 * Fires when this field receives input focus.
3051 * @param {Roo.form.Field} this
3056 * Fires when this field loses input focus.
3057 * @param {Roo.form.Field} this
3062 * Fires when any key related to navigation (arrows, tab, enter, esc, etc.) is pressed. You can check
3063 * {@link Roo.EventObject#getKey} to determine which key was pressed.
3064 * @param {Roo.form.Field} this
3065 * @param {Roo.EventObject} e The event object
3070 * Fires just before the field blurs if the field value has changed.
3071 * @param {Roo.form.Field} this
3072 * @param {Mixed} newValue The new value
3073 * @param {Mixed} oldValue The original value
3078 * Fires after the field has been marked as invalid.
3079 * @param {Roo.form.Field} this
3080 * @param {String} msg The validation message
3085 * Fires after the field has been validated with no errors.
3086 * @param {Roo.form.Field} this
3091 * Fires after the key up
3092 * @param {Roo.form.Field} this
3093 * @param {Roo.EventObject} e The event Object
3099 Roo.extend(Roo.bootstrap.Input, Roo.bootstrap.Component, {
3101 * @cfg {String/Boolean} validationEvent The event that should initiate field validation. Set to false to disable
3102 automatic validation (defaults to "keyup").
3104 validationEvent : "keyup",
3106 * @cfg {Boolean} validateOnBlur Whether the field should validate when it loses focus (defaults to true).
3108 validateOnBlur : true,
3110 * @cfg {Number} validationDelay The length of time in milliseconds after user input begins until validation is initiated (defaults to 250)
3112 validationDelay : 250,
3114 * @cfg {String} focusClass The CSS class to use when the field receives focus (defaults to "x-form-focus")
3116 focusClass : "x-form-focus", // not needed???
3120 * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to "x-form-invalid")
3122 invalidClass : "has-error",
3125 * @cfg {Boolean} selectOnFocus True to automatically select any existing field text when the field receives input focus (defaults to false)
3127 selectOnFocus : false,
3130 * @cfg {String} maskRe An input mask regular expression that will be used to filter keystrokes that don't match (defaults to null)
3134 * @cfg {String} vtype A validation type name as defined in {@link Roo.form.VTypes} (defaults to null)
3139 * @cfg {Boolean} disableKeyFilter True to disable input keystroke filtering (defaults to false)
3141 disableKeyFilter : false,
3144 * @cfg {Boolean} disabled True to disable the field (defaults to false).
3148 * @cfg {Boolean} allowBlank False to validate that the value length > 0 (defaults to true)
3152 * @cfg {String} blankText Error text to display if the allow blank validation fails (defaults to "This field is required")
3154 blankText : "This field is required",
3157 * @cfg {Number} minLength Minimum input field length required (defaults to 0)
3161 * @cfg {Number} maxLength Maximum input field length allowed (defaults to Number.MAX_VALUE)
3163 maxLength : Number.MAX_VALUE,
3165 * @cfg {String} minLengthText Error text to display if the minimum length validation fails (defaults to "The minimum length for this field is {minLength}")
3167 minLengthText : "The minimum length for this field is {0}",
3169 * @cfg {String} maxLengthText Error text to display if the maximum length validation fails (defaults to "The maximum length for this field is {maxLength}")
3171 maxLengthText : "The maximum length for this field is {0}",
3175 * @cfg {Function} validator A custom validation function to be called during field validation (defaults to null).
3176 * If available, this function will be called only after the basic validators all return true, and will be passed the
3177 * current field value and expected to return boolean true if the value is valid or a string error message if invalid.
3181 * @cfg {RegExp} regex A JavaScript RegExp object to be tested against the field value during validation (defaults to null).
3182 * If available, this regex will be evaluated only after the basic validators all return true, and will be passed the
3183 * current field value. If the test fails, the field will be marked invalid using {@link #regexText}.
3187 * @cfg {String} regexText The error text to display if {@link #regex} is used and the test fails during validation (defaults to "")
3205 getAutoCreate : function(){
3207 var parent = this.parent();
3209 var align = parent.labelAlign;
3214 cls: 'form-group' //input-group
3220 type : this.inputType,
3221 cls : 'form-control',
3222 placeholder : this.placeholder || ''
3226 input.name = this.name;
3229 var inputblock = input;
3231 if (this.before || this.after) {
3234 cls : 'input-group',
3238 inputblock.cn.push({
3240 cls : 'input-group-addon',
3244 inputblock.cn.push(input);
3246 inputblock.cn.push({
3248 cls : 'input-group-addon',
3256 Roo.log(this.fieldLabel.length);
3258 if (align ==='left' && this.fieldLabel.length) {
3259 Roo.log("left and has label");
3265 cls : 'col-sm-2 control-label',
3266 html : this.fieldLabel
3277 } else if ( this.fieldLabel.length) {
3283 //cls : 'input-group-addon',
3284 html : this.fieldLabel
3294 Roo.log(" no label && no align");
3307 if (this.disabled) {
3308 input.disabled=true;
3314 * return the real input element.
3316 inputEl: function ()
3318 return this.el.select('input.form-control',true).first();
3320 setDisabled : function(v)
3322 var i = this.inputEl().dom;
3324 i.removeAttribute('disabled');
3328 i.setAttribute('disabled','true');
3330 initEvents : function()
3333 this.inputEl().on("keydown" , this.fireKey, this);
3334 this.inputEl().on("focus", this.onFocus, this);
3335 this.inputEl().on("blur", this.onBlur, this);
3336 this.inputEl().relayEvent('keyup', this);
3338 // reference to original value for reset
3339 this.originalValue = this.getValue();
3340 //Roo.form.TextField.superclass.initEvents.call(this);
3341 if(this.validationEvent == 'keyup'){
3342 this.validationTask = new Roo.util.DelayedTask(this.validate, this);
3343 this.inputEl().on('keyup', this.filterValidation, this);
3345 else if(this.validationEvent !== false){
3346 this.inputEl().on(this.validationEvent, this.validate, this, {buffer: this.validationDelay});
3349 if(this.selectOnFocus){
3350 this.on("focus", this.preFocus, this);
3353 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Roo.form.VTypes[this.vtype+'Mask']))){
3354 this.inputEl().on("keypress", this.filterKeys, this);
3357 this.el.on("keyup", this.onKeyUp, this, {buffer:50});
3358 this.el.on("click", this.autoSize, this);
3361 if(this.inputEl().is('input[type=password]') && Roo.isSafari){
3362 this.inputEl().on('keydown', this.SafariOnKeyDown, this);
3366 filterValidation : function(e){
3367 if(!e.isNavKeyPress()){
3368 this.validationTask.delay(this.validationDelay);
3372 * Validates the field value
3373 * @return {Boolean} True if the value is valid, else false
3375 validate : function(){
3376 //if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
3377 if(this.disabled || this.validateValue(this.getRawValue())){
3378 this.clearInvalid();
3386 * Validates a value according to the field's validation rules and marks the field as invalid
3387 * if the validation fails
3388 * @param {Mixed} value The value to validate
3389 * @return {Boolean} True if the value is valid, else false
3391 validateValue : function(value){
3392 if(value.length < 1) { // if it's blank
3393 if(this.allowBlank){
3394 this.clearInvalid();
3397 this.markInvalid(this.blankText);
3401 if(value.length < this.minLength){
3402 this.markInvalid(String.format(this.minLengthText, this.minLength));
3405 if(value.length > this.maxLength){
3406 this.markInvalid(String.format(this.maxLengthText, this.maxLength));
3410 var vt = Roo.form.VTypes;
3411 if(!vt[this.vtype](value, this)){
3412 this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
3416 if(typeof this.validator == "function"){
3417 var msg = this.validator(value);
3419 this.markInvalid(msg);
3423 if(this.regex && !this.regex.test(value)){
3424 this.markInvalid(this.regexText);
3433 fireKey : function(e){
3434 //Roo.log('field ' + e.getKey());
3435 if(e.isNavKeyPress()){
3436 this.fireEvent("specialkey", this, e);
3439 onFocus : function(){
3440 if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
3441 // this.el.addClass(this.focusClass);
3444 this.hasFocus = true;
3445 this.startValue = this.getValue();
3446 this.fireEvent("focus", this);
3450 beforeBlur : Roo.emptyFn,
3454 onBlur : function(){
3456 if(!Roo.isOpera && this.focusClass){ // don't touch in Opera
3457 //this.el.removeClass(this.focusClass);
3459 this.hasFocus = false;
3460 if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
3463 var v = this.getValue();
3464 if(String(v) !== String(this.startValue)){
3465 this.fireEvent('change', this, v, this.startValue);
3467 this.fireEvent("blur", this);
3470 * Returns the normalized data value (undefined or emptyText will be returned as ''). To return the raw value see {@link #getRawValue}.
3471 * @return {Mixed} value The field value
3473 getValue : function(){
3474 var v = this.inputEl().getValue();
3478 * Returns the raw data value which may or may not be a valid, defined value. To return a normalized value see {@link #getValue}.
3479 * @return {Mixed} value The field value
3481 getRawValue : function(){
3482 var v = this.inputEl().getValue();
3487 * Sets a data value into the field and validates it. To set the value directly without validation see {@link #setRawValue}.
3488 * @param {Mixed} value The value to set
3490 setValue : function(v){
3493 this.inputEl().dom.value = (v === null || v === undefined ? '' : v);
3499 processValue : function(value){
3500 if(this.stripCharsRe){
3501 var newValue = value.replace(this.stripCharsRe, '');
3502 if(newValue !== value){
3503 this.setRawValue(newValue);
3510 preFocus : function(){
3512 if(this.selectOnFocus){
3513 this.inputEl().dom.select();
3516 filterKeys : function(e){
3518 if(!Roo.isIE && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
3521 var c = e.getCharCode(), cc = String.fromCharCode(c);
3522 if(Roo.isIE && (e.isSpecialKey() || !cc)){
3525 if(!this.maskRe.test(cc)){
3530 * Clear any invalid styles/messages for this field
3532 clearInvalid : function(){
3534 if(!this.el || this.preventMark){ // not rendered
3537 this.el.removeClass(this.invalidClass);
3539 switch(this.msgTarget){
3541 this.el.dom.qtip = '';
3544 this.el.dom.title = '';
3548 Roo.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
3553 this.errorIcon.dom.qtip = '';
3554 this.errorIcon.hide();
3555 this.un('resize', this.alignErrorIcon, this);
3559 var t = Roo.getDom(this.msgTarget);
3561 t.style.display = 'none';
3565 this.fireEvent('valid', this);
3568 * Mark this field as invalid
3569 * @param {String} msg The validation message
3571 markInvalid : function(msg){
3572 if(!this.el || this.preventMark){ // not rendered
3575 this.el.addClass(this.invalidClass);
3577 msg = msg || this.invalidText;
3578 switch(this.msgTarget){
3580 this.el.dom.qtip = msg;
3581 this.el.dom.qclass = 'x-form-invalid-tip';
3582 if(Roo.QuickTips){ // fix for floating editors interacting with DND
3583 Roo.QuickTips.enable();
3587 this.el.dom.title = msg;
3591 var elp = this.el.findParent('.x-form-element', 5, true);
3592 this.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
3593 this.errorEl.setWidth(elp.getWidth(true)-20);
3595 this.errorEl.update(msg);
3596 Roo.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
3599 if(!this.errorIcon){
3600 var elp = this.el.findParent('.x-form-element', 5, true);
3601 this.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
3603 this.alignErrorIcon();
3604 this.errorIcon.dom.qtip = msg;
3605 this.errorIcon.dom.qclass = 'x-form-invalid-tip';
3606 this.errorIcon.show();
3607 this.on('resize', this.alignErrorIcon, this);
3610 var t = Roo.getDom(this.msgTarget);
3612 t.style.display = this.msgDisplay;
3616 this.fireEvent('invalid', this, msg);
3619 SafariOnKeyDown : function(event)
3621 // this is a workaround for a password hang bug on chrome/ webkit.
3623 var isSelectAll = false;
3625 if(this.inputEl().dom.selectionEnd > 0){
3626 isSelectAll = (this.inputEl().dom.selectionEnd - this.inputEl().dom.selectionStart - this.getValue().length == 0) ? true : false;
3628 if(((event.getKey() == 8 || event.getKey() == 46) && this.getValue().length ==1)){ // backspace and delete key
3629 event.preventDefault();
3634 if(isSelectAll){ // backspace and delete key
3636 event.preventDefault();
3637 // this is very hacky as keydown always get's upper case.
3639 var cc = String.fromCharCode(event.getCharCode());
3640 this.setValue( event.shiftKey ? cc : cc.toLowerCase());