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.createDelegate(this) };
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