/** * set the version of bootstrap based on the stylesheet... * */ Roo.bootstrap.version = ( function() { var ret=3; Roo.each(document.styleSheets, function(s) { if ( s.href && s.href.match(/css-bootstrap4/)) { ret=4; } }); return ret; })(); /* * - LGPL * * base class for bootstrap elements. * */ Roo.bootstrap = Roo.bootstrap || {}; /** * @class Roo.bootstrap.Component * @extends Roo.Component * Bootstrap Component base class * @cfg {String} cls css class * @cfg {String} style any extra css * @cfg {Object} xattr extra attributes to add to 'element' (used by builder to store stuff.) * @cfg {Boolean} can_build_overlaid True if element can be rebuild from a HTML page * @cfg {string} dataId cutomer id * @cfg {string} name Specifies name attribute * @cfg {string} tooltip Text for the tooltip * @cfg {string} container_method method to fetch parents container element (used by NavHeaderbar - getHeaderChildContainer) * @cfg {string|object} visibilityEl (el|parent) What element to use for visibility (@see getVisibilityEl()) * @constructor * Do not use directly - it does not do anything.. * @param {Object} config The config object */ Roo.bootstrap.Component = function(config){ Roo.bootstrap.Component.superclass.constructor.call(this, config); this.addEvents({ /** * @event childrenrendered * Fires when the children have been rendered.. * @param {Roo.bootstrap.Component} this */ "childrenrendered" : true }); }; Roo.extend(Roo.bootstrap.Component, Roo.BoxComponent, { allowDomMove : false, // to stop relocations in parent onRender... cls : false, style : false, autoCreate : false, tooltip : null, /** * Initialize Events for the element */ initEvents : function() { }, xattr : false, parentId : false, can_build_overlaid : true, container_method : false, dataId : false, name : false, parent: function() { // returns the parent component.. return Roo.ComponentMgr.get(this.parentId) }, // private onRender : function(ct, position) { // Roo.log("Call onRender: " + this.xtype); Roo.bootstrap.Component.superclass.onRender.call(this, ct, position); if(this.el){ if (this.el.attr('xtype')) { this.el.attr('xtypex', this.el.attr('xtype')); this.el.dom.removeAttribute('xtype'); this.initEvents(); } return; } var cfg = Roo.apply({}, this.getAutoCreate()); cfg.id = this.id || Roo.id(); // fill in the extra attributes if (this.xattr && typeof(this.xattr) =='object') { for (var i in this.xattr) { cfg[i] = this.xattr[i]; } } if(this.dataId){ cfg.dataId = this.dataId; } if (this.cls) { cfg.cls = (typeof(cfg.cls) == 'undefined') ? this.cls : cfg.cls + ' ' + this.cls; } if (this.style) { // fixme needs to support more complex style data. cfg.style = this.style; } if(this.name){ cfg.name = this.name; } this.el = ct.createChild(cfg, position); if (this.tooltip) { this.tooltipEl().attr('tooltip', this.tooltip); } if(this.tabIndex !== undefined){ this.el.dom.setAttribute('tabIndex', this.tabIndex); } this.initEvents(); }, /** * Fetch the element to add children to * @return {Roo.Element} defaults to this.el */ getChildContainer : function() { return this.el; }, /** * Fetch the element to display the tooltip on. * @return {Roo.Element} defaults to this.el */ tooltipEl : function() { return this.el; }, addxtype : function(tree,cntr) { var cn = this; cn = Roo.factory(tree); //Roo.log(['addxtype', cn]); cn.parentType = this.xtype; //?? cn.parentId = this.id; cntr = (typeof(cntr) == 'undefined' ) ? 'getChildContainer' : cntr; if (typeof(cn.container_method) == 'string') { cntr = cn.container_method; } var has_flexy_each = (typeof(tree['flexy:foreach']) != 'undefined'); var has_flexy_if = (typeof(tree['flexy:if']) != 'undefined'); var build_from_html = Roo.XComponent.build_from_html; var is_body = (tree.xtype == 'Body') ; var page_has_body = (Roo.get(document.body).attr('xtype') == 'Roo.bootstrap.Body'); var self_cntr_el = Roo.get(this[cntr](false)); // do not try and build conditional elements if ((has_flexy_each || has_flexy_if || this.can_build_overlaid == false ) && build_from_html) { return false; } if (!has_flexy_each || !build_from_html || is_body || !page_has_body) { if(!has_flexy_if || typeof(tree.name) == 'undefined' || !build_from_html || is_body || !page_has_body){ return this.addxtypeChild(tree,cntr, is_body); } var echild =self_cntr_el ? self_cntr_el.child('>*[name=' + tree.name + ']') : false; if(echild){ return this.addxtypeChild(Roo.apply({}, tree),cntr); } Roo.log('skipping render'); return cn; } var ret = false; if (!build_from_html) { return false; } // this i think handles overlaying multiple children of the same type // with the sam eelement.. - which might be buggy.. while (true) { var echild =self_cntr_el ? self_cntr_el.child('>*[xtype]') : false; if (!echild) { break; } if (echild && echild.attr('xtype').split('.').pop() != cn.xtype) { break; } ret = this.addxtypeChild(Roo.apply({}, tree),cntr); } return ret; }, addxtypeChild : function (tree, cntr, is_body) { Roo.debug && Roo.log('addxtypeChild:' + cntr); var cn = this; cntr = (typeof(cntr) == 'undefined' ) ? 'getChildContainer' : cntr; var has_flexy = (typeof(tree['flexy:if']) != 'undefined') || (typeof(tree['flexy:foreach']) != 'undefined'); skip_children = false; // render the element if it's not BODY. if (!is_body) { // if parent was disabled, then do not try and create the children.. if(!this[cntr](true)){ tree.items = []; return tree; } cn = Roo.factory(tree); cn.parentType = this.xtype; //?? cn.parentId = this.id; var build_from_html = Roo.XComponent.build_from_html; // does the container contain child eleemnts with 'xtype' attributes. // that match this xtype.. // note - when we render we create these as well.. // so we should check to see if body has xtype set. if (build_from_html && Roo.get(document.body).attr('xtype') == 'Roo.bootstrap.Body') { var self_cntr_el = Roo.get(this[cntr](false)); var echild =self_cntr_el ? self_cntr_el.child('>*[xtype]') : false; if (echild) { //Roo.log(Roo.XComponent.build_from_html); //Roo.log("got echild:"); //Roo.log(echild); } // there is a scenario where some of the child elements are flexy:if (and all of the same type) // and are not displayed -this causes this to use up the wrong element when matching. // at present the only work around for this is to nest flexy:if elements in another element that is always rendered. if (echild && echild.attr('xtype').split('.').pop() == cn.xtype) { // Roo.log("found child for " + this.xtype +": " + echild.attr('xtype') ); cn.el = echild; // Roo.log("GOT"); //echild.dom.removeAttribute('xtype'); } else { Roo.debug && Roo.log("MISSING " + cn.xtype + " on child of " + (this.el ? this.el.attr('xbuilderid') : 'no parent')); Roo.debug && Roo.log(self_cntr_el); Roo.debug && Roo.log(echild); Roo.debug && Roo.log(cn); } } // if object has flexy:if - then it may or may not be rendered. if (build_from_html && has_flexy && !cn.el && cn.can_build_overlaid) { // skip a flexy if element. Roo.debug && Roo.log('skipping render'); Roo.debug && Roo.log(tree); if (!cn.el) { Roo.debug && Roo.log('skipping all children'); skip_children = true; } } else { // actually if flexy:foreach is found, we really want to create // multiple copies here... //Roo.log('render'); //Roo.log(this[cntr]()); // some elements do not have render methods.. like the layouts... /* if(this[cntr](true) === false){ cn.items = []; return cn; } */ cn.render && cn.render(this[cntr](true)); } // then add the element.. } // handle the kids.. var nitems = []; /* if (typeof (tree.menu) != 'undefined') { tree.menu.parentType = cn.xtype; tree.menu.triggerEl = cn.el; nitems.push(cn.addxtype(Roo.apply({}, tree.menu))); } */ if (!tree.items || !tree.items.length) { cn.items = nitems; //Roo.log(["no children", this]); return cn; } var items = tree.items; delete tree.items; //Roo.log(items.length); // add the items.. if (!skip_children) { for(var i =0;i < items.length;i++) { // Roo.log(['add child', items[i]]); nitems.push(cn.addxtype(Roo.apply({}, items[i]))); } } cn.items = nitems; //Roo.log("fire childrenrendered"); cn.fireEvent('childrenrendered', this); return cn; }, /** * Set the element that will be used to show or hide */ setVisibilityEl : function(el) { this.visibilityEl = el; }, /** * Get the element that will be used to show or hide */ getVisibilityEl : function() { if (typeof(this.visibilityEl) == 'object') { return this.visibilityEl; } if (typeof(this.visibilityEl) == 'string') { return this.visibilityEl == 'parent' ? this.parent().getEl() : this.getEl(); } return this.getEl(); }, /** * Show a component - removes 'hidden' class */ show : function() { if(!this.getVisibilityEl()){ return; } this.getVisibilityEl().removeClass(['hidden','d-none']); this.fireEvent('show', this); }, /** * Hide a component - adds 'hidden' class */ hide: function() { if(!this.getVisibilityEl()){ return; } this.getVisibilityEl().addClass(['hidden','d-none']); this.fireEvent('hide', this); } }); /* * - LGPL * * Body * */ /** * @class Roo.bootstrap.Body * @extends Roo.bootstrap.Component * Bootstrap Body class * * @constructor * Create a new body * @param {Object} config The config object */ Roo.bootstrap.Body = function(config){ config = config || {}; Roo.bootstrap.Body.superclass.constructor.call(this, config); this.el = Roo.get(config.el ? config.el : document.body ); if (this.cls && this.cls.length) { Roo.get(document.body).addClass(this.cls); } }; Roo.extend(Roo.bootstrap.Body, Roo.bootstrap.Component, { is_body : true,// just to make sure it's constructed? autoCreate : { cls: 'container' }, onRender : function(ct, position) { /* Roo.log("Roo.bootstrap.Body - onRender"); if (this.cls && this.cls.length) { Roo.get(document.body).addClass(this.cls); } // style??? xttr??? */ } }); /* * - LGPL * * button group * */ /** * @class Roo.bootstrap.ButtonGroup * @extends Roo.bootstrap.Component * Bootstrap ButtonGroup class * @cfg {String} size lg | sm | xs (default empty normal) * @cfg {String} align vertical | justified (default none) * @cfg {String} direction up | down (default down) * @cfg {Boolean} toolbar false | true * @cfg {Boolean} btn true | false * * * @constructor * Create a new Input * @param {Object} config The config object */ Roo.bootstrap.ButtonGroup = function(config){ Roo.bootstrap.ButtonGroup.superclass.constructor.call(this, config); }; Roo.extend(Roo.bootstrap.ButtonGroup, Roo.bootstrap.Component, { size: '', align: '', direction: '', toolbar: false, btn: true, getAutoCreate : function(){ var cfg = { cls: 'btn-group', html : null }; cfg.html = this.html || cfg.html; if (this.toolbar) { cfg = { cls: 'btn-toolbar', html: null }; return cfg; } if (['vertical','justified'].indexOf(this.align)!==-1) { cfg.cls = 'btn-group-' + this.align; if (this.align == 'justified') { console.log(this.items); } } if (['lg','sm','xs'].indexOf(this.size)!==-1) { cfg.cls += ' btn-group-' + this.size; } if (this.direction == 'up') { cfg.cls += ' dropup' ; } return cfg; }, /** * Add a button to the group (similar to NavItem API.) */ addItem : function(cfg) { var cn = new Roo.bootstrap.Button(cfg); //this.register(cn); cn.parentId = this.id; cn.onRender(this.el, null); return cn; } }); /* * - LGPL * * button * */ /** * @class Roo.bootstrap.Button * @extends Roo.bootstrap.Component * Bootstrap Button class * @cfg {String} html The button content * @cfg {String} weight (default | primary | secondary | success | info | warning | danger | link ) default * @cfg {String} badge_weight (default | primary | secondary | success | info | warning | danger | link ) default (same as button) * @cfg {Boolean} outline default false (except for weight=default which emulates old behaveiour with an outline) * @cfg {String} size ( lg | sm | xs) * @cfg {String} tag ( a | input | submit) * @cfg {String} href empty or href * @cfg {Boolean} disabled default false; * @cfg {Boolean} isClose default false; * @cfg {String} glyphicon depricated - use fa * @cfg {String} fa fontawesome icon - eg. 'comment' - without the fa/fas etc.. * @cfg {String} badge text for badge * @cfg {String} theme (default|glow) * @cfg {Boolean} inverse dark themed version * @cfg {Boolean} toggle is it a slidy toggle button * @cfg {Boolean} pressed (true|false) default null - if the button ahs active state * @cfg {String} ontext text for on slidy toggle state * @cfg {String} offtext text for off slidy toggle state * @cfg {Boolean} preventDefault default true (stop click event triggering the URL if it's a link.) * @cfg {Boolean} removeClass remove the standard class.. * @cfg {String} target target for a href. (_self|_blank|_parent|_top| other) * * @constructor * Create a new button * @param {Object} config The config object */ Roo.bootstrap.Button = function(config){ Roo.bootstrap.Button.superclass.constructor.call(this, config); this.weightClass = ["btn-default btn-outline-secondary", "btn-primary", "btn-success", "btn-info", "btn-warning", "btn-danger", "btn-link" ], this.addEvents({ // raw events /** * @event click * When a butotn is pressed * @param {Roo.bootstrap.Button} btn * @param {Roo.EventObject} e */ "click" : true, /** * @event toggle * After the button has been toggles * @param {Roo.bootstrap.Button} btn * @param {Roo.EventObject} e * @param {boolean} pressed (also available as button.pressed) */ "toggle" : true }); }; Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component, { html: false, active: false, weight: '', badge_weight: '', outline : false, size: '', tag: 'button', href: '', disabled: false, isClose: false, glyphicon: '', fa: '', badge: '', theme: 'default', inverse: false, toggle: false, ontext: 'ON', offtext: 'OFF', defaulton: true, preventDefault: true, removeClass: false, name: false, target: false, pressed : null, getAutoCreate : function(){ var cfg = { tag : 'button', cls : 'roo-button', html: '' }; if (['a', 'button', 'input', 'submit'].indexOf(this.tag) < 0) { throw "Invalid value for tag: " + this.tag + ". must be a, button, input or submit."; this.tag = 'button'; } else { cfg.tag = this.tag; } cfg.html = '' + (this.html || cfg.html) + ''; if (this.toggle == true) { cfg={ tag: 'div', cls: 'slider-frame roo-button', cn: [ { tag: 'span', 'data-on-text':'ON', 'data-off-text':'OFF', cls: 'slider-button', html: this.offtext } ] }; if (['default', 'secondary' , 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) { cfg.cls += ' '+this.weight; } return cfg; } if (this.isClose) { cfg.cls += ' close'; cfg["aria-hidden"] = true; cfg.html = "×"; return cfg; } if (this.theme==='default') { cfg.cls = 'btn roo-button'; //if (this.parentType != 'Navbar') { this.weight = this.weight.length ? this.weight : 'default'; //} if (['default', 'primary', 'secondary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) { var outline = this.outline || this.weight == 'default' ? 'outline-' : ''; var weight = this.weight == 'default' ? 'secondary' : this.weight; cfg.cls += ' btn-' + outline + weight; if (this.weight == 'default') { // BC cfg.cls += ' btn-' + this.weight; } } } else if (this.theme==='glow') { cfg.tag = 'a'; cfg.cls = 'btn-glow roo-button'; if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) { cfg.cls += ' ' + this.weight; } } if (this.inverse) { this.cls += ' inverse'; } if (this.active || this.pressed === true) { cfg.cls += ' active'; } if (this.disabled) { cfg.disabled = 'disabled'; } if (this.items) { Roo.log('changing to ul' ); cfg.tag = 'ul'; this.glyphicon = 'caret'; if (Roo.bootstrap.version == 4) { this.fa = 'caret-down'; } } cfg.cls += this.size.length ? (' btn-' + this.size) : ''; //gsRoo.log(this.parentType); if (this.parentType === 'Navbar' && !this.parent().bar) { Roo.log('changing to li?'); cfg.tag = 'li'; cfg.cls = ''; cfg.cn = [{ tag : 'a', cls : 'roo-button', html : this.html, href : this.href || '#' }]; if (this.menu) { cfg.cn[0].html = this.html + ' '; cfg.cls += ' dropdown'; } delete cfg.html; } cfg.cls += this.parentType === 'Navbar' ? ' navbar-btn' : ''; if (this.glyphicon) { cfg.html = ' ' + cfg.html; cfg.cn = [ { tag: 'span', cls: 'glyphicon glyphicon-' + this.glyphicon } ]; } if (this.fa) { cfg.html = ' ' + cfg.html; cfg.cn = [ { tag: 'i', cls: 'fa fas fa-' + this.fa } ]; } if (this.badge) { cfg.html += ' '; cfg.tag = 'a'; // cfg.cls='btn roo-button'; cfg.href=this.href; var value = cfg.html; if(this.glyphicon){ value = { tag: 'span', cls: 'glyphicon glyphicon-' + this.glyphicon, html: this.html }; } if(this.fa){ value = { tag: 'i', cls: 'fa fas fa-' + this.fa, html: this.html }; } var bw = this.badge_weight.length ? this.badge_weight : (this.weight.length ? this.weight : 'secondary'); bw = bw == 'default' ? 'secondary' : bw; cfg.cn = [ value, { tag: 'span', cls: 'badge badge-' + bw, html: this.badge } ]; cfg.html=''; } if (this.menu) { cfg.cls += ' dropdown'; cfg.html = typeof(cfg.html) != 'undefined' ? cfg.html + ' ' : ''; } if (cfg.tag !== 'a' && this.href !== '') { throw "Tag must be a to set href."; } else if (this.href.length > 0) { cfg.href = this.href; } if(this.removeClass){ cfg.cls = ''; } if(this.target){ cfg.target = this.target; } return cfg; }, initEvents: function() { // Roo.log('init events?'); // Roo.log(this.el.dom); // add the menu... if (typeof (this.menu) != 'undefined') { this.menu.parentType = this.xtype; this.menu.triggerEl = this.el; this.addxtype(Roo.apply({}, this.menu)); } if (this.el.hasClass('roo-button')) { this.el.on('click', this.onClick, this); } else { this.el.select('.roo-button').on('click', this.onClick, this); } if(this.removeClass){ this.el.on('click', this.onClick, this); } this.el.enableDisplayMode(); }, onClick : function(e) { if (this.disabled) { return; } Roo.log('button on click '); if(this.preventDefault){ e.preventDefault(); } if (this.pressed === true || this.pressed === false) { this.toggleActive(e); } this.fireEvent('click', this, e); }, /** * Enables this button */ enable : function() { this.disabled = false; this.el.removeClass('disabled'); }, /** * Disable this button */ disable : function() { this.disabled = true; this.el.addClass('disabled'); }, /** * sets the active state on/off, * @param {Boolean} state (optional) Force a particular state */ setActive : function(v) { this.el[v ? 'addClass' : 'removeClass']('active'); this.pressed = v; }, /** * toggles the current active state */ toggleActive : function(e) { this.setActive(!this.pressed); this.fireEvent('toggle', this, e, !this.pressed); }, /** * get the current active state * @return {boolean} true if it's active */ isActive : function() { return this.el.hasClass('active'); }, /** * set the text of the first selected button */ setText : function(str) { this.el.select('.roo-button-text',true).first().dom.innerHTML = str; }, /** * get the text of the first selected button */ getText : function() { return this.el.select('.roo-button-text',true).first().dom.innerHTML; }, setWeight : function(str) { this.el.removeClass(this.weightClass); this.weight = str; var outline = this.outline ? 'outline-' : ''; if (str == 'default') { this.el.addClass('btn-default btn-outline-secondary'); return; } this.el.addClass('btn-' + outline + str); } }); /* * - LGPL * * column * */ /** * @class Roo.bootstrap.Column * @extends Roo.bootstrap.Component * Bootstrap Column class * @cfg {Number} xs colspan out of 12 for mobile-sized screens or 0 for hidden * @cfg {Number} sm colspan out of 12 for tablet-sized screens or 0 for hidden * @cfg {Number} md colspan out of 12 for computer-sized screens or 0 for hidden * @cfg {Number} lg colspan out of 12 for large computer-sized screens or 0 for hidden * @cfg {Number} xsoff colspan offset out of 12 for mobile-sized screens or 0 for hidden * @cfg {Number} smoff colspan offset out of 12 for tablet-sized screens or 0 for hidden * @cfg {Number} mdoff colspan offset out of 12 for computer-sized screens or 0 for hidden * @cfg {Number} lgoff colspan offset out of 12 for large computer-sized screens or 0 for hidden * * * @cfg {Boolean} hidden (true|false) hide the element * @cfg {String} alert (success|info|warning|danger) type alert (changes background / border...) * @cfg {String} fa (ban|check|...) font awesome icon * @cfg {Number} fasize (1|2|....) font awsome size * @cfg {String} icon (info-sign|check|...) glyphicon name * @cfg {String} html content of column. * * @constructor * Create a new Column * @param {Object} config The config object */ Roo.bootstrap.Column = function(config){ Roo.bootstrap.Column.superclass.constructor.call(this, config); }; Roo.extend(Roo.bootstrap.Column, Roo.bootstrap.Component, { xs: false, sm: false, md: false, lg: false, xsoff: false, smoff: false, mdoff: false, lgoff: false, html: '', offset: 0, alert: false, fa: false, icon : false, hidden : false, fasize : 1, getAutoCreate : function(){ var cfg = Roo.apply({}, Roo.bootstrap.Column.superclass.getAutoCreate.call(this)); cfg = { tag: 'div', cls: 'column' }; var settings=this; ['xs','sm','md','lg'].map(function(size){ //Roo.log( size + ':' + settings[size]); if (settings[size+'off'] !== false) { cfg.cls += ' col-' + size + '-offset-' + settings[size+'off'] ; } if (settings[size] === false) { return; } if (!settings[size]) { // 0 = hidden cfg.cls += ' hidden-' + size + ' hidden' + size + '-down';; return; } cfg.cls += ' col-' + size + '-' + settings[size] + ( size == 'xs' ? (' col-' + settings[size] ) : '' // bs4 col-{num} replaces col-xs ); }); if (this.hidden) { cfg.cls += ' hidden'; } if (this.alert && ["success","info","warning", "danger"].indexOf(this.alert) > -1) { cfg.cls +=' alert alert-' + this.alert; } if (this.html.length) { cfg.html = this.html; } if (this.fa) { var fasize = ''; if (this.fasize > 1) { fasize = ' fa-' + this.fasize + 'x'; } cfg.html = '' + (cfg.html || ''); } if (this.icon) { cfg.html = '' + (cfg.html || ''); } return cfg; } }); /* * - LGPL * * page container. * */ /** * @class Roo.bootstrap.Container * @extends Roo.bootstrap.Component * Bootstrap Container class * @cfg {Boolean} jumbotron is it a jumbotron element * @cfg {String} html content of element * @cfg {String} well (lg|sm|md) a well, large, small or medium. * @cfg {String} panel (default|primary|success|info|warning|danger) render as panel - type - primary/success..... * @cfg {String} header content of header (for panel) * @cfg {String} footer content of footer (for panel) * @cfg {String} sticky (footer|wrap|push) block to use as footer or body- needs css-bootstrap/sticky-footer.css * @cfg {String} tag (header|aside|section) type of HTML tag. * @cfg {String} alert (success|info|warning|danger) type alert (changes background / border...) * @cfg {String} fa font awesome icon * @cfg {String} icon (info-sign|check|...) glyphicon name * @cfg {Boolean} hidden (true|false) hide the element * @cfg {Boolean} expandable (true|false) default false * @cfg {Boolean} expanded (true|false) default true * @cfg {String} rheader contet on the right of header * @cfg {Boolean} clickable (true|false) default false * * @constructor * Create a new Container * @param {Object} config The config object */ Roo.bootstrap.Container = function(config){ Roo.bootstrap.Container.superclass.constructor.call(this, config); this.addEvents({ // raw events /** * @event expand * After the panel has been expand * * @param {Roo.bootstrap.Container} this */ "expand" : true, /** * @event collapse * After the panel has been collapsed * * @param {Roo.bootstrap.Container} this */ "collapse" : true, /** * @event click * When a element is chick * @param {Roo.bootstrap.Container} this * @param {Roo.EventObject} e */ "click" : true }); }; Roo.extend(Roo.bootstrap.Container, Roo.bootstrap.Component, { jumbotron : false, well: '', panel : '', header: '', footer : '', sticky: '', tag : false, alert : false, fa: false, icon : false, expandable : false, rheader : '', expanded : true, clickable: false, getChildContainer : function() { if(!this.el){ return false; } if (this.panel.length) { return this.el.select('.panel-body',true).first(); } return this.el; }, getAutoCreate : function(){ var cfg = { tag : this.tag || 'div', html : '', cls : '' }; if (this.jumbotron) { cfg.cls = 'jumbotron'; } // - this is applied by the parent.. //if (this.cls) { // cfg.cls = this.cls + ''; //} if (this.sticky.length) { var bd = Roo.get(document.body); if (!bd.hasClass('bootstrap-sticky')) { bd.addClass('bootstrap-sticky'); Roo.select('html',true).setStyle('height', '100%'); } cfg.cls += 'bootstrap-sticky-' + this.sticky; } if (this.well.length) { switch (this.well) { case 'lg': case 'sm': cfg.cls +=' well well-' +this.well; break; default: cfg.cls +=' well'; break; } } if (this.hidden) { cfg.cls += ' hidden'; } if (this.alert && ["success","info","warning", "danger"].indexOf(this.alert) > -1) { cfg.cls +=' alert alert-' + this.alert; } var body = cfg; if (this.panel.length) { cfg.cls += ' panel panel-' + this.panel; cfg.cn = []; if (this.header.length) { var h = []; if(this.expandable){ cfg.cls = cfg.cls + ' expandable'; h.push({ tag: 'i', cls: (this.expanded ? 'fa fa-minus' : 'fa fa-plus') }); } h.push( { tag: 'span', cls : 'panel-title', html : (this.expandable ? ' ' : '') + this.header }, { tag: 'span', cls: 'panel-header-right', html: this.rheader } ); cfg.cn.push({ cls : 'panel-heading', style : this.expandable ? 'cursor: pointer' : '', cn : h }); } body = false; cfg.cn.push({ cls : 'panel-body' + (this.expanded ? '' : ' hide'), html : this.html }); if (this.footer.length) { cfg.cn.push({ cls : 'panel-footer', html : this.footer }); } } if (body) { body.html = this.html || cfg.html; // prefix with the icons.. if (this.fa) { body.html = '' + body.html ; } if (this.icon) { body.html = '' + body.html ; } } if ((!this.cls || !this.cls.length) && (!cfg.cls || !cfg.cls.length)) { cfg.cls = 'container'; } return cfg; }, initEvents: function() { if(this.expandable){ var headerEl = this.headerEl(); if(headerEl){ headerEl.on('click', this.onToggleClick, this); } } if(this.clickable){ this.el.on('click', this.onClick, this); } }, onToggleClick : function() { var headerEl = this.headerEl(); if(!headerEl){ return; } if(this.expanded){ this.collapse(); return; } this.expand(); }, expand : function() { if(this.fireEvent('expand', this)) { this.expanded = true; //this.el.select('.panel-body',true).first().setVisibilityMode(Roo.Element.DISPLAY).show(); this.el.select('.panel-body',true).first().removeClass('hide'); var toggleEl = this.toggleEl(); if(!toggleEl){ return; } toggleEl.removeClass(['fa-minus', 'fa-plus']).addClass(['fa-minus']); } }, collapse : function() { if(this.fireEvent('collapse', this)) { this.expanded = false; //this.el.select('.panel-body',true).first().setVisibilityMode(Roo.Element.DISPLAY).hide(); this.el.select('.panel-body',true).first().addClass('hide'); var toggleEl = this.toggleEl(); if(!toggleEl){ return; } toggleEl.removeClass(['fa-minus', 'fa-plus']).addClass(['fa-plus']); } }, toggleEl : function() { if(!this.el || !this.panel.length || !this.header.length || !this.expandable){ return; } return this.el.select('.panel-heading .fa',true).first(); }, headerEl : function() { if(!this.el || !this.panel.length || !this.header.length){ return; } return this.el.select('.panel-heading',true).first() }, bodyEl : function() { if(!this.el || !this.panel.length){ return; } return this.el.select('.panel-body',true).first() }, titleEl : function() { if(!this.el || !this.panel.length || !this.header.length){ return; } return this.el.select('.panel-title',true).first(); }, setTitle : function(v) { var titleEl = this.titleEl(); if(!titleEl){ return; } titleEl.dom.innerHTML = v; }, getTitle : function() { var titleEl = this.titleEl(); if(!titleEl){ return ''; } return titleEl.dom.innerHTML; }, setRightTitle : function(v) { var t = this.el.select('.panel-header-right',true).first(); if(!t){ return; } t.dom.innerHTML = v; }, onClick : function(e) { e.preventDefault(); this.fireEvent('click', this, e); } }); /* * - LGPL * * image * */ /** * @class Roo.bootstrap.Img * @extends Roo.bootstrap.Component * Bootstrap Img class * @cfg {Boolean} imgResponsive false | true * @cfg {String} border rounded | circle | thumbnail * @cfg {String} src image source * @cfg {String} alt image alternative text * @cfg {String} href a tag href * @cfg {String} target (_self|_blank|_parent|_top)target for a href. * @cfg {String} xsUrl xs image source * @cfg {String} smUrl sm image source * @cfg {String} mdUrl md image source * @cfg {String} lgUrl lg image source * * @constructor * Create a new Input * @param {Object} config The config object */ Roo.bootstrap.Img = function(config){ Roo.bootstrap.Img.superclass.constructor.call(this, config); this.addEvents({ // img events /** * @event click * The img click event for the img. * @param {Roo.EventObject} e */ "click" : true }); }; Roo.extend(Roo.bootstrap.Img, Roo.bootstrap.Component, { imgResponsive: true, border: '', src: 'about:blank', href: false, target: false, xsUrl: '', smUrl: '', mdUrl: '', lgUrl: '', getAutoCreate : function() { if(this.src || (!this.xsUrl && !this.smUrl && !this.mdUrl && !this.lgUrl)){ return this.createSingleImg(); } var cfg = { tag: 'div', cls: 'roo-image-responsive-group', cn: [] }; var _this = this; Roo.each(['xs', 'sm', 'md', 'lg'], function(size){ if(!_this[size + 'Url']){ return; } var img = { tag: 'img', cls: (_this.imgResponsive) ? 'img-responsive' : '', html: _this.html || cfg.html, src: _this[size + 'Url'] }; img.cls += ' roo-image-responsive-' + size; var s = ['xs', 'sm', 'md', 'lg']; s.splice(s.indexOf(size), 1); Roo.each(s, function(ss){ img.cls += ' hidden-' + ss; }); if (['rounded','circle','thumbnail'].indexOf(_this.border)>-1) { cfg.cls += ' img-' + _this.border; } if(_this.alt){ cfg.alt = _this.alt; } if(_this.href){ var a = { tag: 'a', href: _this.href, cn: [ img ] }; if(this.target){ a.target = _this.target; } } cfg.cn.push((_this.href) ? a : img); }); return cfg; }, createSingleImg : function() { var cfg = { tag: 'img', cls: (this.imgResponsive) ? 'img-responsive' : '', html : null, src : 'about:blank' // just incase src get's set to undefined?!? }; cfg.html = this.html || cfg.html; cfg.src = this.src || cfg.src; if (['rounded','circle','thumbnail'].indexOf(this.border)>-1) { cfg.cls += ' img-' + this.border; } if(this.alt){ cfg.alt = this.alt; } if(this.href){ var a = { tag: 'a', href: this.href, cn: [ cfg ] }; if(this.target){ a.target = this.target; } } return (this.href) ? a : cfg; }, initEvents: function() { if(!this.href){ this.el.on('click', this.onClick, this); } }, onClick : function(e) { Roo.log('img onclick'); this.fireEvent('click', this, e); }, /** * Sets the url of the image - used to update it * @param {String} url the url of the image */ setSrc : function(url) { this.src = url; if(this.src || (!this.xsUrl && !this.smUrl && !this.mdUrl && !this.lgUrl)){ this.el.dom.src = url; return; } this.el.select('img', true).first().dom.src = url; } }); /* * - LGPL * * image * */ /** * @class Roo.bootstrap.Link * @extends Roo.bootstrap.Component * Bootstrap Link Class * @cfg {String} alt image alternative text * @cfg {String} href a tag href * @cfg {String} target (_self|_blank|_parent|_top) target for a href. * @cfg {String} html the content of the link. * @cfg {String} anchor name for the anchor link * @cfg {String} fa - favicon * @cfg {Boolean} preventDefault (true | false) default false * * @constructor * Create a new Input * @param {Object} config The config object */ Roo.bootstrap.Link = function(config){ Roo.bootstrap.Link.superclass.constructor.call(this, config); this.addEvents({ // img events /** * @event click * The img click event for the img. * @param {Roo.EventObject} e */ "click" : true }); }; Roo.extend(Roo.bootstrap.Link, Roo.bootstrap.Component, { href: false, target: false, preventDefault: false, anchor : false, alt : false, fa: false, getAutoCreate : function() { var html = this.html || ''; if (this.fa !== false) { html = ''; } var cfg = { tag: 'a' }; // anchor's do not require html/href... if (this.anchor === false) { cfg.html = html; cfg.href = this.href || '#'; } else { cfg.name = this.anchor; if (this.html !== false || this.fa !== false) { cfg.html = html; } if (this.href !== false) { cfg.href = this.href; } } if(this.alt !== false){ cfg.alt = this.alt; } if(this.target !== false) { cfg.target = this.target; } return cfg; }, initEvents: function() { if(!this.href || this.preventDefault){ this.el.on('click', this.onClick, this); } }, onClick : function(e) { if(this.preventDefault){ e.preventDefault(); } //Roo.log('img onclick'); this.fireEvent('click', this, e); } }); /* * - LGPL * * header * */ /** * @class Roo.bootstrap.Header * @extends Roo.bootstrap.Component * Bootstrap Header class * @cfg {String} html content of header * @cfg {Number} level (1|2|3|4|5|6) default 1 * * @constructor * Create a new Header * @param {Object} config The config object */ Roo.bootstrap.Header = function(config){ Roo.bootstrap.Header.superclass.constructor.call(this, config); }; Roo.extend(Roo.bootstrap.Header, Roo.bootstrap.Component, { //href : false, html : false, level : 1, getAutoCreate : function(){ var cfg = { tag: 'h' + (1 *this.level), html: this.html || '' } ; return cfg; } }); /* * Based on: * Ext JS Library 1.1.1 * Copyright(c) 2006-2007, Ext JS, LLC. * * Originally Released Under LGPL - original licence link has changed is not relivant. * * Fork - LGPL *