* frame: Shadow displays equally on all four sides<br />
* drop: Traditional bottom-right drop shadow (default)
*/
+ mode: false,
/**
* @cfg {String} offset
* The number of pixels to offset the shadow from the element (defaults to 4)
/**
* @class Roo.bootstrap.Component
* @extends Roo.Component
+ * @abstract
+ * @children Roo.bootstrap.Component
* Bootstrap Component base class
* @cfg {String} cls css class
* @cfg {String} style any extra css
}
if (this.cls) {
- cfg.cls = (typeof(cfg.cls) == 'undefined') ? this.cls : cfg.cls + ' ' + 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;
+ cfg.style = (typeof(cfg.style) == 'undefined' ? this.style : cfg.style) + '; ' + this.style;
}
if(this.name){
{
return this.el;
},
+ getDocumentBody : function() // used by menus - as they are attached to the body so zIndexes work
+ {
+ return Roo.get(document.body);
+ },
+
/**
* Fetch the element to display the tooltip on.
* @return {Roo.Element} defaults to this.el
* @cfg {String} cls class of the element
* @cfg {Boolean} preventDefault (true|false) default false
* @cfg {Boolean} clickable (true|false) default false
+ * @cfg {String} role default blank - set to button to force cursor pointer
+
*
* @constructor
* Create a new Element
* @param {Roo.bootstrap.Element} this
* @param {Roo.EventObject} e
*/
- "click" : true
+ "click" : true
+
+
});
};
html: '',
preventDefault: false,
clickable: false,
+ tapedTwice : false,
+ role : false,
getAutoCreate : function(){
// cls: this.cls, double assign in parent class Component.js :: onRender
html: this.html
};
+ if (this.role !== false) {
+ cfg.role = this.role;
+ }
return cfg;
},
this.el.on('click', this.onClick, this);
}
+
},
onClick : function(e)
e.preventDefault();
}
- this.fireEvent('click', this, e);
+ this.fireEvent('click', this, e); // why was this double click before?
},
+
+
+
+
+
getValue : function()
{
return this.el.dom.innerHTML;
/**
* @class Roo.bootstrap.Body
* @extends Roo.bootstrap.Component
+ * @builder-top
+ * @children Roo.bootstrap.Component
+ * @parent none
* Bootstrap Body class
*
* @constructor
{
this.disabled = false;
this.el.removeClass('disabled');
+ this.el.dom.removeAttribute("disabled");
},
/**
{
this.disabled = true;
this.el.addClass('disabled');
+ this.el.attr("disabled", "disabled")
},
/**
* sets the active state on/off,
/**
* @class Roo.bootstrap.Column
* @extends Roo.bootstrap.Component
+ * @children 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
/**
* @class Roo.bootstrap.Container
* @extends Roo.bootstrap.Component
+ * @builder-top
+ * @children Roo.bootstrap.Component
* Bootstrap Container class
* @cfg {Boolean} jumbotron is it a jumbotron element
* @cfg {String} html content of element
/**
* @class Roo.bootstrap.Card
* @extends Roo.bootstrap.Component
+ * @children Roo.bootstrap.Component
* Bootstrap Card class
*
*
/**
* @event rotate
* When a element a card is rotate
- * @param {Roo.bootstrap.Element} this
+ * @param {Roo.bootstrap.Card} this
* @param {Roo.Element} n the node being dropped?
* @param {Boolean} rotate status
*/
- 'rotate' : true
-
+ 'rotate' : true,
+ /**
+ * @event cardover
+ * When a card element is dragged over ready to drop (return false to block dropable)
+ * @param {Roo.bootstrap.Card} this
+ * @param {Object} data from dragdrop
+ */
+ 'cardover' : true
+
});
};
headerEl : false,
header_imageEl : false,
+
layoutCls : function()
{
var cls = '';
if (this.rotateable) {
this.el.select('.card-header',true).on('click', this.onToggleRotate, this);
}
- this.collapsableEl = this.el.select('.roo-collapsable').first();
+ this.collapsableEl = this.el.select('.roo-collapsable',true).first();
- this.footerEl = this.el.select('.card-footer').first();
- this.collapsableToggleEl = this.el.select('.roo-collapse-toggle');
- this.headerContainerEl = this.el.select('.roo-card-header-ctr').first();
+ this.footerEl = this.el.select('.card-footer',true).first();
+ this.collapsableToggleEl = this.el.select('.roo-collapse-toggle',true).first();
+ this.headerContainerEl = this.el.select('.roo-card-header-ctr',true).first();
this.headerEl = this.el.select('.card-header',true).first();
if (this.rotated) {
/**
* Part of the Roo.dd.DropZone interface. If no target node is found, the
* whole Element becomes the target, and this causes the drop gesture to append.
+ *
+ * Returns an object:
+ * {
+
+ position : 'below' or 'above'
+ card : relateive to card OBJECT (or true for no cards listed)
+ items_n : relative to nth item in list
+ card_n : relative to nth card in list
+ }
+ *
+ *
*/
getTargetFromEvent : function(e, dragged_card_el)
{
}
Roo.log(['getTargetFromEvent', target_info ]);
-
+
+ if (this.fireEvent('cardover', this, [ data ]) === false) {
+ return false;
+ }
+
this.dropPlaceHolder('show', target_info,data);
return false;
}
this.dropPlaceHolder('hide');
-
-
-
+
this.acceptCard(data.source, info.position, info.card, info.items_n);
return true;
+
+/*
+* Licence: LGPL
+*/
+
+/**
+ * @class Roo.bootstrap.ButtonUploader
+ * @extends Roo.bootstrap.Button
+ * Bootstrap Button Uploader class - it's a button which when you add files to it
+ *
+ *
+ * @cfg {Number} errorTimeout default 3000
+ * @cfg {Array} images an array of ?? Img objects ??? when loading existing files..
+ * @cfg {Array} html The button text.
+ * @cfg {Boolean} multiple (default true) Should the upload allow multiple files to be uploaded.
+ *
+ * @constructor
+ * Create a new CardUploader
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.ButtonUploader = function(config){
+
+
+
+ Roo.bootstrap.ButtonUploader.superclass.constructor.call(this, config);
+
+
+ this.addEvents({
+ // raw events
+ /**
+ * @event beforeselect
+ * When button is pressed, before show upload files dialog is shown
+ * @param {Roo.bootstrap.UploaderButton} this
+ *
+ */
+ 'beforeselect' : true,
+ /**
+ * @event fired when files have been selected,
+ * When a the download link is clicked
+ * @param {Roo.bootstrap.UploaderButton} this
+ * @param {Array} Array of files that have been uploaded
+ */
+ 'uploaded' : true
+
+ });
+};
+
+Roo.extend(Roo.bootstrap.ButtonUploader, Roo.bootstrap.Button, {
+
+
+ errorTimeout : 3000,
+
+ images : false,
+
+ fileCollection : false,
+ allowBlank : true,
+
+ multiple : true,
+
+ getAutoCreate : function()
+ {
+ var im = {
+ tag: 'input',
+ type : 'file',
+ cls : 'd-none roo-card-upload-selector'
+
+ };
+ if (this.multiple) {
+ im.multiple = 'multiple';
+ }
+
+ return {
+ cls :'div' ,
+ cn : [
+ Roo.bootstrap.Button.prototype.getAutoCreate.call(this),
+ im
+
+ ]
+ };
+
+
+ },
+
+
+ initEvents : function()
+ {
+
+ Roo.bootstrap.Button.prototype.initEvents.call(this);
+
+
+
+
+
+ this.urlAPI = (window.createObjectURL && window) ||
+ (window.URL && URL.revokeObjectURL && URL) ||
+ (window.webkitURL && webkitURL);
+
+
+
+
+ this.selectorEl = this.el.select('.roo-card-upload-selector', true).first();
+
+ this.selectorEl.on('change', this.onFileSelected, this);
+
+
+
+ },
+
+
+ onClick : function(e)
+ {
+ e.preventDefault();
+
+ if ( this.fireEvent('beforeselect', this) === false) {
+ return;
+ }
+
+ this.selectorEl.dom.click();
+
+ },
+
+ onFileSelected : function(e)
+ {
+ e.preventDefault();
+
+ if(typeof(this.selectorEl.dom.files) == 'undefined' || !this.selectorEl.dom.files.length){
+ return;
+ }
+ var files = Array.prototype.slice.call(this.selectorEl.dom.files);
+ this.selectorEl.dom.value = '';// hopefully reset..
+
+ this.fireEvent('uploaded', this, files );
+
+ },
+
+
+
+
+ /**
+ * addCard - add an Attachment to the uploader
+ * @param data - the data about the image to upload
+ *
+ * {
+ id : 123
+ title : "Title of file",
+ is_uploaded : false,
+ src : "http://.....",
+ srcfile : { the File upload object },
+ mimetype : file.type,
+ preview : false,
+ is_deleted : 0
+ .. any other data...
+ }
+ *
+ *
+ */
+
+ reset: function()
+ {
+
+ this.selectorEl
+ }
+
+
+
+
+});
/*
* - LGPL
*
* @cfg {String} smUrl sm image source
* @cfg {String} mdUrl md image source
* @cfg {String} lgUrl lg image source
+ * @cfg {Boolean} backgroundContain (use style background and contain image in content)
*
* @constructor
* Create a new Input
* The img click event for the img.
* @param {Roo.EventObject} e
*/
- "click" : true
+ "click" : true,
+ /**
+ * @event load
+ * The when any image loads
+ * @param {Roo.EventObject} e
+ */
+ "load" : true
});
};
smUrl: '',
mdUrl: '',
lgUrl: '',
+ backgroundContain : false,
getAutoCreate : function()
{
tag: 'img',
cls: (this.imgResponsive) ? 'img-responsive' : '',
html : null,
- src : 'about:blank' // just incase src get's set to undefined?!?
+ src : Roo.BLANK_IMAGE_URL // just incase src get's set to undefined?!?
};
+ if (this.backgroundContain) {
+ cfg.cls += ' background-contain';
+ }
+
cfg.html = this.html || cfg.html;
- cfg.src = this.src || cfg.src;
+ if (this.backgroundContain) {
+ cfg.style="background-image: url(" + this.src + ')';
+ } else {
+ cfg.src = this.src || cfg.src;
+ }
if (['rounded','circle','thumbnail'].indexOf(this.border)>-1) {
cfg.cls += ' img-' + this.border;
if(!this.href){
this.el.on('click', this.onClick, this);
}
+ if(this.src || (!this.xsUrl && !this.smUrl && !this.mdUrl && !this.lgUrl)){
+ this.el.on('load', this.onImageLoad, this);
+ } else {
+ // not sure if this works.. not tested
+ this.el.select('img', true).on('load', this.onImageLoad, this);
+ }
},
Roo.log('img onclick');
this.fireEvent('click', this, e);
},
+ onImageLoad: function(e)
+ {
+ Roo.log('img load');
+ this.fireEvent('load', this, e);
+ },
+
/**
* Sets the url of the image - used to update it
* @param {String} url the url of the image
this.src = url;
if(this.src || (!this.xsUrl && !this.smUrl && !this.mdUrl && !this.lgUrl)){
- this.el.dom.src = url;
+ if (this.backgroundContain) {
+ this.el.dom.style.backgroundImage = 'url(' + url + ')';
+ } else {
+ this.el.dom.src = url;
+ }
return;
}
* @cfg {bool} hidden if the menu should be hidden when rendered.
* @cfg {bool} stopEvent (true|false) Stop event after trigger press (default true)
* @cfg {bool} isLink (true|false) the menu has link disable auto expand and collaspe (default false)
- *
+ * @cfg {bool} hideTrigger (true|false) default false - hide the carret for trigger.
+ * @cfg {String} align default tl-bl? == below - how the menu should be aligned.
+
* @constructor
* Create a new Menu
* @param {Object} config The config object
Roo.bootstrap.Menu = function(config){
+
+ if (config.type == 'treeview') {
+ // normally menu's are drawn attached to the document to handle layering etc..
+ // however treeview (used by the docs menu is drawn into the parent element)
+ this.container_method = 'getChildContainer';
+ }
+
Roo.bootstrap.Menu.superclass.constructor.call(this, config);
if (this.registerMenu && this.type != 'treeview') {
Roo.bootstrap.MenuMgr.register(this);
Roo.extend(Roo.bootstrap.Menu, Roo.bootstrap.Component, {
/// html : false,
- //align : '',
+
triggerEl : false, // is this set by component builder? -- it should really be fetched from parent()???
type: false,
/**
isLink : false,
+ container_method : 'getDocumentBody', // so the menu is rendered on the body and zIndex works.
+
+ hideTrigger : false,
+
+ align : 'tl-bl?',
+
+
getChildContainer : function() {
return this.el;
},
//if (['right'].indexOf(this.align)!==-1) {
// cfg.cn[1].cls += ' pull-right'
//}
-
-
+
var cfg = {
tag : 'ul',
- cls : 'dropdown-menu' ,
+ cls : 'dropdown-menu shadow' ,
style : 'z-index:1000'
};
// Roo.log("ADD event");
// Roo.log(this.triggerEl.dom);
+ if (this.triggerEl) {
+
+ this.triggerEl.on('click', this.onTriggerClick, this);
+
+ this.triggerEl.on(Roo.isTouch ? 'touchstart' : 'mouseup', this.onTriggerPress, this);
+
+ if (!this.hideTrigger) {
+ if (this.triggerEl.hasClass('nav-item') && this.triggerEl.select('.nav-link',true).length) {
+ // dropdown toggle on the 'a' in BS4?
+ this.triggerEl.select('.nav-link',true).first().addClass('dropdown-toggle');
+ } else {
+ this.triggerEl.addClass('dropdown-toggle');
+ }
+ }
+ }
- this.triggerEl.on('click', this.onTriggerClick, this);
-
- this.triggerEl.on(Roo.isTouch ? 'touchstart' : 'mouseup', this.onTriggerPress, this);
-
-
- if (this.triggerEl.hasClass('nav-item')) {
- // dropdown toggle on the 'a' in BS4?
- this.triggerEl.select('.nav-link',true).first().addClass('dropdown-toggle');
- } else {
- this.triggerEl.addClass('dropdown-toggle');
- }
if (Roo.isTouch) {
this.el.on('touchstart' , this.onTouch, this);
}
if(!this.el){
this.render();
}
+ this.el.addClass('show'); // show otherwise we do not know how big we are..
+
+ var xy = this.el.getAlignToXY(el, pos);
+
+ // bl-tl << left align below
+ // tl-bl << left align
+
+ if(this.el.getWidth() + xy[0] >= Roo.lib.Dom.getViewWidth()){
+ // if it goes to far to the right.. -> align left.
+ xy = this.el.getAlignToXY(el, this.align.replace('/l/g', 'r'))
+ }
+ if(xy[0] < 0){
+ // was left align - go right?
+ xy = this.el.getAlignToXY(el, this.align.replace('/r/g', 'l'))
+ }
+
+ // goes down the bottom
+ if(this.el.getHeight() + xy[1] >= Roo.lib.Dom.getViewHeight() ||
+ xy[1] < 0 ){
+ var a = this.align.replace('?', '').split('-');
+ xy = this.el.getAlignToXY(el, a[1] + '-' + a[0] + '?')
+
+ }
- this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);
+ this.showAt( xy , parentMenu, false);
},
/**
* Displays this menu at a specific xy position
//this.el.show();
this.hideMenuItems();
this.hidden = false;
- this.triggerEl.addClass('open');
+ if (this.triggerEl) {
+ this.triggerEl.addClass('open');
+ }
+
this.el.addClass('show');
+
+
// reassign x when hitting right
- if(this.el.getWidth() + xy[0] >= Roo.lib.Dom.getViewWidth()){
- xy[0] = xy[0] - this.el.getWidth() + this.triggerEl.getWidth();
- }
// reassign y when hitting bottom
- if(this.el.getHeight() + xy[1] >= Roo.lib.Dom.getViewHeight()){
- xy[1] = xy[1] - this.el.getHeight() - this.triggerEl.getHeight();
- }
// but the list may align on trigger left or trigger top... should it be a properity?
hide : function(deep)
{
if (false === this.fireEvent("beforehide", this)) {
- Roo.log("hide canceled");
- return;
- }
+ Roo.log("hide canceled");
+ return;
+ }
this.hideMenuItems();
if(this.el && this.isVisible()){
this.activeItem.deactivate();
this.activeItem = null;
}
- this.triggerEl.removeClass('open');;
- this.el.removeClass('show');
+ if (this.triggerEl) {
+ this.triggerEl.removeClass('open');
+ }
+
+ this.el.removeClass('show');
this.hidden = true;
this.fireEvent("hide", this);
}
this.hide();
} else {
Roo.log('show');
- this.show(this.triggerEl, '?', false);
+
+ this.show(this.triggerEl, this.align, false);
}
if(this.stopEvent || e.getTarget().nodeName.toLowerCase() === 'i'){
/**
* @class Roo.bootstrap.Modal
* @extends Roo.bootstrap.Component
+ * @builder-top
+ * @parent none
+ * @children Roo.bootstrap.Component
* Bootstrap Modal class
* @cfg {String} title Title of dialog
* @cfg {String} html - the body of the dialog (for simple ones) - you can also use template..
cfg.href = this.href;
}
if (this.fa) {
- cfg.html = '<i class="fa fas fa-'+this.fa+'"></i> <span>' + this.html + '</span>';
- }
+ cfg.html = '<i class="fa fas fa-'+this.fa+'"></i> <span class="nav-html">' + this.html + '</span>';
+ } else {
+ cfg.cls += " nav-html";
+ }
// menu .. should add dropdown-menu class - so no need for carat..
{
tag: this.tagtype,
href : this.href || "#",
- html: this.html || ''
+ html: this.html || '',
+ cls : ''
}
];
if (this.tagtype == 'a') {
}
if (this.icon) {
- cfg.cn[0].html = '<i class="'+this.icon+'"></i> <span>' + cfg.cn[0].html + '</span>';
- }
- if (this.fa) {
- cfg.cn[0].html = '<i class="fa fas fa-'+this.fa+'"></i> <span>' + cfg.cn[0].html + '</span>';
- }
- if(this.glyphicon) {
+ cfg.cn[0].html = '<i class="'+this.icon+'"></i> <span class="nav-html">' + cfg.cn[0].html + '</span>';
+ } else if (this.fa) {
+ cfg.cn[0].html = '<i class="fa fas fa-'+this.fa+'"></i> <span class="nav-html">' + cfg.cn[0].html + '</span>';
+ } else if(this.glyphicon) {
cfg.cn[0].html = '<span class="glyphicon glyphicon-' + this.glyphicon + '"></span> ' + cfg.cn[0].html;
- }
+ } else {
+ cfg.cn[0].cls += " nav-html";
+ }
if (this.menu) {
-
cfg.cn[0].html += " <span class='caret'></span>";
}
if (this.badge !== '') {
-
cfg.cn[0].html += ' <span class="badge badge-secondary">' + this.badge + '</span>';
}
}
var ret = Roo.bootstrap.NavItem.superclass.onRender.call(this, ct, position);
this.navLink = this.el.select('.nav-link',true).first();
+ this.htmlEl = this.el.hasClass('nav-html') ? this.el : this.el.select('.nav-html',true).first();
return ret;
},
Roo.get(c).scrollTo('top', options.value, true);
return;
- }
+ },
+ /**
+ * Set the HTML (text content) of the item
+ * @param {string} html content for the nav item
+ */
+ setHtml : function(html)
+ {
+ this.html = html;
+ this.htmlEl.dom.innerHTML = html;
+
+ }
});
/**
* @class Roo.bootstrap.Row
* @extends Roo.bootstrap.Component
+ * @children Roo.bootstrap.Component
* Bootstrap Row class (contains columns...)
*
* @constructor
* Fork - LGPL
* <script type="text/javascript">
*/
+ /**
+ * @extends Roo.dd.DDProxy
+ * @class Roo.grid.SplitDragZone
+ * Support for Column Header resizing
+ * @constructor
+ * @param {Object} config
+ */
+// private
+// This is a support class used internally by the Grid components
+Roo.grid.SplitDragZone = function(grid, hd, hd2){
+ this.grid = grid;
+ this.view = grid.getView();
+ this.proxy = this.view.resizeProxy;
+ Roo.grid.SplitDragZone.superclass.constructor.call(
+ this,
+ hd, // ID
+ "gridSplitters" + this.grid.getGridEl().id, // SGROUP
+ { // CONFIG
+ dragElId : Roo.id(this.proxy.dom),
+ resizeFrame:false
+ }
+ );
+
+ this.setHandleElId(Roo.id(hd));
+ if (hd2 !== false) {
+ this.setOuterHandleElId(Roo.id(hd2));
+ }
+
+ this.scroll = false;
+};
+Roo.extend(Roo.grid.SplitDragZone, Roo.dd.DDProxy, {
+ fly: Roo.Element.fly,
+
+ b4StartDrag : function(x, y){
+ this.view.headersDisabled = true;
+ var h = this.view.mainWrap ? this.view.mainWrap.getHeight() : (
+ this.view.headEl.getHeight() + this.view.bodyEl.getHeight()
+ );
+ this.proxy.setHeight(h);
+
+ // for old system colWidth really stored the actual width?
+ // in bootstrap we tried using xs/ms/etc.. to do % sizing?
+ // which in reality did not work.. - it worked only for fixed sizes
+ // for resizable we need to use actual sizes.
+ var w = this.cm.getColumnWidth(this.cellIndex);
+ if (!this.view.mainWrap) {
+ // bootstrap.
+ w = this.view.getHeaderIndex(this.cellIndex).getWidth();
+ }
+
+
+
+ // this was w-this.grid.minColumnWidth;
+ // doesnt really make sense? - w = thie curren width or the rendered one?
+ var minw = Math.max(w-this.grid.minColumnWidth, 0);
+ this.resetConstraints();
+ this.setXConstraint(minw, 1000);
+ this.setYConstraint(0, 0);
+ this.minX = x - minw;
+ this.maxX = x + 1000;
+ this.startPos = x;
+ if (!this.view.mainWrap) { // this is Bootstrap code..
+ this.getDragEl().style.display='block';
+ }
+
+ Roo.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
+ },
+
+
+ handleMouseDown : function(e){
+ ev = Roo.EventObject.setEvent(e);
+ var t = this.fly(ev.getTarget());
+ if(t.hasClass("x-grid-split")){
+ this.cellIndex = this.view.getCellIndex(t.dom);
+ this.split = t.dom;
+ this.cm = this.grid.colModel;
+ if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
+ Roo.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
+ }
+ }
+ },
+
+ endDrag : function(e){
+ this.view.headersDisabled = false;
+ var endX = Math.max(this.minX, Roo.lib.Event.getPageX(e));
+ var diff = endX - this.startPos;
+ //
+ var w = this.cm.getColumnWidth(this.cellIndex);
+ if (!this.view.mainWrap) {
+ w = 0;
+ }
+ this.view.onColumnSplitterMoved(this.cellIndex, w+diff);
+ },
+
+ autoOffset : function(){
+ this.setDelta(0,0);
+ }
+});/*
+ * 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
+ * <script type="text/javascript">
+ */
+
+/**
+ * @class Roo.grid.AbstractSelectionModel
+ * @extends Roo.util.Observable
+ * @abstract
+ * Abstract base class for grid SelectionModels. It provides the interface that should be
+ * implemented by descendant classes. This class should not be directly instantiated.
+ * @constructor
+ */
+Roo.grid.AbstractSelectionModel = function(){
+ this.locked = false;
+ Roo.grid.AbstractSelectionModel.superclass.constructor.call(this);
+};
+
+Roo.extend(Roo.grid.AbstractSelectionModel, Roo.util.Observable, {
+ /** @ignore Called by the grid automatically. Do not call directly. */
+ init : function(grid){
+ this.grid = grid;
+ this.initEvents();
+ },
+
+ /**
+ * Locks the selections.
+ */
+ lock : function(){
+ this.locked = true;
+ },
+
+ /**
+ * Unlocks the selections.
+ */
+ unlock : function(){
+ this.locked = false;
+ },
+
+ /**
+ * Returns true if the selections are locked.
+ * @return {Boolean}
+ */
+ isLocked : function(){
+ return this.locked;
+ }
+});/*
+ * 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
+ * <script type="text/javascript">
+ */
+/**
+ * @extends Roo.grid.AbstractSelectionModel
+ * @class Roo.grid.RowSelectionModel
+ * The default SelectionModel used by {@link Roo.grid.Grid}.
+ * It supports multiple selections and keyboard selection/navigation.
+ * @constructor
+ * @param {Object} config
+ */
+Roo.grid.RowSelectionModel = function(config){
+ Roo.apply(this, config);
+ this.selections = new Roo.util.MixedCollection(false, function(o){
+ return o.id;
+ });
+
+ this.last = false;
+ this.lastActive = false;
+
+ this.addEvents({
+ /**
+ * @event selectionchange
+ * Fires when the selection changes
+ * @param {SelectionModel} this
+ */
+ "selectionchange" : true,
+ /**
+ * @event afterselectionchange
+ * Fires after the selection changes (eg. by key press or clicking)
+ * @param {SelectionModel} this
+ */
+ "afterselectionchange" : true,
+ /**
+ * @event beforerowselect
+ * Fires when a row is selected being selected, return false to cancel.
+ * @param {SelectionModel} this
+ * @param {Number} rowIndex The selected index
+ * @param {Boolean} keepExisting False if other selections will be cleared
+ */
+ "beforerowselect" : true,
+ /**
+ * @event rowselect
+ * Fires when a row is selected.
+ * @param {SelectionModel} this
+ * @param {Number} rowIndex The selected index
+ * @param {Roo.data.Record} r The record
+ */
+ "rowselect" : true,
+ /**
+ * @event rowdeselect
+ * Fires when a row is deselected.
+ * @param {SelectionModel} this
+ * @param {Number} rowIndex The selected index
+ */
+ "rowdeselect" : true
+ });
+ Roo.grid.RowSelectionModel.superclass.constructor.call(this);
+ this.locked = false;
+};
+
+Roo.extend(Roo.grid.RowSelectionModel, Roo.grid.AbstractSelectionModel, {
+ /**
+ * @cfg {Boolean} singleSelect
+ * True to allow selection of only one row at a time (defaults to false)
+ */
+ singleSelect : false,
+
+ // private
+ initEvents : function(){
+
+ if(!this.grid.enableDragDrop && !this.grid.enableDrag){
+ this.grid.on("mousedown", this.handleMouseDown, this);
+ }else{ // allow click to work like normal
+ this.grid.on("rowclick", this.handleDragableRowClick, this);
+ }
+ // bootstrap does not have a view..
+ var view = this.grid.view ? this.grid.view : this.grid;
+ this.rowNav = new Roo.KeyNav(this.grid.getGridEl(), {
+ "up" : function(e){
+ if(!e.shiftKey){
+ this.selectPrevious(e.shiftKey);
+ }else if(this.last !== false && this.lastActive !== false){
+ var last = this.last;
+ this.selectRange(this.last, this.lastActive-1);
+ view.focusRow(this.lastActive);
+ if(last !== false){
+ this.last = last;
+ }
+ }else{
+ this.selectFirstRow();
+ }
+ this.fireEvent("afterselectionchange", this);
+ },
+ "down" : function(e){
+ if(!e.shiftKey){
+ this.selectNext(e.shiftKey);
+ }else if(this.last !== false && this.lastActive !== false){
+ var last = this.last;
+ this.selectRange(this.last, this.lastActive+1);
+ view.focusRow(this.lastActive);
+ if(last !== false){
+ this.last = last;
+ }
+ }else{
+ this.selectFirstRow();
+ }
+ this.fireEvent("afterselectionchange", this);
+ },
+ scope: this
+ });
+
+
+ view.on("refresh", this.onRefresh, this);
+ view.on("rowupdated", this.onRowUpdated, this);
+ view.on("rowremoved", this.onRemove, this);
+ },
+
+ // private
+ onRefresh : function(){
+ var ds = this.grid.ds, i, v = this.grid.view;
+ var s = this.selections;
+ s.each(function(r){
+ if((i = ds.indexOfId(r.id)) != -1){
+ v.onRowSelect(i);
+ s.add(ds.getAt(i)); // updating the selection relate data
+ }else{
+ s.remove(r);
+ }
+ });
+ },
+
+ // private
+ onRemove : function(v, index, r){
+ this.selections.remove(r);
+ },
+
+ // private
+ onRowUpdated : function(v, index, r){
+ if(this.isSelected(r)){
+ v.onRowSelect(index);
+ }
+ },
+
+ /**
+ * Select records.
+ * @param {Array} records The records to select
+ * @param {Boolean} keepExisting (optional) True to keep existing selections
+ */
+ selectRecords : function(records, keepExisting){
+ if(!keepExisting){
+ this.clearSelections();
+ }
+ var ds = this.grid.ds;
+ for(var i = 0, len = records.length; i < len; i++){
+ this.selectRow(ds.indexOf(records[i]), true);
+ }
+ },
+
+ /**
+ * Gets the number of selected rows.
+ * @return {Number}
+ */
+ getCount : function(){
+ return this.selections.length;
+ },
+
+ /**
+ * Selects the first row in the grid.
+ */
+ selectFirstRow : function(){
+ this.selectRow(0);
+ },
+
+ /**
+ * Select the last row.
+ * @param {Boolean} keepExisting (optional) True to keep existing selections
+ */
+ selectLastRow : function(keepExisting){
+ this.selectRow(this.grid.ds.getCount() - 1, keepExisting);
+ },
+
+ /**
+ * Selects the row immediately following the last selected row.
+ * @param {Boolean} keepExisting (optional) True to keep existing selections
+ */
+ selectNext : function(keepExisting){
+ if(this.last !== false && (this.last+1) < this.grid.ds.getCount()){
+ this.selectRow(this.last+1, keepExisting);
+ var view = this.grid.view ? this.grid.view : this.grid;
+ view.focusRow(this.last);
+ }
+ },
+
+ /**
+ * Selects the row that precedes the last selected row.
+ * @param {Boolean} keepExisting (optional) True to keep existing selections
+ */
+ selectPrevious : function(keepExisting){
+ if(this.last){
+ this.selectRow(this.last-1, keepExisting);
+ var view = this.grid.view ? this.grid.view : this.grid;
+ view.focusRow(this.last);
+ }
+ },
+
+ /**
+ * Returns the selected records
+ * @return {Array} Array of selected records
+ */
+ getSelections : function(){
+ return [].concat(this.selections.items);
+ },
+
+ /**
+ * Returns the first selected record.
+ * @return {Record}
+ */
+ getSelected : function(){
+ return this.selections.itemAt(0);
+ },
+
+
+ /**
+ * Clears all selections.
+ */
+ clearSelections : function(fast){
+ if(this.locked) {
+ return;
+ }
+ if(fast !== true){
+ var ds = this.grid.ds;
+ var s = this.selections;
+ s.each(function(r){
+ this.deselectRow(ds.indexOfId(r.id));
+ }, this);
+ s.clear();
+ }else{
+ this.selections.clear();
+ }
+ this.last = false;
+ },
+
+
+ /**
+ * Selects all rows.
+ */
+ selectAll : function(){
+ if(this.locked) {
+ return;
+ }
+ this.selections.clear();
+ for(var i = 0, len = this.grid.ds.getCount(); i < len; i++){
+ this.selectRow(i, true);
+ }
+ },
+
+ /**
+ * Returns True if there is a selection.
+ * @return {Boolean}
+ */
+ hasSelection : function(){
+ return this.selections.length > 0;
+ },
+
+ /**
+ * Returns True if the specified row is selected.
+ * @param {Number/Record} record The record or index of the record to check
+ * @return {Boolean}
+ */
+ isSelected : function(index){
+ var r = typeof index == "number" ? this.grid.ds.getAt(index) : index;
+ return (r && this.selections.key(r.id) ? true : false);
+ },
+
+ /**
+ * Returns True if the specified record id is selected.
+ * @param {String} id The id of record to check
+ * @return {Boolean}
+ */
+ isIdSelected : function(id){
+ return (this.selections.key(id) ? true : false);
+ },
+
+ // private
+ handleMouseDown : function(e, t)
+ {
+ var view = this.grid.view ? this.grid.view : this.grid;
+ var rowIndex;
+ if(this.isLocked() || (rowIndex = view.findRowIndex(t)) === false){
+ return;
+ };
+ if(e.shiftKey && this.last !== false){
+ var last = this.last;
+ this.selectRange(last, rowIndex, e.ctrlKey);
+ this.last = last; // reset the last
+ view.focusRow(rowIndex);
+ }else{
+ var isSelected = this.isSelected(rowIndex);
+ if(e.button !== 0 && isSelected){
+ view.focusRow(rowIndex);
+ }else if(e.ctrlKey && isSelected){
+ this.deselectRow(rowIndex);
+ }else if(!isSelected){
+ this.selectRow(rowIndex, e.button === 0 && (e.ctrlKey || e.shiftKey));
+ view.focusRow(rowIndex);
+ }
+ }
+ this.fireEvent("afterselectionchange", this);
+ },
+ // private
+ handleDragableRowClick : function(grid, rowIndex, e)
+ {
+ if(e.button === 0 && !e.shiftKey && !e.ctrlKey) {
+ this.selectRow(rowIndex, false);
+ var view = this.grid.view ? this.grid.view : this.grid;
+ view.focusRow(rowIndex);
+ this.fireEvent("afterselectionchange", this);
+ }
+ },
+
+ /**
+ * Selects multiple rows.
+ * @param {Array} rows Array of the indexes of the row to select
+ * @param {Boolean} keepExisting (optional) True to keep existing selections
+ */
+ selectRows : function(rows, keepExisting){
+ if(!keepExisting){
+ this.clearSelections();
+ }
+ for(var i = 0, len = rows.length; i < len; i++){
+ this.selectRow(rows[i], true);
+ }
+ },
+
+ /**
+ * Selects a range of rows. All rows in between startRow and endRow are also selected.
+ * @param {Number} startRow The index of the first row in the range
+ * @param {Number} endRow The index of the last row in the range
+ * @param {Boolean} keepExisting (optional) True to retain existing selections
+ */
+ selectRange : function(startRow, endRow, keepExisting){
+ if(this.locked) {
+ return;
+ }
+ if(!keepExisting){
+ this.clearSelections();
+ }
+ if(startRow <= endRow){
+ for(var i = startRow; i <= endRow; i++){
+ this.selectRow(i, true);
+ }
+ }else{
+ for(var i = startRow; i >= endRow; i--){
+ this.selectRow(i, true);
+ }
+ }
+ },
+
+ /**
+ * Deselects a range of rows. All rows in between startRow and endRow are also deselected.
+ * @param {Number} startRow The index of the first row in the range
+ * @param {Number} endRow The index of the last row in the range
+ */
+ deselectRange : function(startRow, endRow, preventViewNotify){
+ if(this.locked) {
+ return;
+ }
+ for(var i = startRow; i <= endRow; i++){
+ this.deselectRow(i, preventViewNotify);
+ }
+ },
+
+ /**
+ * Selects a row.
+ * @param {Number} row The index of the row to select
+ * @param {Boolean} keepExisting (optional) True to keep existing selections
+ */
+ selectRow : function(index, keepExisting, preventViewNotify){
+ if(this.locked || (index < 0 || index >= this.grid.ds.getCount())) {
+ return;
+ }
+ if(this.fireEvent("beforerowselect", this, index, keepExisting) !== false){
+ if(!keepExisting || this.singleSelect){
+ this.clearSelections();
+ }
+ var r = this.grid.ds.getAt(index);
+ this.selections.add(r);
+ this.last = this.lastActive = index;
+ if(!preventViewNotify){
+ var view = this.grid.view ? this.grid.view : this.grid;
+ view.onRowSelect(index);
+ }
+ this.fireEvent("rowselect", this, index, r);
+ this.fireEvent("selectionchange", this);
+ }
+ },
+
+ /**
+ * Deselects a row.
+ * @param {Number} row The index of the row to deselect
+ */
+ deselectRow : function(index, preventViewNotify){
+ if(this.locked) {
+ return;
+ }
+ if(this.last == index){
+ this.last = false;
+ }
+ if(this.lastActive == index){
+ this.lastActive = false;
+ }
+ var r = this.grid.ds.getAt(index);
+ this.selections.remove(r);
+ if(!preventViewNotify){
+ var view = this.grid.view ? this.grid.view : this.grid;
+ view.onRowDeselect(index);
+ }
+ this.fireEvent("rowdeselect", this, index);
+ this.fireEvent("selectionchange", this);
+ },
+
+ // private
+ restoreLast : function(){
+ if(this._last){
+ this.last = this._last;
+ }
+ },
+
+ // private
+ acceptsNav : function(row, col, cm){
+ return !cm.isHidden(col) && cm.isCellEditable(col, row);
+ },
+
+ // private
+ onEditorKey : function(field, e){
+ var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
+ if(k == e.TAB){
+ e.stopEvent();
+ ed.completeEdit();
+ if(e.shiftKey){
+ newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
+ }else{
+ newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
+ }
+ }else if(k == e.ENTER && !e.ctrlKey){
+ e.stopEvent();
+ ed.completeEdit();
+ if(e.shiftKey){
+ newCell = g.walkCells(ed.row-1, ed.col, -1, this.acceptsNav, this);
+ }else{
+ newCell = g.walkCells(ed.row+1, ed.col, 1, this.acceptsNav, this);
+ }
+ }else if(k == e.ESC){
+ ed.cancelEdit();
+ }
+ if(newCell){
+ g.startEditing(newCell[0], newCell[1]);
+ }
+ }
+});/*
+ * 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
+ * <script type="text/javascript">
+ */
/**
/**
* The config passed into the constructor
*/
- this.config = config;
+ this.config = []; //config;
this.lookup = {};
// if no id, create one
// if the column does not have a dataIndex mapping,
// map it to the order it is in the config
for(var i = 0, len = config.length; i < len; i++){
- var c = config[i];
- if(typeof c.dataIndex == "undefined"){
- c.dataIndex = i;
- }
- if(typeof c.renderer == "string"){
- c.renderer = Roo.util.Format[c.renderer];
- }
- if(typeof c.id == "undefined"){
- c.id = Roo.id();
- }
- if(c.editor && c.editor.xtype){
- c.editor = Roo.factory(c.editor, Roo.grid);
- }
- if(c.editor && c.editor.isFormField){
- c.editor = new Roo.grid.GridEditor(c.editor);
- }
- this.lookup[c.id] = c;
+ this.addColumn(config[i]);
+
}
/**
Roo.extend(Roo.grid.ColumnModel, Roo.util.Observable, {
/**
* @cfg {String} header The header text to display in the Grid view.
+ */
+ /**
+ * @cfg {String} xsHeader Header at Bootsrap Extra Small width (default for all)
+ */
+ /**
+ * @cfg {String} smHeader Header at Bootsrap Small width
+ */
+ /**
+ * @cfg {String} mdHeader Header at Bootsrap Medium width
+ */
+ /**
+ * @cfg {String} lgHeader Header at Bootsrap Large width
+ */
+ /**
+ * @cfg {String} xlHeader Header at Bootsrap extra Large width
*/
/**
* @cfg {String} dataIndex (Optional) The name of the field in the grid's {@link Roo.data.Store}'s
* @cfg {String} tooltip (Optional)
*/
/**
- * @cfg {Number} xs (Optional)
+ * @cfg {Number} xs (Optional) can be '0' for hidden at this size (number less than 12)
*/
/**
- * @cfg {Number} sm (Optional)
+ * @cfg {Number} sm (Optional) can be '0' for hidden at this size (number less than 12)
*/
/**
- * @cfg {Number} md (Optional)
+ * @cfg {Number} md (Optional) can be '0' for hidden at this size (number less than 12)
*/
/**
- * @cfg {Number} lg (Optional)
+ * @cfg {Number} lg (Optional) can be '0' for hidden at this size (number less than 12)
+ */
+ /**
+ * @cfg {Number} xl (Optional) can be '0' for hidden at this size (number less than 12)
*/
/**
* Returns the id of the column at the specified index.
/**
- * Returns the column for a specified dataIndex.
+ * Returns the column Object for a specified dataIndex.
* @param {String} dataIndex The column dataIndex
* @return {Object|Boolean} the column or false if not found
*/
/**
* Returns the width for the specified column.
* @param {Number} col The column index
+ * @param (optional) {String} gridSize bootstrap width size.
* @return {Number}
*/
- getColumnWidth : function(col){
- return this.config[col].width * 1 || this.defaultWidth;
+ getColumnWidth : function(col, gridSize)
+ {
+ var cfg = this.config[col];
+
+ if (typeof(gridSize) == 'undefined') {
+ return cfg.width * 1 || this.defaultWidth;
+ }
+ if (gridSize === false) { // if we set it..
+ return cfg.width || false;
+ }
+ var sizes = ['xl', 'lg', 'md', 'sm', 'xs'];
+
+ for(var i = sizes.indexOf(gridSize); i < sizes.length; i++) {
+ if (typeof(cfg[ sizes[i] ] ) == 'undefined') {
+ continue;
+ }
+ return cfg[ sizes[i] ];
+ }
+ return 1;
+
},
/**
*/
setEditor : function(col, editor){
this.config[col].editor = editor;
+ },
+ /**
+ * Add a column (experimental...) - defaults to adding to the end..
+ * @param {Object} config
+ */
+ addColumn : function(c)
+ {
+
+ var i = this.config.length;
+ this.config[i] = c;
+
+ if(typeof c.dataIndex == "undefined"){
+ c.dataIndex = i;
+ }
+ if(typeof c.renderer == "string"){
+ c.renderer = Roo.util.Format[c.renderer];
+ }
+ if(typeof c.id == "undefined"){
+ c.id = Roo.id();
+ }
+ if(c.editor && c.editor.xtype){
+ c.editor = Roo.factory(c.editor, Roo.grid);
+ }
+ if(c.editor && c.editor.isFormField){
+ c.editor = new Roo.grid.GridEditor(c.editor);
+ }
+ this.lookup[c.id] = c;
}
+
});
Roo.grid.ColumnModel.defaultRenderer = function(value)
* True to create a single-use mask that is automatically destroyed after loading (useful for page loads),
* False to persist the mask element reference for multiple uses (e.g., for paged data widgets). Defaults to false.
*/
+ removeMask : false,
/**
* @cfg {String} msg
* The text to display in a centered loading message box (defaults to 'Loading...')
um.un('failure', this.onLoad, this);
}
}
-};/*
- * - LGPL
- *
- * table
- *
- */
-
-/**
+};/**
* @class Roo.bootstrap.Table
+ * @licence LGBL
* @extends Roo.bootstrap.Component
- * Bootstrap Table class
+ * Bootstrap Table class. This class represents the primary interface of a component based grid control.
+ * Similar to Roo.grid.Grid
+ * <pre><code>
+ var table = Roo.factory({
+ xtype : 'Table',
+ xns : Roo.bootstrap,
+ autoSizeColumns: true,
+
+
+ store : {
+ xtype : 'Store',
+ xns : Roo.data,
+ remoteSort : true,
+ sortInfo : { direction : 'ASC', field: 'name' },
+ proxy : {
+ xtype : 'HttpProxy',
+ xns : Roo.data,
+ method : 'GET',
+ url : 'https://example.com/some.data.url.json'
+ },
+ reader : {
+ xtype : 'JsonReader',
+ xns : Roo.data,
+ fields : [ 'id', 'name', whatever' ],
+ id : 'id',
+ root : 'data'
+ }
+ },
+ cm : [
+ {
+ xtype : 'ColumnModel',
+ xns : Roo.grid,
+ align : 'center',
+ cursor : 'pointer',
+ dataIndex : 'is_in_group',
+ header : "Name",
+ sortable : true,
+ renderer : function(v, x , r) {
+
+ return String.format("{0}", v)
+ }
+ width : 3
+ } // more columns..
+ ],
+ selModel : {
+ xtype : 'RowSelectionModel',
+ xns : Roo.bootstrap.Table
+ // you can add listeners to catch selection change here....
+ }
+
+
+ });
+ // set any options
+ grid.render(Roo.get("some-div"));
+</code></pre>
+
+Currently the Table uses multiple headers to try and handle XL / Medium etc... styling
+
+
+
+ *
+ * @cfg {Roo.grid.AbstractSelectionModel} sm The selection model to use (cell selection is not supported yet)
+ * @cfg {Roo.data.Store} store The data store to use
+ * @cfg {Roo.grid.ColumnModel} cm[] A column for th grid.
+ *
* @cfg {String} cls table class
- * @cfg {String} align (left|center|right) Specifies the alignment of a table according to surrounding text
- * @cfg {String} bgcolor Specifies the background color for a table
- * @cfg {Number} border Specifies whether the table cells should have borders or not
- * @cfg {Number} cellpadding Specifies the space between the cell wall and the cell content
- * @cfg {Number} cellspacing Specifies the space between cells
- * @cfg {String} frame Specifies which parts of the outside borders that should be visible
- * @cfg {String} rules Specifies which parts of the inside borders that should be visible
- * @cfg {String} sortable Specifies that the table should be sortable
- * @cfg {String} summary Specifies a summary of the content of a table
- * @cfg {Number} width Specifies the width of a table
- * @cfg {String} layout table layout (auto | fixed | initial | inherit)
+ *
*
* @cfg {boolean} striped Should the rows be alternative striped
* @cfg {boolean} bordered Add borders to the table
* @cfg {boolean} hover Add hover highlighting
* @cfg {boolean} condensed Format condensed
- * @cfg {boolean} responsive Format condensed
+ * @cfg {boolean} responsive default false - if this is on, columns are rendered with col-xs-4 etc. classes, otherwise columns will be sized by CSS,
+ * also adds table-responsive (see bootstrap docs for details)
* @cfg {Boolean} loadMask (true|false) default false
* @cfg {Boolean} footerShow (true|false) generate tfoot, default true
* @cfg {Boolean} headerShow (true|false) generate thead, default true
* @cfg {Roo.bootstrap.PagingToolbar} footer a paging toolbar
* @cfg {Boolean} lazyLoad auto load data while scrolling to the end (default false)
* @cfg {Boolean} auto_hide_footer auto hide footer if only one page (default false)
-
+ * @cfg {Boolean} enableColumnResize default true if columns can be resized (drag/drop)
+ * @cfg {Number} minColumnWidth default 50 pixels minimum column width
*
* @constructor
* Create a new Table
* @param {Object} config The config object
*/
-Roo.bootstrap.Table = function(config){
+Roo.bootstrap.Table = function(config)
+{
Roo.bootstrap.Table.superclass.constructor.call(this, config);
-
-
-
+
// BC...
this.rowSelection = (typeof(config.rowSelection) != 'undefined') ? config.rowSelection : this.rowSelection;
this.cellSelection = (typeof(config.cellSelection) != 'undefined') ? config.cellSelection : this.cellSelection;
this.headerShow = (typeof(config.thead) != 'undefined') ? config.thead : this.headerShow;
this.footerShow = (typeof(config.tfoot) != 'undefined') ? config.tfoot : this.footerShow;
+ this.view = this; // compat with grid.
+
this.sm = this.sm || {xtype: 'RowSelectionModel'};
if (this.sm) {
this.sm.grid = this;
- this.selModel = Roo.factory(this.sm, Roo.bootstrap.Table);
+ this.selModel = Roo.factory(this.sm, Roo.grid);
this.sm = this.selModel;
this.sm.xmodule = this.xmodule || false;
}
* @param {Number} columnIndex
* @param {Roo.EventObject} e
*/
- "headercontextmenu" : true
+ "headercontextmenu" : true,
+ /**
+ * @event mousedown
+ * The raw mousedown event for the entire grid.
+ * @param {Roo.EventObject} e
+ */
+ "mousedown" : true
+
});
};
Roo.extend(Roo.bootstrap.Table, Roo.bootstrap.Component, {
cls: false,
- align: false,
- bgcolor: false,
- border: false,
- cellpadding: false,
- cellspacing: false,
- frame: false,
- rules: false,
- sortable: false,
- summary: false,
- width: false,
+
striped : false,
scrollBody : false,
bordered: false,
loadMask : false,
footerShow : true,
headerShow : true,
+ enableColumnResize: true,
rowSelection : false,
cellSelection : false,
layout : false,
+
+ minColumnWidth : 50,
// Roo.Element - the tbody
- mainBody: false,
- // Roo.Element - thead element
- mainHead: false,
+ bodyEl: false, // <tbody> Roo.Element - thead element
+ headEl: false, // <thead> Roo.Element - thead element
+ resizeProxy : false, // proxy element for dragging?
+
+
container: false, // used by gridpanel...
auto_hide_footer : false,
+ view: false, // actually points to this..
+
getAutoCreate : function()
{
var cfg = Roo.apply({}, Roo.bootstrap.Table.superclass.getAutoCreate.call(this));
cfg = {
tag: 'table',
- cls : 'table',
+ cls : 'table',
cn : []
};
+ // this get's auto added by panel.Grid
if (this.scrollBody) {
cfg.cls += ' table-body-fixed';
}
if (this.condensed) {
cfg.cls += ' table-condensed';
}
+
if (this.responsive) {
cfg.cls += ' table-responsive';
}
cfg.cls+= ' ' +this.cls;
}
- // this lot should be simplifed...
- var _t = this;
- var cp = [
- 'align',
- 'bgcolor',
- 'border',
- 'cellpadding',
- 'cellspacing',
- 'frame',
- 'rules',
- 'sortable',
- 'summary',
- 'width'
- ].forEach(function(k) {
- if (_t[k]) {
- cfg[k] = _t[k];
- }
- });
if (this.layout) {
//Roo.log('initEvents with ds!!!!');
- this.mainBody = this.el.select('tbody', true).first();
- this.mainHead = this.el.select('thead', true).first();
+ this.bodyEl = this.el.select('tbody', true).first();
+ this.headEl = this.el.select('thead', true).first();
this.mainFoot = this.el.select('tfoot', true).first();
- var _this = this;
Roo.each(this.el.select('thead th.sortable', true).elements, function(e){
- e.on('click', _this.sort, _this);
- });
+ e.on('click', this.sort, this);
+ }, this);
- this.mainBody.on("click", this.onClick, this);
- this.mainBody.on("dblclick", this.onDblClick, this);
// why is this done????? = it breaks dialogs??
//this.parent().el.setStyle('position', 'relative');
this.el.on("contextmenu", this.onContextMenu, this);
- this.mainBody.on('scroll', this.onBodyScroll, this);
this.cm.on("headerchange", this.onHeaderChange, this);
-
this.cm.on("hiddenchange", this.onHiddenChange, this, arguments);
+
+ //?? does bodyEl get replaced on render?
+ this.bodyEl.on("click", this.onClick, this);
+ this.bodyEl.on("dblclick", this.onDblClick, this);
+ this.bodyEl.on('scroll', this.onBodyScroll, this);
+
+ // guessing mainbody will work - this relays usually caught by selmodel at present.
+ this.relayEvents(this.bodyEl, ["mousedown","mouseup","mouseover","mouseout","keypress"]);
+
+
+ this.resizeProxy = Roo.get(document.body).createChild({ cls:"x-grid-resize-proxy", html: ' ' });
+
+ if(this.headEl && this.enableColumnResize !== false && Roo.grid.SplitDragZone){
+ new Roo.grid.SplitDragZone(this, this.headEl.dom, false); // not sure what 'lockedHd is for this implementation..)
+ }
+
+ this.initCSS();
+ },
+ // Compatibility with grid - we implement all the view features at present.
+ getView : function()
+ {
+ return this;
},
+ initCSS : function()
+ {
+
+
+ var cm = this.cm, styles = [];
+ this.CSS.removeStyleSheet(this.id + '-cssrules');
+ var headHeight = this.headEl ? this.headEl.dom.clientHeight : 0;
+ // we can honour xs/sm/md/xl as widths...
+ // we first have to decide what widht we are currently at...
+ var sz = Roo.getGridSize();
+
+ var total = 0;
+ var last = -1;
+ var cols = []; // visable cols.
+ var total_abs = 0;
+ for(var i = 0, len = cm.getColumnCount(); i < len; i++) {
+ var w = cm.getColumnWidth(i, false);
+ if(cm.isHidden(i)){
+ cols.push( { rel : false, abs : 0 });
+ continue;
+ }
+ if (w !== false) {
+ cols.push( { rel : false, abs : w });
+ total_abs += w;
+ last = i; // not really..
+ continue;
+ }
+ var w = cm.getColumnWidth(i, sz);
+ if (w > 0) {
+ last = i
+ }
+ total += w;
+ cols.push( { rel : w, abs : false });
+ }
+
+ var avail = this.bodyEl.dom.clientWidth - total_abs;
+
+ var unitWidth = Math.floor(avail / total);
+ var rem = avail - (unitWidth * total);
+
+ var hidden, width, pos = 0 , splithide , left;
+ for(var i = 0, len = cm.getColumnCount(); i < len; i++) {
+
+ hidden = 'display:none;';
+ left = '';
+ width = 'width:0px;';
+ splithide = '';
+ if(!cm.isHidden(i)){
+ hidden = '';
+
+
+ // we can honour xs/sm/md/xl ?
+ var w = cols[i].rel == false ? cols[i].abs : (cols[i].rel * unitWidth);
+ if (w===0) {
+ hidden = 'display:none;';
+ }
+ // width should return a small number...
+ if (i == last) {
+ w+=rem; // add the remaining with..
+ }
+ pos += w;
+ left = "left:" + (pos -4) + "px;";
+ width = "width:" + w+ "px;";
+
+ }
+ if (this.responsive) {
+ width = '';
+ left = '';
+ hidden = cm.isHidden(i) ? 'display:none;' : '';
+ splithide = 'display: none;';
+ }
+
+ styles.push( '#' , this.id , ' .x-col-' , i, " {", cm.config[i].css, width, hidden, "}\n" );
+ if (this.headEl) {
+ if (i == last) {
+ splithide = 'display:none;';
+ }
+
+ styles.push('#' , this.id , ' .x-hcol-' , i, " { ", width, hidden," }\n",
+ '#' , this.id , ' .x-grid-split-' , i, " { ", left, splithide,'height:', (headHeight - 4), "px;}\n"
+ );
+ }
+
+ }
+ //Roo.log(styles.join(''));
+ this.CSS.createStyleSheet( styles.join(''), this.id + '-cssrules');
+
+ },
+
+
+
onContextMenu : function(e, t)
{
this.processEvent("contextmenu", e);
var rowIndex = this.getRowIndex(row);
// why??? - should these not be based on SelectionModel?
- if(this.cellSelection){
+ //if(this.cellSelection){
this.fireEvent('cellclick', this, cell, rowIndex, cellIndex, e);
- }
+ //}
- if(this.rowSelection){
+ //if(this.rowSelection){
this.fireEvent('rowclick', this, row, rowIndex, e);
- }
-
-
+ //}
+
},
onDblClick : function(e,el)
this.fireEvent('rowdblclick', this, row, rowIndex, e);
}
},
-
+ findRowIndex : function(el)
+ {
+ var cell = Roo.get(el);
+ if(!cell) {
+ return false;
+ }
+ var row = cell.findParent('tr', false, true);
+
+ if(!row || typeof(row) == 'undefined'){
+ return false;
+ }
+ return this.getRowIndex(row);
+ },
sort : function(e,el)
{
var col = Roo.get(el);
var sort = col.attr('sort');
var dir = 'ASC';
- if(col.select('i', true).first().hasClass('glyphicon-arrow-up')){
+ if(col.select('i', true).first().hasClass('fa-arrow-up')){
dir = 'DESC';
}
tag: 'th',
cls : 'x-hcol-' + i,
style : '',
+
html: cm.getColumnHeader(i)
};
+ var tooltip = cm.getColumnTooltip(i);
+ if (tooltip) {
+ c.tooltip = tooltip;
+ }
+
+
var hh = '';
if(typeof(config.sortable) != 'undefined' && config.sortable){
- c.cls = 'sortable';
- c.html = '<i class="glyphicon"></i>' + c.html;
+ c.cls += ' sortable';
+ c.html = '<i class="fa"></i>' + c.html;
}
// could use BS4 hidden-..-down
c.colspan = config.colspan;
}
- if(typeof(config.hidden) != 'undefined' && config.hidden){
- c.style += ' display:none;';
- }
+ // hidden is handled by CSS now
if(typeof(config.dataIndex) != 'undefined'){
c.sort = config.dataIndex;
c.style += ' text-align:' + config.align + ';';
}
- if(typeof(config.width) != 'undefined'){
+ /* width is done in CSS
+ *if(typeof(config.width) != 'undefined'){
c.style += ' width:' + config.width + 'px;';
this.totalWidth += config.width;
} else {
this.totalWidth += 100; // assume minimum of 100 per column?
}
+ */
if(typeof(config.cls) != 'undefined'){
c.cls = (typeof(c.cls) == 'undefined') ? config.cls : (c.cls + ' ' + config.cls);
}
+ // this is the bit that doesnt reall work at all...
- ['xs','sm','md','lg'].map(function(size){
-
- if(typeof(config[size]) == 'undefined'){
- return;
- }
+ if (this.responsive) {
- if (!config[size]) { // 0 = hidden
- // BS 4 '0' is treated as hide that column and below.
- c.cls += ' hidden-' + size + ' hidden' + size + '-down';
- return;
- }
-
- c.cls += ' col-' + size + '-' + config[size] + (
- size == 'xs' ? (' col-' + config[size] ) : '' // bs4 col-{num} replaces col-xs
- );
-
-
- });
+
+ ['xs','sm','md','lg'].map(function(size){
+
+ if(typeof(config[size]) == 'undefined'){
+ return;
+ }
+
+ if (!config[size]) { // 0 = hidden
+ // BS 4 '0' is treated as hide that column and below.
+ c.cls += ' hidden-' + size + ' hidden' + size + '-down';
+ return;
+ }
+
+ c.cls += ' col-' + size + '-' + config[size] + (
+ size == 'xs' ? (' col-' + config[size] ) : '' // bs4 col-{num} replaces col-xs
+ );
+
+
+ });
+ }
+ // at the end?
+
+ c.html +=' <span class="x-grid-split x-grid-split-' + i + '"></span>';
+
+
+
header.cn.push(c)
}
var ds = this.store;
Roo.each(this.el.select('thead th.sortable', true).elements, function(e){
- e.select('i', true).removeClass(['glyphicon-arrow-up', 'glyphicon-arrow-down']);
+ e.select('i', true).removeClass(['fa-arrow-up', 'fa-arrow-down']);
if (_this.store.sortInfo) {
if(e.hasClass('sortable') && e.attr('sort') == _this.store.sortInfo.field && _this.store.sortInfo.direction.toUpperCase() == 'ASC'){
- e.select('i', true).addClass(['glyphicon-arrow-up']);
+ e.select('i', true).addClass(['fa-arrow-up']);
}
if(e.hasClass('sortable') && e.attr('sort') == _this.store.sortInfo.field && _this.store.sortInfo.direction.toUpperCase() == 'DESC'){
- e.select('i', true).addClass(['glyphicon-arrow-down']);
+ e.select('i', true).addClass(['fa-arrow-down']);
}
}
});
- var tbody = this.mainBody;
+ var tbody = this.bodyEl;
if(ds.getCount() > 0){
ds.data.each(function(d,rowIndex){
this.fireEvent('rowsrendered', this);
this.autoSize();
+
+ this.initCSS(); /// resize cols
+
+
},
if(isUpdate !== true){
this.fireEvent("beforerowremoved", this, index, record);
}
- var bt = this.mainBody.dom;
+ var bt = this.bodyEl.dom;
var rows = this.el.select('tbody > tr', true).elements;
{
//Roo.log('on Add called');
// - note this does not handle multiple adding very well..
- var bt = this.mainBody.dom;
+ var bt = this.bodyEl.dom;
for (var i =0 ; i < records.length;i++) {
//Roo.log('call insert row Add called on ' + rowIndex + ':' + i);
//Roo.log(records[i]);
//this.layout();
this.fireEvent("rowupdated", this, index, record);
},
+ // private - called by RowSelection
+ onRowSelect : function(rowIndex){
+ var row = this.getRowDom(rowIndex);
+ row.addClass(['bg-info','info']);
+ },
+ // private - called by RowSelection
+ onRowDeselect : function(rowIndex)
+ {
+ if (rowIndex < 0) {
+ return;
+ }
+ var row = this.getRowDom(rowIndex);
+ row.removeClass(['bg-info','info']);
+ },
+ /**
+ * Focuses the specified row.
+ * @param {Number} row The row index
+ */
+ focusRow : function(row)
+ {
+ //Roo.log('GridView.focusRow');
+ var x = this.bodyEl.dom.scrollLeft;
+ this.focusCell(row, 0, false);
+ this.bodyEl.dom.scrollLeft = x;
+
+ },
+ /**
+ * Focuses the specified cell.
+ * @param {Number} row The row index
+ * @param {Number} col The column index
+ * @param {Boolean} hscroll false to disable horizontal scrolling
+ */
+ focusCell : function(row, col, hscroll)
+ {
+ //Roo.log('GridView.focusCell');
+ var el = this.ensureVisible(row, col, hscroll);
+ // not sure what focusEL achives = it's a <a> pos relative
+ //this.focusEl.alignTo(el, "tl-tl");
+ //if(Roo.isGecko){
+ // this.focusEl.focus();
+ //}else{
+ // this.focusEl.focus.defer(1, this.focusEl);
+ //}
+ },
+
+ /**
+ * Scrolls the specified cell into view
+ * @param {Number} row The row index
+ * @param {Number} col The column index
+ * @param {Boolean} hscroll false to disable horizontal scrolling
+ */
+ ensureVisible : function(row, col, hscroll)
+ {
+ //Roo.log('GridView.ensureVisible,' + row + ',' + col);
+ //return null; //disable for testing.
+ if(typeof row != "number"){
+ row = row.rowIndex;
+ }
+ if(row < 0 && row >= this.ds.getCount()){
+ return null;
+ }
+ col = (col !== undefined ? col : 0);
+ var cm = this.cm;
+ while(cm.isHidden(col)){
+ col++;
+ }
+
+ var el = this.getCellDom(row, col);
+ if(!el){
+ return null;
+ }
+ var c = this.bodyEl.dom;
+
+ var ctop = parseInt(el.offsetTop, 10);
+ var cleft = parseInt(el.offsetLeft, 10);
+ var cbot = ctop + el.offsetHeight;
+ var cright = cleft + el.offsetWidth;
+
+ //var ch = c.clientHeight - this.mainHd.dom.offsetHeight;
+ var ch = 0; //?? header is not withing the area?
+ var stop = parseInt(c.scrollTop, 10);
+ var sleft = parseInt(c.scrollLeft, 10);
+ var sbot = stop + ch;
+ var sright = sleft + c.clientWidth;
+ /*
+ Roo.log('GridView.ensureVisible:' +
+ ' ctop:' + ctop +
+ ' c.clientHeight:' + c.clientHeight +
+ ' this.mainHd.dom.offsetHeight:' + this.mainHd.dom.offsetHeight +
+ ' stop:' + stop +
+ ' cbot:' + cbot +
+ ' sbot:' + sbot +
+ ' ch:' + ch
+ );
+ */
+ if(ctop < stop){
+ c.scrollTop = ctop;
+ //Roo.log("set scrolltop to ctop DISABLE?");
+ }else if(cbot > sbot){
+ //Roo.log("set scrolltop to cbot-ch");
+ c.scrollTop = cbot-ch;
+ }
+
+ if(hscroll !== false){
+ if(cleft < sleft){
+ c.scrollLeft = cleft;
+ }else if(cright > sright){
+ c.scrollLeft = cright-c.clientWidth;
+ }
+ }
+
+ return el;
+ },
+
insertRow : function(dm, rowIndex, isUpdate){
//var s = this.getScrollState();
var row = this.renderRow(this.cm, this.store, rowIndex);
// insert before rowIndex..
- var e = this.mainBody.createChild(row,this.getRowDom(rowIndex));
+ var e = this.bodyEl.createChild(row,this.getRowDom(rowIndex));
var _this = this;
return (typeof(rows[rowIndex]) == 'undefined') ? false : rows[rowIndex];
},
+ getCellDom : function(rowIndex, colIndex)
+ {
+ var row = this.getRowDom(rowIndex);
+ if (row === false) {
+ return false;
+ }
+ var cols = row.select('td', true).elements;
+ return (typeof(cols[colIndex]) == 'undefined') ? false : cols[colIndex];
+
+ },
+
// returns the object tree for a tr..
var td = {
tag: 'td',
+ // this might end up displaying HTML?
+ // this is too messy... - better to only do it on columsn you know are going to be too long
+ //tooltip : (typeof(value) === 'object') ? '' : value,
cls : rowcfg.rowClass + ' x-col-' + i,
style: '',
html: (typeof(value) === 'object') ? '' : value
td.colspan = config.colspan;
}
- if(typeof(config.hidden) != 'undefined' && config.hidden){
- td.style += ' display:none;';
- }
+
if(typeof(config.align) != 'undefined' && config.align.length){
td.style += ' text-align:' + config.align + ';';
if(typeof(config.valign) != 'undefined' && config.valign.length){
td.style += ' vertical-align:' + config.valign + ';';
}
-
+ /*
if(typeof(config.width) != 'undefined'){
td.style += ' width:' + config.width + 'px;';
}
+ */
if(typeof(config.cursor) != 'undefined'){
td.style += ' cursor:' + config.cursor + ';';
if(typeof(config.cls) != 'undefined'){
td.cls = (typeof(td.cls) == 'undefined') ? config.cls : (td.cls + ' ' + config.cls);
}
-
- ['xs','sm','md','lg'].map(function(size){
-
- if(typeof(config[size]) == 'undefined'){
- return;
- }
-
-
-
- if (!config[size]) { // 0 = hidden
- // BS 4 '0' is treated as hide that column and below.
- td.cls += ' hidden-' + size + ' hidden' + size + '-down';
- return;
- }
-
- td.cls += ' col-' + size + '-' + config[size] + (
- size == 'xs' ? (' col-' + config[size] ) : '' // bs4 col-{num} replaces col-xs
- );
-
-
- });
-
+ if (this.responsive) {
+ ['xs','sm','md','lg'].map(function(size){
+
+ if(typeof(config[size]) == 'undefined'){
+ return;
+ }
+
+
+
+ if (!config[size]) { // 0 = hidden
+ // BS 4 '0' is treated as hide that column and below.
+ td.cls += ' hidden-' + size + ' hidden' + size + '-down';
+ return;
+ }
+
+ td.cls += ' col-' + size + '-' + config[size] + (
+ size == 'xs' ? (' col-' + config[size] ) : '' // bs4 col-{num} replaces col-xs
+ );
+
+
+ });
+ }
row.cn.push(td);
}
*/
setRowVisibility : function(rowIndex, state)
{
- var bt = this.mainBody.dom;
+ var bt = this.bodyEl.dom;
var rows = this.el.select('tbody > tr', true).elements;
if(typeof(rows[rowIndex]) == 'undefined'){
return;
}
- rows[rowIndex].dom.style.display = state ? '' : 'none';
+ rows[rowIndex][ state ? 'removeClass' : 'addClass']('d-none');
+
},
})
}
},
-
+ /**
+ * get the Row Index from a dom element.
+ * @param {Roo.Element} row The row to look for
+ * @returns {Number} the row
+ */
getRowIndex : function(row)
{
var rowIndex = -1;
});
return rowIndex;
+ },
+ /**
+ * get the header TH element for columnIndex
+ * @param {Number} columnIndex
+ * @returns {Roo.Element}
+ */
+ getHeaderIndex: function(colIndex)
+ {
+ var cols = this.headEl.select('th', true).elements;
+ return cols[colIndex];
+ },
+ /**
+ * get the Column Index from a dom element. (using regex on x-hcol-{colid})
+ * @param {domElement} cell to look for
+ * @returns {Number} the column
+ */
+ getCellIndex : function(cell)
+ {
+ var id = String(cell.className).match(Roo.bootstrap.Table.cellRE);
+ if(id){
+ return parseInt(id[1], 10);
+ }
+ return 0;
},
/**
* Returns the grid's underlying element = used by panel.Grid
}
cw = Math.max(cw, this.totalWidth);
this.getGridEl().select('tbody tr',true).setWidth(cw);
+ this.initCSS();
// resize 'expandable coloumn?
},
onBodyScroll: function()
{
- //Roo.log("body scrolled');" + this.mainBody.dom.scrollLeft);
- if(this.mainHead){
- this.mainHead.setStyle({
+ //Roo.log("body scrolled');" + this.bodyEl.dom.scrollLeft);
+ if(this.headEl){
+ this.headEl.setStyle({
'position' : 'relative',
- 'left': (-1* this.mainBody.dom.scrollLeft) + 'px'
+ 'left': (-1* this.bodyEl.dom.scrollLeft) + 'px'
});
}
if(this.lazyLoad){
- var scrollHeight = this.mainBody.dom.scrollHeight;
+ var scrollHeight = this.bodyEl.dom.scrollHeight;
- var scrollTop = Math.ceil(this.mainBody.getScroll().top);
+ var scrollTop = Math.ceil(this.bodyEl.getScroll().top);
- var height = this.mainBody.getHeight();
+ var height = this.bodyEl.getHeight();
if(scrollHeight - height == scrollTop) {
}
},
-
+ onColumnSplitterMoved : function(i, diff)
+ {
+ this.userResized = true;
+
+ var cm = this.colModel;
+
+ var w = this.getHeaderIndex(i).getWidth() + diff;
+
+
+ cm.setColumnWidth(i, w, true);
+ this.initCSS();
+ //var cid = cm.getColumnId(i); << not used in this version?
+ /* Roo.log(['#' + this.id + ' .x-col-' + i, "width", w + "px"]);
+
+ this.CSS.updateRule( '#' + this.id + ' .x-col-' + i, "width", w + "px");
+ this.CSS.updateRule('#' + this.id + ' .x-hcol-' + i, "width", w + "px");
+ this.CSS.updateRule('#' + this.id + ' .x-grid-split-' + i, "left", w + "px");
+*/
+ //this.updateSplitters();
+ //this.layout(); << ??
+ this.fireEvent("columnresize", i, w);
+ },
onHeaderChange : function()
{
var header = this.renderHeader();
var table = this.el.select('table', true).first();
- this.mainHead.remove();
- this.mainHead = table.createChild(header, this.mainBody, false);
+ this.headEl.remove();
+ this.headEl = table.createChild(header, this.bodyEl, false);
+
+ Roo.each(this.el.select('thead th.sortable', true).elements, function(e){
+ e.on('click', this.sort, this);
+ }, this);
+
+ if(this.enableColumnResize !== false && Roo.grid.SplitDragZone){
+ new Roo.grid.SplitDragZone(this, this.headEl.dom, false); // not sure what 'lockedHd is for this implementation..)
+ }
+
},
onHiddenChange : function(colModel, colIndex, hidden)
{
+ /*
+ this.cm.setHidden()
var thSelector = '#' + this.id + ' .x-hcol-' + colIndex;
var tdSelector = '#' + this.id + ' .x-col-' + colIndex;
this.CSS.updateRule(thSelector, "display", "none");
this.CSS.updateRule(tdSelector, "display", "none");
}
-
+ */
+ // onload calls initCSS()
this.onHeaderChange();
this.onLoad();
},
}
});
-
+// currently only used to find the split on drag..
+Roo.bootstrap.Table.cellRE = /(?:.*?)x-grid-(?:hd|cell|split)-([\d]+)(?:.*?)/;
- /*
+/**
+ * @depricated
+*/
+Roo.bootstrap.Table.AbstractSelectionModel = Roo.grid.AbstractSelectionModel;
+Roo.bootstrap.Table.RowSelectionModel = Roo.grid.RowSelectionModel;
+/*
* - LGPL
*
* table cell
}
if(this.labelWidth < 13 && this.labelmd == 0){
- this.labelmd = this.labelWidth;
+ this.labellg = this.labellg > 0 ? this.labellg : this.labelWidth;
}
if(this.labellg > 0){
*/
/**
- * @cfg {Roo.data.DataProxy} proxy The Proxy object which provides access to a data object.
+ * @cfg {Roo.data.DataProxy} proxy [required] The Proxy object which provides access to a data object.
*/
/**
* @cfg {Array} data Inline data to be loaded when the store is initialized.
*/
/**
- * @cfg {Roo.data.Reader} reader The Reader object which processes the data object and returns
+ * @cfg {Roo.data.DataReader} reader [required] The Reader object which processes the data object and returns
* an Array of Roo.data.record objects which are cached keyed by their <em>id</em> property.
*/
/**
* @cfg {Array} fields An array of field definition objects, or field name strings.
* @cfg {Object} an existing reader (eg. copied from another store)
* @cfg {Array} data The multi-dimensional array of data
+ * @cfg {Roo.data.DataProxy} proxy [not-required]
+ * @cfg {Roo.data.Reader} reader [not-required]
* @constructor
* @param {Object} config
*/
/**
* @class Roo.data.DataReader
+ * @abstract
* Base class for reading structured data from a data source. This class is intended to be
* extended (see {Roo.data.ArrayReader}, {Roo.data.JsonReader} and {Roo.data.XmlReader}) and should not be created directly.
*/
/**
* @class Roo.data.DataProxy
* @extends Roo.data.Observable
+ * @abstract
* This class is an abstract base class for implementations which provide retrieval of
* unformatted data objects.<br>
* <p>
readRecords : function(o)
{
var sid = this.meta ? this.meta.id : null;
- var recordType = this.recordType, fields = recordType.prototype.fields;
- var records = [];
- var root = o;
- for(var i = 0; i < root.length; i++){
- var n = root[i];
- var values = {};
- var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
- for(var j = 0, jlen = fields.length; j < jlen; j++){
- var f = fields.items[j];
- var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
- var v = n[k] !== undefined ? n[k] : f.defaultValue;
- v = f.convert(v);
- values[f.name] = v;
- }
- var record = new recordType(values, id);
- record.json = n;
- records[records.length] = record;
- }
- return {
- records : records,
- totalRecords : records.length
- };
+ var recordType = this.recordType, fields = recordType.prototype.fields;
+ var records = [];
+ var root = o;
+ for(var i = 0; i < root.length; i++){
+ var n = root[i];
+ var values = {};
+ var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
+ for(var j = 0, jlen = fields.length; j < jlen; j++){
+ var f = fields.items[j];
+ var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
+ var v = n[k] !== undefined ? n[k] : f.defaultValue;
+ v = f.convert(v);
+ values[f.name] = v;
+ }
+ var record = new recordType(values, id);
+ record.json = n;
+ records[records.length] = record;
+ }
+ return {
+ records : records,
+ totalRecords : records.length
+ };
},
// used when loading children.. @see loadDataFromChildren
toLoadData: function(rec)
{
- // expect rec just to be an array.. eg [a,b,c, [...] << cn ]
- return typeof(rec.data.cn) == 'undefined' ? [] : rec.data.cn;
-
+ // expect rec just to be an array.. eg [a,b,c, [...] << cn ]
+ return typeof(rec.data.cn) == 'undefined' ? [] : rec.data.cn;
+
}
this.inputEl().on('mousedown', this.onTriggerClick, this);
this.inputEl().addClass('x-combo-noedit');
}else{
- this.inputEl().dom.setAttribute('readOnly', false);
+ this.inputEl().dom.removeAttribute('readOnly');
this.inputEl().un('mousedown', this.onTriggerClick, this);
this.inputEl().removeClass('x-combo-noedit');
}
combobox.cls += ' roo-select2-container-multi';
}
+ var required = this.allowBlank ? {
+ tag : 'i',
+ style: 'display: none'
+ } : {
+ tag : 'i',
+ cls : 'roo-required-indicator left-indicator text-danger fa fa-lg fa-star',
+ tooltip : 'This field is required'
+ };
+
var align = this.labelAlign || this.parentLabelAlign();
if (align ==='left' && this.fieldLabel.length) {
cfg.cn = [
- {
- tag : 'i',
- cls : 'roo-required-indicator left-indicator text-danger fa fa-lg fa-star',
- tooltip : 'This field is required'
- },
+ required,
{
tag: 'label',
cls : 'control-label col-form-label',
tag : 'span',
html : this.fieldLabel
},
- {
- tag : 'i',
- cls : 'roo-required-indicator right-indicator text-danger fa fa-lg fa-star',
- tooltip : 'This field is required'
- }
+ required
]
},
{
} else if ( this.fieldLabel.length) {
cfg.cn = [
- {
- tag : 'i',
- cls : 'roo-required-indicator left-indicator text-danger fa fa-lg fa-star',
- tooltip : 'This field is required'
- },
+ required,
{
tag: 'label',
cls : 'control-label',
cls : 'control-label',
html : this.fieldLabel,
cn : [
- {
- tag : 'i',
- cls : 'roo-required-indicator right-indicator text-danger fa fa-lg fa-star',
- tooltip : 'This field is required'
- }
+ required
]
},
{
Roo.extend(Roo.bootstrap.Calendar, Roo.bootstrap.Component, {
+ /**
+ * @cfg {Roo.data.Store} store
+ * The data source for the calendar
+ */
+ store : false,
/**
* @cfg {Number} startDay
* Day index at which the week should begin, 0-based (defaults to 0, which is Sunday)
/**
* @class Roo.bootstrap.Popover
* @extends Roo.bootstrap.Component
+ * @builder-top
* Bootstrap Popover class
* @cfg {String} html contents of the popover (or false to use children..)
* @cfg {String} title of popover (or false to hide)
if (this.parent() && (this.over == 'parent' || (this.over === false))) {
on_el = this.parent().el;
} else if (this.over) {
- Roo.get(this.over);
+ on_el = Roo.get(this.over);
}
}
clickHander : false,
+
onMouseDown : function(e)
{
- if (!e.getTarget(".roo-popover")) {
+ if (this.popups.length && !e.getTarget(".roo-popover")) {
+ /// what is nothing is showing..
this.hideAll();
}
},
+
popups : [],
register : function(popup)
Roo.bootstrap.Popover.clickHandler = Roo.get(document).on("mousedown", Roo.bootstrap.Popover.onMouseDown, Roo.bootstrap.Popover);
}
// hide other popups.
- this.hideAll();
- this.popups.push(popup);
+ popup.on('show', Roo.bootstrap.Popover.onShow, popup);
+ popup.on('hide', Roo.bootstrap.Popover.onHide, popup);
+ this.hideAll(); //<< why?
+ //this.popups.push(popup);
},
hideAll : function()
{
this.popups.forEach(function(p) {
p.hide();
});
- }
+ },
+ onShow : function() {
+ Roo.bootstrap.Popover.popups.push(this);
+ },
+ onHide : function() {
+ Roo.bootstrap.Popover.popups.remove(this);
+ }
});/*
* - LGPL
/**
* @class Roo.bootstrap.TabPanel
* @extends Roo.bootstrap.Component
+ * @children Roo.bootstrap.Component
* Bootstrap TabPanel class
* @cfg {Boolean} active panel active
* @cfg {String} html panel content
break;
case 'span':
if (className.indexOf('disabled') < 0) {
- this.viewDate.setUTCDate(1);
+ if (!this.viewDate) {
+ this.viewDate = new Date();
+ }
+ this.viewDate.setUTCDate(1);
if (className.indexOf('month') > -1) {
this.viewDate.setUTCMonth(Roo.bootstrap.DateField.dates[this.language].monthsShort.indexOf(html));
} else {
*/
stylesheets: false,
+ /**
+ * @cfg {boolean} allowComments - default false - allow comments in HTML source - by default they are stripped - if you are editing email you may need this.
+ */
+ allowComments: false,
// id of frame..
frameId: false,
return;
}
if (node.nodeName == "#comment") {
- node.parentNode.removeChild(node);
+ if (!this.allowComments) {
+ node.parentNode.removeChild(node);
+ }
// clean up silly Windows -- stuff?
return;
}
}
-});
-/**
- * @class Roo.bootstrap.Table.AbstractSelectionModel
- * @extends Roo.util.Observable
- * Abstract base class for grid SelectionModels. It provides the interface that should be
- * implemented by descendant classes. This class should not be directly instantiated.
- * @constructor
- */
-Roo.bootstrap.Table.AbstractSelectionModel = function(){
- this.locked = false;
- Roo.bootstrap.Table.AbstractSelectionModel.superclass.constructor.call(this);
-};
-
-
-Roo.extend(Roo.bootstrap.Table.AbstractSelectionModel, Roo.util.Observable, {
- /** @ignore Called by the grid automatically. Do not call directly. */
- init : function(grid){
- this.grid = grid;
- this.initEvents();
- },
-
- /**
- * Locks the selections.
- */
- lock : function(){
- this.locked = true;
- },
-
- /**
- * Unlocks the selections.
- */
- unlock : function(){
- this.locked = false;
- },
-
- /**
- * Returns true if the selections are locked.
- * @return {Boolean}
- */
- isLocked : function(){
- return this.locked;
- },
-
-
- initEvents : function ()
- {
-
- }
-});
-/**
- * @extends Roo.bootstrap.Table.AbstractSelectionModel
- * @class Roo.bootstrap.Table.RowSelectionModel
- * The default SelectionModel used by {@link Roo.bootstrap.Table}.
- * It supports multiple selections and keyboard selection/navigation.
- * @constructor
- * @param {Object} config
- */
-
-Roo.bootstrap.Table.RowSelectionModel = function(config){
- Roo.apply(this, config);
- this.selections = new Roo.util.MixedCollection(false, function(o){
- return o.id;
- });
-
- this.last = false;
- this.lastActive = false;
-
- this.addEvents({
- /**
- * @event selectionchange
- * Fires when the selection changes
- * @param {SelectionModel} this
- */
- "selectionchange" : true,
- /**
- * @event afterselectionchange
- * Fires after the selection changes (eg. by key press or clicking)
- * @param {SelectionModel} this
- */
- "afterselectionchange" : true,
- /**
- * @event beforerowselect
- * Fires when a row is selected being selected, return false to cancel.
- * @param {SelectionModel} this
- * @param {Number} rowIndex The selected index
- * @param {Boolean} keepExisting False if other selections will be cleared
- */
- "beforerowselect" : true,
- /**
- * @event rowselect
- * Fires when a row is selected.
- * @param {SelectionModel} this
- * @param {Number} rowIndex The selected index
- * @param {Roo.data.Record} r The record
- */
- "rowselect" : true,
- /**
- * @event rowdeselect
- * Fires when a row is deselected.
- * @param {SelectionModel} this
- * @param {Number} rowIndex The selected index
- */
- "rowdeselect" : true
- });
- Roo.bootstrap.Table.RowSelectionModel.superclass.constructor.call(this);
- this.locked = false;
- };
-
-Roo.extend(Roo.bootstrap.Table.RowSelectionModel, Roo.bootstrap.Table.AbstractSelectionModel, {
- /**
- * @cfg {Boolean} singleSelect
- * True to allow selection of only one row at a time (defaults to false)
- */
- singleSelect : false,
-
- // private
- initEvents : function()
- {
-
- //if(!this.grid.enableDragDrop && !this.grid.enableDrag){
- // this.growclickrid.on("mousedown", this.handleMouseDown, this);
- //}else{ // allow click to work like normal
- // this.grid.on("rowclick", this.handleDragableRowClick, this);
- //}
- //this.grid.on("rowdblclick", this.handleMouseDBClick, this);
- this.grid.on("rowclick", this.handleMouseDown, this);
-
- this.rowNav = new Roo.KeyNav(this.grid.getGridEl(), {
- "up" : function(e){
- if(!e.shiftKey){
- this.selectPrevious(e.shiftKey);
- }else if(this.last !== false && this.lastActive !== false){
- var last = this.last;
- this.selectRange(this.last, this.lastActive-1);
- this.grid.getView().focusRow(this.lastActive);
- if(last !== false){
- this.last = last;
- }
- }else{
- this.selectFirstRow();
- }
- this.fireEvent("afterselectionchange", this);
- },
- "down" : function(e){
- if(!e.shiftKey){
- this.selectNext(e.shiftKey);
- }else if(this.last !== false && this.lastActive !== false){
- var last = this.last;
- this.selectRange(this.last, this.lastActive+1);
- this.grid.getView().focusRow(this.lastActive);
- if(last !== false){
- this.last = last;
- }
- }else{
- this.selectFirstRow();
- }
- this.fireEvent("afterselectionchange", this);
- },
- scope: this
- });
- this.grid.store.on('load', function(){
- this.selections.clear();
- },this);
- /*
- var view = this.grid.view;
- view.on("refresh", this.onRefresh, this);
- view.on("rowupdated", this.onRowUpdated, this);
- view.on("rowremoved", this.onRemove, this);
- */
- },
-
- // private
- onRefresh : function()
- {
- var ds = this.grid.store, i, v = this.grid.view;
- var s = this.selections;
- s.each(function(r){
- if((i = ds.indexOfId(r.id)) != -1){
- v.onRowSelect(i);
- }else{
- s.remove(r);
- }
- });
- },
-
- // private
- onRemove : function(v, index, r){
- this.selections.remove(r);
- },
-
- // private
- onRowUpdated : function(v, index, r){
- if(this.isSelected(r)){
- v.onRowSelect(index);
- }
- },
-
- /**
- * Select records.
- * @param {Array} records The records to select
- * @param {Boolean} keepExisting (optional) True to keep existing selections
- */
- selectRecords : function(records, keepExisting)
- {
- if(!keepExisting){
- this.clearSelections();
- }
- var ds = this.grid.store;
- for(var i = 0, len = records.length; i < len; i++){
- this.selectRow(ds.indexOf(records[i]), true);
- }
- },
-
- /**
- * Gets the number of selected rows.
- * @return {Number}
- */
- getCount : function(){
- return this.selections.length;
- },
-
- /**
- * Selects the first row in the grid.
- */
- selectFirstRow : function(){
- this.selectRow(0);
- },
-
- /**
- * Select the last row.
- * @param {Boolean} keepExisting (optional) True to keep existing selections
- */
- selectLastRow : function(keepExisting){
- //this.selectRow(this.grid.dataSource.getCount() - 1, keepExisting);
- this.selectRow(this.grid.store.getCount() - 1, keepExisting);
- },
-
- /**
- * Selects the row immediately following the last selected row.
- * @param {Boolean} keepExisting (optional) True to keep existing selections
- */
- selectNext : function(keepExisting)
- {
- if(this.last !== false && (this.last+1) < this.grid.store.getCount()){
- this.selectRow(this.last+1, keepExisting);
- this.grid.getView().focusRow(this.last);
- }
- },
-
- /**
- * Selects the row that precedes the last selected row.
- * @param {Boolean} keepExisting (optional) True to keep existing selections
- */
- selectPrevious : function(keepExisting){
- if(this.last){
- this.selectRow(this.last-1, keepExisting);
- this.grid.getView().focusRow(this.last);
- }
- },
-
- /**
- * Returns the selected records
- * @return {Array} Array of selected records
- */
- getSelections : function(){
- return [].concat(this.selections.items);
- },
-
- /**
- * Returns the first selected record.
- * @return {Record}
- */
- getSelected : function(){
- return this.selections.itemAt(0);
- },
-
-
- /**
- * Clears all selections.
- */
- clearSelections : function(fast)
- {
- if(this.locked) {
- return;
- }
- if(fast !== true){
- var ds = this.grid.store;
- var s = this.selections;
- s.each(function(r){
- this.deselectRow(ds.indexOfId(r.id));
- }, this);
- s.clear();
- }else{
- this.selections.clear();
- }
- this.last = false;
- },
-
-
- /**
- * Selects all rows.
- */
- selectAll : function(){
- if(this.locked) {
- return;
- }
- this.selections.clear();
- for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
- this.selectRow(i, true);
- }
- },
-
- /**
- * Returns True if there is a selection.
- * @return {Boolean}
- */
- hasSelection : function(){
- return this.selections.length > 0;
- },
-
- /**
- * Returns True if the specified row is selected.
- * @param {Number/Record} record The record or index of the record to check
- * @return {Boolean}
- */
- isSelected : function(index){
- var r = typeof index == "number" ? this.grid.store.getAt(index) : index;
- return (r && this.selections.key(r.id) ? true : false);
- },
-
- /**
- * Returns True if the specified record id is selected.
- * @param {String} id The id of record to check
- * @return {Boolean}
- */
- isIdSelected : function(id){
- return (this.selections.key(id) ? true : false);
- },
-
-
- // private
- handleMouseDBClick : function(e, t){
-
- },
- // private
- handleMouseDown : function(e, t)
- {
- var rowIndex = this.grid.headerShow ? t.dom.rowIndex - 1 : t.dom.rowIndex ; // first row is header???
- if(this.isLocked() || rowIndex < 0 ){
- return;
- };
- if(e.shiftKey && this.last !== false){
- var last = this.last;
- this.selectRange(last, rowIndex, e.ctrlKey);
- this.last = last; // reset the last
- t.focus();
-
- }else{
- var isSelected = this.isSelected(rowIndex);
- //Roo.log("select row:" + rowIndex);
- if(isSelected){
- this.deselectRow(rowIndex);
- } else {
- this.selectRow(rowIndex, true);
- }
-
- /*
- if(e.button !== 0 && isSelected){
- alert('rowIndex 2: ' + rowIndex);
- view.focusRow(rowIndex);
- }else if(e.ctrlKey && isSelected){
- this.deselectRow(rowIndex);
- }else if(!isSelected){
- this.selectRow(rowIndex, e.button === 0 && (e.ctrlKey || e.shiftKey));
- view.focusRow(rowIndex);
- }
- */
- }
- this.fireEvent("afterselectionchange", this);
- },
- // private
- handleDragableRowClick : function(grid, rowIndex, e)
- {
- if(e.button === 0 && !e.shiftKey && !e.ctrlKey) {
- this.selectRow(rowIndex, false);
- grid.view.focusRow(rowIndex);
- this.fireEvent("afterselectionchange", this);
- }
- },
-
- /**
- * Selects multiple rows.
- * @param {Array} rows Array of the indexes of the row to select
- * @param {Boolean} keepExisting (optional) True to keep existing selections
- */
- selectRows : function(rows, keepExisting){
- if(!keepExisting){
- this.clearSelections();
- }
- for(var i = 0, len = rows.length; i < len; i++){
- this.selectRow(rows[i], true);
- }
- },
-
- /**
- * Selects a range of rows. All rows in between startRow and endRow are also selected.
- * @param {Number} startRow The index of the first row in the range
- * @param {Number} endRow The index of the last row in the range
- * @param {Boolean} keepExisting (optional) True to retain existing selections
- */
- selectRange : function(startRow, endRow, keepExisting){
- if(this.locked) {
- return;
- }
- if(!keepExisting){
- this.clearSelections();
- }
- if(startRow <= endRow){
- for(var i = startRow; i <= endRow; i++){
- this.selectRow(i, true);
- }
- }else{
- for(var i = startRow; i >= endRow; i--){
- this.selectRow(i, true);
- }
- }
- },
-
- /**
- * Deselects a range of rows. All rows in between startRow and endRow are also deselected.
- * @param {Number} startRow The index of the first row in the range
- * @param {Number} endRow The index of the last row in the range
- */
- deselectRange : function(startRow, endRow, preventViewNotify){
- if(this.locked) {
- return;
- }
- for(var i = startRow; i <= endRow; i++){
- this.deselectRow(i, preventViewNotify);
- }
- },
-
- /**
- * Selects a row.
- * @param {Number} row The index of the row to select
- * @param {Boolean} keepExisting (optional) True to keep existing selections
- */
- selectRow : function(index, keepExisting, preventViewNotify)
- {
- if(this.locked || (index < 0 || index > this.grid.store.getCount())) {
- return;
- }
- if(this.fireEvent("beforerowselect", this, index, keepExisting) !== false){
- if(!keepExisting || this.singleSelect){
- this.clearSelections();
- }
-
- var r = this.grid.store.getAt(index);
- //console.log('selectRow - record id :' + r.id);
-
- this.selections.add(r);
- this.last = this.lastActive = index;
- if(!preventViewNotify){
- var proxy = new Roo.Element(
- this.grid.getRowDom(index)
- );
- proxy.addClass('bg-info info');
- }
- this.fireEvent("rowselect", this, index, r);
- this.fireEvent("selectionchange", this);
- }
- },
-
- /**
- * Deselects a row.
- * @param {Number} row The index of the row to deselect
- */
- deselectRow : function(index, preventViewNotify)
- {
- if(this.locked) {
- return;
- }
- if(this.last == index){
- this.last = false;
- }
- if(this.lastActive == index){
- this.lastActive = false;
- }
-
- var r = this.grid.store.getAt(index);
- if (!r) {
- return;
- }
-
- this.selections.remove(r);
- //.console.log('deselectRow - record id :' + r.id);
- if(!preventViewNotify){
-
- var proxy = new Roo.Element(
- this.grid.getRowDom(index)
- );
- proxy.removeClass('bg-info info');
- }
- this.fireEvent("rowdeselect", this, index);
- this.fireEvent("selectionchange", this);
- },
-
- // private
- restoreLast : function(){
- if(this._last){
- this.last = this._last;
- }
- },
-
- // private
- acceptsNav : function(row, col, cm){
- return !cm.isHidden(col) && cm.isCellEditable(col, row);
- },
-
- // private
- onEditorKey : function(field, e){
- var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
- if(k == e.TAB){
- e.stopEvent();
- ed.completeEdit();
- if(e.shiftKey){
- newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
- }else{
- newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
- }
- }else if(k == e.ENTER && !e.ctrlKey){
- e.stopEvent();
- ed.completeEdit();
- if(e.shiftKey){
- newCell = g.walkCells(ed.row-1, ed.col, -1, this.acceptsNav, this);
- }else{
- newCell = g.walkCells(ed.row+1, ed.col, 1, this.acceptsNav, this);
- }
- }else if(k == e.ESC){
- ed.cancelEdit();
- }
- if(newCell){
- g.startEditing(newCell[0], newCell[1]);
- }
- }
-});
-/*
+});/*
* Based on:
* Ext JS Library 1.1.1
* Copyright(c) 2006-2007, Ext JS, LLC.
getAutoCreate : function(){
var cfg = {
tag : 'li',
- cls: 'divider'
+ cls: 'dropdown-divider divider'
};
return cfg;
return;
}
- var bindEl = el;
+ var bindEl = el;
+ var pel = false;
+ if (!el.attr('tooltip')) {
+ pel = el.findParent("[tooltip]");
+ if (pel) {
+ bindEl = Roo.get(pel);
+ }
+ }
+
+
// you can not look for children, as if el is the body.. then everythign is the child..
- if (!el.attr('tooltip')) { //
+ if (!pel && !el.attr('tooltip')) { //
if (!el.select("[tooltip]").elements.length) {
return;
}
//Roo.log("child element over..");
}
- this.currentEl = bindEl;
+ this.currentEl = el;
this.currentTip.bind(bindEl);
this.currentRegion = Roo.lib.Region.getRegion(dom);
this.currentTip.enter();
}
+ var elems = document.getElementsByTagName('div');
+ var highest = Number.MIN_SAFE_INTEGER || -(Math.pow(2, 53) - 1);
+ for (var i = 0; i < elems.length; i++) {
+ var zindex = Number.parseInt(
+ document.defaultView.getComputedStyle(elems[i], null).getPropertyValue("z-index"),
+ 10
+ );
+ if (zindex > highest) {
+ highest = zindex;
+ }
+ }
+
+
+
+ this.el.dom.style.zIndex = highest;
+
this.el.alignTo(this.bindEl, align[0],align[1]);
//var arrow = this.el.select('.arrow',true).first();
//arrow.set(align[2],
* @licence LGPL
* @cfg {String} title The title of alert
* @cfg {String} html The content of alert
- * @cfg {String} weight ( success | info | warning | danger )
- * @cfg {String} faicon font-awesomeicon
+ * @cfg {String} weight (success|info|warning|danger) Weight of the message
+ * @cfg {String} fa font-awesomeicon
+ * @cfg {Number} seconds default:-1 Number of seconds until it disapears (-1 means never.)
+ * @cfg {Boolean} close true to show a x closer
+ *
*
* @constructor
* Create a new alert
title: '',
html: '',
weight: false,
- faicon: false,
+ fa: false,
+ faicon: false, // BC
+ close : false,
+
getAutoCreate : function()
{
tag : 'div',
cls : 'alert',
cn : [
+ {
+ tag: 'button',
+ type : "button",
+ cls: "close",
+ html : '×',
+ style : this.close ? '' : 'display:none'
+ },
{
tag : 'i',
cls : 'roo-alert-icon'
if(this.faicon){
cfg.cn[0].cls += ' fa ' + this.faicon;
}
+ if(this.fa){
+ cfg.cn[0].cls += ' fa ' + this.fa;
+ }
if(this.weight){
cfg.cls += ' alert-' + this.weight;
initEvents: function()
{
this.el.setVisibilityMode(Roo.Element.DISPLAY);
+ this.titleEl = this.el.select('.roo-alert-title',true).first();
+ this.iconEl = this.el.select('.roo-alert-icon',true).first();
+ this.htmlEl = this.el.select('.roo-alert-text',true).first();
+ if (this.seconds > 0) {
+ this.hide.defer(this.seconds, this);
+ }
},
-
+ /**
+ * Set the Title Message HTML
+ * @param {String} html
+ */
setTitle : function(str)
{
- this.el.select('.roo-alert-title',true).first().dom.innerHTML = str;
+ this.titleEl.dom.innerHTML = str;
},
-
- setText : function(str)
+
+ /**
+ * Set the Body Message HTML
+ * @param {String} html
+ */
+ setHtml : function(str)
{
- this.el.select('.roo-alert-text',true).first().dom.innerHTML = str;
+ this.htmlEl.dom.innerHTML = str;
},
+ /**
+ * Set the Weight of the alert
+ * @param {String} (success|info|warning|danger) weight
+ */
setWeight : function(weight)
{
if(this.weight){
- this.el.select('.alert',true).first().removeClass('alert-' + this.weight);
+ this.el.removeClass('alert-' + this.weight);
}
this.weight = weight;
- this.el.select('.alert',true).first().addClass('alert-' + this.weight);
+ this.el.addClass('alert-' + this.weight);
},
-
+ /**
+ * Set the Icon of the alert
+ * @param {String} see fontawsome names (name without the 'fa-' bit)
+ */
setIcon : function(icon)
{
if(this.faicon){
- this.el.select('.roo-alert-icon',true).first().removeClass(['fa', 'fa-' + this.faicon]);
+ this.alertEl.removeClass(['fa', 'fa-' + this.faicon]);
}
this.faicon = icon;
- this.el.select('.roo-alert-icon',true).first().addClass(['fa', 'fa-' + this.faicon]);
+ this.alertEl.addClass(['fa', 'fa-' + this.faicon]);
},
-
+ /**
+ * Hide the Alert
+ */
hide: function()
{
this.el.hide();
},
-
+ /**
+ * Show the Alert
+ */
show: function()
{
this.el.show();
/**
* @class Roo.bootstrap.layout.Border
* @extends Roo.bootstrap.layout.Manager
+ * @builder-top
* This class represents a common layout manager used in desktop applications. For screenshots and more details,
* please see: examples/bootstrap/nested.html<br><br>
/**
* @class Roo.ContentPanel
* @extends Roo.util.Observable
+ * @builder-top
* A basic ContentPanel element.
* @cfg {Boolean} fitToFrame True for this panel to adjust its size to fit when the region resizes (defaults to false)
* @cfg {Boolean} fitContainer When using {@link #fitToFrame} and {@link #resizeEl}, you can also fit the parent container (defaults to false)
* Fires when this tab is created
* @param {Roo.ContentPanel} this
*/
- "render" : true
+ "render" : true,
+
+ /**
+ * @event scroll
+ * Fires when this content is scrolled
+ * @param {Roo.ContentPanel} this
+ * @param {Event} scrollEvent
+ */
+ "scroll" : true
if(this.autoScroll && !this.iframe){
this.resizeEl.setStyle("overflow", "auto");
+ this.resizeEl.on('scroll', this.onScroll, this);
} else {
// fix randome scrolling
//this.el.on('scroll', function() {
iframe : false,
iframeEl : false,
+ /* Resize Element - use this to work out scroll etc. */
+ resizeEl : false,
+
setRegion : function(region){
this.region = region;
this.setActiveClass(region && !this.background);
getChildContainer: function () {
return this.getEl();
+ },
+
+
+ onScroll : function(e)
+ {
+ this.fireEvent('scroll', this, e);
}
};
Roo.extend(Roo.bootstrap.PhoneInput, Roo.bootstrap.TriggerField, {
-
+ /**
+ * @cfg {Roo.data.Store} store [required] The data store to which this combo is bound (defaults to undefined)
+ */
listWidth: undefined,
selectedClass: 'active',