/**
* 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
*