var cfg = Roo.apply({}, this.getAutoCreate());
- cfg.id = Roo.id();
+ cfg.id = this.id || Roo.id();
// fill in the extra attributes
if (this.xattr && typeof(this.xattr) =='object') {
cfg.name = this.name;
}
-
-
this.el = ct.createChild(cfg, position);
if (this.tooltip) {
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);
+ //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.
this.fireEvent('childrenrendered', this);
return cn;
- }
-
-
+ },
+ /**
+ * Show a component - removes 'hidden' class
+ */
+ show : function()
+ {
+ if (this.el) {
+ this.el.removeClass('hidden');
+ }
+ },
+ /**
+ * Hide a component - adds 'hidden' class
+ */
+ hide: function()
+ {
+ if (this.el && !this.el.hasClass('hidden')) {
+ this.el.addClass('hidden');
+ }
+
+ }
});
/*
* @cfg {String} fa (ban|check|...) 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 {String} rheader contet on the right of header
*
* @constructor
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
+ });
};
Roo.extend(Roo.bootstrap.Container, Roo.bootstrap.Component, {
alert : false,
fa: false,
icon : false,
+ expandable : false,
+ rheader : '',
+ expanded : true,
getChildContainer : function() {
cfg.cls += ' panel panel-' + this.panel;
cfg.cn = [];
if (this.header.length) {
- cfg.cn.push({
+
+ var h = [];
+
+ if(this.expandable){
- cls : 'panel-heading',
- cn : [{
- tag: 'h3',
+ cfg.cls = cfg.cls + ' expandable';
+
+ h.push({
+ tag: 'i',
+ cls: 'fa fa-minus'
+ });
+ }
+
+ h.push(
+ {
+ tag: 'span',
cls : 'panel-title',
html : this.header
- }]
-
+ },
+ {
+ tag: 'span',
+ cls: 'panel-header-right',
+ html: this.rheader
+ }
+ );
+
+ cfg.cn.push({
+ cls : 'panel-heading',
+ cn : h
});
+
}
+
body = false;
cfg.cn.push({
cls : 'panel-body',
return cfg;
},
+ initEvents: function()
+ {
+ if(!this.expandable){
+ return;
+ }
+
+ var headerEl = this.headerEl();
+
+ if(!headerEl){
+ return;
+ }
+
+ headerEl.on('click', this.onToggleClick, 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();
+
+ 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();
+
+ 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()
+ },
+
titleEl : function()
{
if(!this.el || !this.panel.length || !this.header.length){
return titleEl.dom.innerHTML;
},
- show : function() {
- this.el.removeClass('hidden');
- },
- hide: function() {
- if (!this.el.hasClass('hidden')) {
- this.el.addClass('hidden');
+ setRightTitle : function(v)
+ {
+ var t = this.el.select('.panel-header-right',true).first();
+
+ if(!t){
+ return;
}
+ t.dom.innerHTML = v;
}
});
* @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
src: '',
href: false,
target: false,
+ xsUrl: '',
+ smUrl: '',
+ mdUrl: '',
+ lgUrl: '',
- getAutoCreate : function(){
+ 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' : '',
}
-
return (this.href) ? a : cfg;
},
- initEvents: function() {
-
+ initEvents: function()
+ {
if(!this.href){
this.el.on('click', this.onClick, this);
}
+
},
onClick : function(e)
};
// anchor's do not require html/href...
if (this.anchor === false) {
- cfg.html = this.html || 'html-missing';
+ cfg.html = this.html || '';
cfg.href = this.href || '#';
} else {
cfg.name = this.anchor;
}
}
- // private
+ // private this should really trigger on mouseup..
function onMouseDown(e){
- Roo.log("on MouseDown");
+ Roo.log("on Mouse Up");
if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu") && !e.getTarget('.user-menu')){
- hideAll();
+ Roo.log("hideAll");
+ hideAll();
+ e.stopEvent();
}
// Roo.log("ADD event");
// Roo.log(this.triggerEl.dom);
- this.triggerEl.on('click', this.onTriggerPress, this);
+ this.triggerEl.on(Roo.isTouch ? 'touchstart' : 'mouseup', this.onTriggerPress, this);
+
this.triggerEl.addClass('dropdown-toggle');
- this.el.on(Roo.isTouch ? 'touchstart' : 'click' , this.onClick, this);
+ this.el.on(Roo.isTouch ? 'touchstart' : 'click' , this.onClick, this);
this.el.on("mouseover", this.onMouseOver, this);
this.el.on("mouseout", this.onMouseOut, this);
}
if(_e !== false){
this.fireEvent("beforeshow", this);
-
//xy = this.el.adjustForConstraints(xy);
}
- //this.el.setXY(xy);
+
//this.el.show();
this.hideMenuItems();
this.hidden = false;
this.triggerEl.addClass('open');
+
+ if(this.el.getWidth() + xy[0] > Roo.lib.Dom.getViewWidth()){
+ xy[0] = xy[0] - this.el.getWidth() + this.triggerEl.getWidth();
+ }
+
+ this.el.setXY(xy);
this.focus();
this.fireEvent("show", this);
},
if (Roo.get(e.getTarget()).findParent('.dropdown-menu')) {
return;
}
+
if (this.isVisible()) {
Roo.log('hide');
this.hide();
} else {
+ Roo.log('show');
this.show(this.triggerEl, false, false);
}
-
+ e.stopEvent();
},
//this.el.addClass([this.fieldClass, this.cls]);
},
+
getAutoCreate : function(){
},this);
}
}
-
-
-
});
* @class Roo.bootstrap.NavGroup
* @extends Roo.bootstrap.Component
* Bootstrap NavGroup class
- * @cfg {String} align left | right
- * @cfg {Boolean} inverse false | true
+ * @cfg {String} align (left|right)
+ * @cfg {Boolean} inverse
* @cfg {String} type (nav|pills|tab) default nav
* @cfg {String} navId - reference Id for navbar.
* @cfg {Boolean} preventDefault (true | false) default false
* @cfg {String} tabId the tab that this item activates.
* @cfg {String} tagtype (a|span) render as a href or span?
- * @cfg {Boolean} animateRef (true|false) link to element default false
+ * @cfg {Boolean} animateRef (true|false) link to element default false
* @constructor
* Create a new Navbar Item
{
if(
this.preventDefault ||
- this.href == '#' ||
- (this.animateRef && this.href.charAt(0) == '#')
+ this.href == '#'
){
+
e.preventDefault();
}
return;
}
- Roo.log("fire event clicked");
+
+
+ //Roo.log("fire event clicked");
if(this.fireEvent('click', this, e) === false){
return;
};
return;
}
- if(this.animateRef && this.href.charAt(0) == '#'){
+ //Roo.log(this.href);
+ var ael = this.el.select('a',true).first();
+ //Roo.log(ael);
+
+ if(ael && this.animateRef && this.href.indexOf('#') > -1){
+ //Roo.log(["test:",ael.dom.href.split("#")[0], document.location.toString().split("#")[0]]);
+ if (ael.dom.href.split("#")[0] != document.location.toString().split("#")[0]) {
+ return; // ignore... - it's a 'hash' to another page.
+ }
+
+ e.preventDefault();
this.scrollToElement(e);
- return;
}
- var p = this.parent();
+
+ var p = this.parent();
+
if (['tabs','pills'].indexOf(p.type)!==-1) {
if (typeof(p.setActiveItem) !== 'undefined') {
p.setActiveItem(this);
}
}
+
// if parent is a navbarheader....- and link is probably a '#' page ref.. then remove the expanded menu.
if (p.parentType == 'NavHeaderbar' && !this.menu) {
// remove the collapsed menu expand...
p.parent().el.select('.navbar-collapse',true).removeClass('in');
}
-
},
isActive: function () {
{
var c = document.body;
- var target = Roo.get(c).select('a[name=' + this.href.replace('#', '') +']', true).first();
+ /*
+ * Firefox / IE places the overflow at the html level, unless specifically styled to behave differently.
+ */
+ if(Roo.isFirefox || Roo.isIE || Roo.isIE11){
+ c = document.documentElement;
+ }
+
+ var target = Roo.get(c).select('a[name=' + this.href.split('#')[1] +']', true).first();
if(!target){
return;
* @cfg {String} html contents of the element
* @cfg {String} tag tag of the element
* @cfg {String} cls class of the element
+ * @cfg {Boolean} preventDefault (true|false) default false
+ * @cfg {Boolean} clickable (true|false) default false
*
* @constructor
* Create a new Element
Roo.bootstrap.Element = function(config){
Roo.bootstrap.Element.superclass.constructor.call(this, config);
+
+ this.addEvents({
+ // raw events
+ /**
+ * @event click
+ * When a element is chick
+ * @param {Roo.bootstrap.Element} this
+ * @param {Roo.EventObject} e
+ */
+ "click" : true
+ });
};
Roo.extend(Roo.bootstrap.Element, Roo.bootstrap.Component, {
tag: 'div',
cls: '',
html: '',
-
+ preventDefault: false,
+ clickable: false,
getAutoCreate : function(){
html: this.html
}
-
-
return cfg;
},
+ initEvents: function()
+ {
+ Roo.bootstrap.Element.superclass.initEvents.call(this);
+
+ if(this.clickable){
+ this.el.on('click', this.onClick, this);
+ }
+
+ },
+
+ onClick : function(e)
+ {
+ if(this.preventDefault){
+ e.preventDefault();
+ }
+
+ this.fireEvent('click', this, e);
+ },
+
getValue : function()
{
return this.el.dom.innerHTML;
c.style += ' width:' + config.width + 'px;';
}
+ if(typeof(config.cls) != 'undefined'){
+ c.cls = (typeof(c.cls) == 'undefined') ? config.cls : (c.cls + ' ' + config.cls);
+ }
+
header.cn.push(c)
}
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);
+ }
row.cn.push(td);
var inputblock = input;
+ var feedback = {
+ tag: 'span',
+ cls: 'glyphicon form-control-feedback'
+ };
+
if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
- var feedback = {
- tag: 'span',
- cls: 'glyphicon form-control-feedback'
- };
-
inputblock = {
cls : 'has-feedback',
cn : [
]
};
}
-
-// var inputblock = input;
if (this.before || this.after) {
inputblock.cn.push(input);
- if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
- inputblock.cls += ' has-feedback';
- inputblock.cn.push(feedback);
- }
-
if (this.after && typeof(this.after) == 'string') {
inputblock.cn.push({
tag :'span',
(this.after.xtype == 'Button' ? 'btn' : 'addon') //?? what about checkboxes - that looks like a bit of a hack thought?
});
}
+
+ if(this.hasFeedback && this.inputType != 'hidden' && !this.allowBlank){
+ inputblock.cls += ' has-feedback';
+ inputblock.cn.push(feedback);
+ }
};
if (align ==='left' && this.fieldLabel.length) {
*/
hideTrigger:false,
+ /**
+ * @cfg {Boolean} removable (true|false) special filter default false
+ */
+ removable : false,
+
/** @cfg {Boolean} grow @hide */
/** @cfg {Number} growMin @hide */
/** @cfg {Number} growMax @hide */
tag: 'span',
cls: 'glyphicon form-control-feedback'
};
+
+ if(this.removable && !this.editable && !this.tickable){
+ inputblock = {
+ cls : 'has-feedback',
+ cn : [
+ inputblock,
+ {
+ tag: 'button',
+ html : 'x',
+ cls : 'roo-combo-removable-btn close'
+ },
+ feedback
+ ]
+ };
+ } else {
+ inputblock = {
+ cls : 'has-feedback',
+ cn : [
+ inputblock,
+ feedback
+ ]
+ };
+ }
- inputblock = {
- cls : 'has-feedback',
- cn : [
- input,
- feedback
- ]
- };
+ } else {
+ if(this.removable && !this.editable && !this.tickable){
+ inputblock = {
+ cls : 'roo-removable',
+ cn : [
+ inputblock,
+ {
+ tag: 'button',
+ html : 'x',
+ cls : 'roo-combo-removable-btn close'
+ }
+ ]
+ };
+ }
}
if (this.before || this.after) {
cfg.cls += ' col-' + size + '-' + settings[size];
}
});
-
+ Roo.log(cfg);
return cfg;
},
this.inputEl().on("click", this.onTriggerClick, this, {preventDefault:true});
}
+ if(this.removable && !this.editable && !this.tickable){
+ var close = this.closeTriggerEl();
+
+ if(close){
+ close.setVisibilityMode(Roo.Element.DISPLAY).hide();
+ close.on('click', this.removeBtnClick, this, close);
+ }
+ }
+
//this.trigger.addClassOnOver('x-form-trigger-over');
//this.trigger.addClassOnClick('x-form-trigger-click');
//}
},
+ closeTriggerEl : function()
+ {
+ var close = this.el.select('.roo-combo-removable-btn', true).first();
+ return close ? close : false;
+ },
+
+ removeBtnClick : function(e, h, el)
+ {
+ e.preventDefault();
+
+ if(this.fireEvent("remove", this) !== false){
+ this.reset();
+ }
+ },
+
createList : function()
{
this.list = Roo.get(document.body).createChild({
* @cfg {String} successProperty Name of the property from which to retrieve the success attribute used by forms.
* @cfg {String} root name of the property which contains the Array of row objects.
* @cfg {String} id Name of the property within a row object that contains a record identifier value.
+ * @cfg {Array} fields Array of field definition objects
* @constructor
* Create a new JsonReader
* @param {Object} meta Metadata configuration options
* @cfg {Boolean} triggerList trigger show the list or not (true|false) default true
* @cfg {Boolean} showToggleBtn show toggle button or not (true|false) default true
* @cfg {String} btnPosition set the position of the trigger button (left | right) default right
+ * @cfg {Boolean} animate default true
+ * @cfg {Boolean} emptyResultText only for touch device
* @constructor
* Create a new ComboBox.
* @param {Object} config Configuration options
* Fires when the remove value from the combobox array
* @param {Roo.bootstrap.ComboBox} combo This combo box
*/
- 'remove' : true
+ 'remove' : true,
+ /**
+ * @event specialfilter
+ * Fires when specialfilter
+ * @param {Roo.bootstrap.ComboBox} combo This combo box
+ */
+ 'specialfilter' : true
});
* mode = 'remote' or 'text' if mode = 'local')
*/
displayField: undefined,
+
/**
* @cfg {String} valueField The underlying data value name to bind to this CombBox (defaults to undefined if
* mode = 'remote' or 'value' if mode = 'local').
*/
validClass : "has-success",
+ /**
+ * @cfg {Boolean} specialFilter (true|false) special filter default false
+ */
+ specialFilter : false,
+
+ /**
+ * @cfg {Boolean} mobileTouchView (true|false) show mobile touch view when using a mobile default true
+ */
+ mobileTouchView : true,
+
//private
addicon : false,
editicon: false,
btnPosition : 'right',
triggerList : true,
showToggleBtn : true,
+ animate : true,
+ emptyResultText: 'Empty',
// element that contains real text value.. (when hidden is used..)
getAutoCreate : function()
{
var cfg = false;
+ /*
+ * Touch Devices
+ */
+
+ if(Roo.isTouch && this.mobileTouchView){
+ cfg = this.getAutoCreateTouchView();
+ return cfg;;
+ }
+
/*
* Normal ComboBox
*/
if (!this.store) {
throw "can not find store for combo";
}
+
this.store = Roo.factory(this.store, Roo.data);
+ /*
+ * Touch Devices
+ */
+
+ if(Roo.isTouch && this.mobileTouchView){
+ this.initTouchView();
+ return;
+ }
+
if(this.tickable){
this.initTickableEvents();
return;
this.lastSelectionText = '';
this.lastData = false;
+ var close = this.closeTriggerEl();
+
+ if(close){
+ close.hide();
+ }
+
},
/**
}
Roo.bootstrap.ComboBox.superclass.setValue.call(this, text);
this.value = v;
+
+ var close = this.closeTriggerEl();
+
+ if(close){
+ (v && (v.length || v * 1 > 0)) ? close.show() : close.hide();
+ }
},
/**
* @property {Object} the last set data for the element
vv = !o || typeof(o[this.valueField]) == 'undefined' ? dv : o[this.valueField];
}
+ var close = this.closeTriggerEl();
+
+ if(close){
+ (vv.length || vv * 1 > 0) ? close.show() : close.hide();
+ }
+
if(this.hiddenField){
this.hiddenField.dom.value = vv;
this.value = vv;
+
},
// private
reset : function(){
if(forceAll){
this.store.clearFilter();
}else{
+
+ if(this.specialFilter){
+ this.fireEvent('specialfilter', this);
+ this.onLoad();
+ return;
+ }
+
this.store.filter(this.displayField, q);
}
+
+ this.store.fireEvent("datachanged", this.store);
+
this.onLoad();
+
+
}else{
this.store.baseParams[this.queryParam] = q;
this.loadNext = false;
},
-
+
// private
getParams : function(q){
var p = {};
if(this.hiddenField){
this.hiddenField.dom.value = this.value;
}
+
+ this.store.fireEvent("datachanged", this.store);
},
clearItem : function()
inputEl: function ()
{
+ if(Roo.isTouch && this.mobileTouchView){
+ return this.el.select('input.form-control',true).first();
+ }
+
if(this.tickable){
return this.searchField;
}
+
return this.el.select('input.form-control',true).first();
},
}
return this.inputEl().select('.select2-search-field-input', true).first();
- }
+ },
+ getAutoCreateTouchView : function()
+ {
+ var id = Roo.id();
+
+ var cfg = {
+ cls: 'form-group' //input-group
+ };
+
+ var input = {
+ tag: 'input',
+ id : id,
+ type : this.inputType,
+ cls : 'form-control x-combo-noedit',
+ autocomplete: 'new-password',
+ placeholder : this.placeholder || '',
+ readonly : true
+ };
+
+ if (this.name) {
+ input.name = this.name;
+ }
+
+ if (this.size) {
+ input.cls += ' input-' + this.size;
+ }
+
+ if (this.disabled) {
+ input.disabled = true;
+ }
+
+ var inputblock = {
+ cls : '',
+ cn : [
+ input
+ ]
+ };
+
+ if(this.before){
+ inputblock.cls += ' input-group';
+
+ inputblock.cn.unshift({
+ tag :'span',
+ cls : 'input-group-addon',
+ html : this.before
+ });
+ }
+
+ if(this.removable && !this.multiple){
+ inputblock.cls += ' roo-removable';
+
+ inputblock.cn.push({
+ tag: 'button',
+ html : 'x',
+ cls : 'roo-combo-removable-btn close'
+ });
+ }
- /**
- * @cfg {Boolean} grow
- * @hide
- */
- /**
- * @cfg {Number} growMin
- * @hide
- */
- /**
- * @cfg {Number} growMax
- * @hide
- */
- /**
- * @hide
- * @method autoSize
- */
-});
-/*
- * 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.View
- * @extends Roo.util.Observable
- * Create a "View" for an element based on a data model or UpdateManager and the supplied DomHelper template.
- * This class also supports single and multi selection modes. <br>
- * Create a data model bound view:
- <pre><code>
- var store = new Roo.data.Store(...);
+ if(this.hasFeedback && !this.allowBlank){
+
+ inputblock.cls += ' has-feedback';
+
+ inputblock.cn.push({
+ tag: 'span',
+ cls: 'glyphicon form-control-feedback'
+ });
+
+ }
+
+ if (this.after) {
+
+ inputblock.cls += (this.before) ? '' : ' input-group';
+
+ inputblock.cn.push({
+ tag :'span',
+ cls : 'input-group-addon',
+ html : this.after
+ });
+ }
- var view = new Roo.View({
- el : "my-element",
- tpl : '<div id="{0}">{2} - {1}</div>', // auto create template
-
- singleSelect: true,
- selectedClass: "ydataview-selected",
- store: store
- });
+ var box = {
+ tag: 'div',
+ cn: [
+ {
+ tag: 'input',
+ type : 'hidden',
+ cls: 'form-hidden-field'
+ },
+ inputblock
+ ]
+
+ };
+
+ if(this.multiple){
+ box = {
+ tag: 'div',
+ cn: [
+ {
+ tag: 'input',
+ type : 'hidden',
+ cls: 'form-hidden-field'
+ },
+ {
+ tag: 'ul',
+ cls: 'select2-choices',
+ cn:[
+ {
+ tag: 'li',
+ cls: 'select2-search-field',
+ cn: [
- // listen for node click?
- view.on("click", function(vw, index, node, e){
- alert('Node "' + node.id + '" at index: ' + index + " was clicked.");
- });
+ inputblock
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ };
+
+ var combobox = {
+ cls: 'select2-container input-group',
+ cn: [
+ box
+ ]
+ };
+
+ if(this.multiple){
+ combobox.cls += ' select2-container-multi';
+ }
+
+ var align = this.labelAlign || this.parentLabelAlign();
+
+ cfg.cn = combobox;
+
+ if(this.fieldLabel.length){
+
+ var lw = align === 'left' ? ('col-sm' + this.labelWidth) : '';
+ var cw = align === 'left' ? ('col-sm' + (12 - this.labelWidth)) : '';
+
+ cfg.cn = [
+ {
+ tag: 'label',
+ cls : 'control-label ' + lw,
+ html : this.fieldLabel
- // load XML data
- dataModel.load("foobar.xml");
- </code></pre>
- For an example of creating a JSON/UpdateManager view, see {@link Roo.JsonView}.
- * <br><br>
- * <b>Note: The root of your template must be a single node. Table/row implementations may work but are not supported due to
- * IE"s limited insertion support with tables and Opera"s faulty event bubbling.</b>
- *
- * Note: old style constructor is still suported (container, template, config)
- *
- * @constructor
- * Create a new View
- * @param {Object} config The config object
- *
- */
-Roo.View = function(config, depreciated_tpl, depreciated_config){
-
- this.parent = false;
-
- if (typeof(depreciated_tpl) == 'undefined') {
- // new way.. - universal constructor.
- Roo.apply(this, config);
- this.el = Roo.get(this.el);
- } else {
- // old format..
- this.el = Roo.get(config);
- this.tpl = depreciated_tpl;
- Roo.apply(this, depreciated_config);
- }
- this.wrapEl = this.el.wrap().wrap();
- ///this.el = this.wrapEla.appendChild(document.createElement("div"));
-
-
- if(typeof(this.tpl) == "string"){
- this.tpl = new Roo.Template(this.tpl);
- } else {
- // support xtype ctors..
- this.tpl = new Roo.factory(this.tpl, Roo);
- }
-
+ },
+ {
+ cls : cw,
+ cn: [
+ combobox
+ ]
+ }
+ ];
+ }
+
+ var settings = this;
+
+ ['xs','sm','md','lg'].map(function(size){
+ if (settings[size]) {
+ cfg.cls += ' col-' + size + '-' + settings[size];
+ }
+ });
+
+ return cfg;
+ },
- this.tpl.compile();
+ initTouchView : function()
+ {
+ this.renderTouchView();
+
+ this.touchViewEl.on('scroll', function(){
+ this.el.dom.scrollTop = 0;
+ }, this);
+
+ this.inputEl().on("click", this.showTouchView, this);
+ this.touchViewFooterEl.select('.roo-touch-view-cancel', true).first().on('click', this.hideTouchView, this);
+ this.touchViewFooterEl.select('.roo-touch-view-ok', true).first().on('click', this.setTouchViewValue, this);
+
+ this.maskEl = new Roo.LoadMask(this.touchViewEl, { store : this.store, msgCls: 'roo-el-mask-msg' });
+
+ this.store.on('beforeload', this.onTouchViewBeforeLoad, this);
+ this.store.on('load', this.onTouchViewLoad, this);
+ this.store.on('loadexception', this.onTouchViewLoadException, this);
+
+ if(this.hiddenName){
+
+ this.hiddenField = this.el.select('input.form-hidden-field',true).first();
+
+ this.hiddenField.dom.value =
+ this.hiddenValue !== undefined ? this.hiddenValue :
+ this.value !== undefined ? this.value : '';
+
+ this.el.dom.removeAttribute('name');
+ this.hiddenField.dom.setAttribute('name', this.hiddenName);
+ }
+
+ if(this.multiple){
+ this.choices = this.el.select('ul.select2-choices', true).first();
+ this.searchField = this.el.select('ul li.select2-search-field', true).first();
+ }
+
+ if(this.removable && !this.multiple){
+ var close = this.closeTriggerEl();
+ if(close){
+ close.setVisibilityMode(Roo.Element.DISPLAY).hide();
+ close.on('click', this.removeBtnClick, this, close);
+ }
+ }
+
+ return;
+
+
+ },
- /** @private */
- this.addEvents({
- /**
- * @event beforeclick
- * Fires before a click is processed. Returns false to cancel the default action.
- * @param {Roo.View} this
- * @param {Number} index The index of the target node
- * @param {HTMLElement} node The target node
- * @param {Roo.EventObject} e The raw event object
- */
- "beforeclick" : true,
- /**
- * @event click
- * Fires when a template node is clicked.
- * @param {Roo.View} this
- * @param {Number} index The index of the target node
- * @param {HTMLElement} node The target node
- * @param {Roo.EventObject} e The raw event object
- */
- "click" : true,
- /**
- * @event dblclick
- * Fires when a template node is double clicked.
- * @param {Roo.View} this
- * @param {Number} index The index of the target node
- * @param {HTMLElement} node The target node
- * @param {Roo.EventObject} e The raw event object
- */
- "dblclick" : true,
- /**
- * @event contextmenu
- * Fires when a template node is right clicked.
- * @param {Roo.View} this
- * @param {Number} index The index of the target node
- * @param {HTMLElement} node The target node
- * @param {Roo.EventObject} e The raw event object
- */
- "contextmenu" : true,
- /**
- * @event selectionchange
- * Fires when the selected nodes change.
- * @param {Roo.View} this
- * @param {Array} selections Array of the selected nodes
- */
- "selectionchange" : true,
+ renderTouchView : function()
+ {
+ this.touchViewEl = Roo.get(document.body).createChild(Roo.bootstrap.ComboBox.touchViewTemplate);
+ this.touchViewEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.touchViewHeaderEl = this.touchViewEl.select('.modal-header', true).first();
+ this.touchViewHeaderEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.touchViewBodyEl = this.touchViewEl.select('.modal-body', true).first();
+ this.touchViewBodyEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+ this.touchViewBodyEl.setStyle('overflow', 'auto');
+
+ this.touchViewListGroup = this.touchViewBodyEl.select('.list-group', true).first();
+ this.touchViewListGroup.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ this.touchViewFooterEl = this.touchViewEl.select('.modal-footer', true).first();
+ this.touchViewFooterEl.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+
+ },
- /**
- * @event beforeselect
- * Fires before a selection is made. If any handlers return false, the selection is cancelled.
- * @param {Roo.View} this
- * @param {HTMLElement} node The node to be selected
- * @param {Array} selections Array of currently selected nodes
- */
- "beforeselect" : true,
- /**
- * @event preparedata
- * Fires on every row to render, to allow you to change the data.
- * @param {Roo.View} this
- * @param {Object} data to be rendered (change this)
- */
- "preparedata" : true
-
-
- });
+ showTouchView : function()
+ {
+ this.touchViewHeaderEl.hide();
+ if(this.fieldLabel.length){
+ this.touchViewHeaderEl.dom.innerHTML = this.fieldLabel;
+ this.touchViewHeaderEl.show();
+ }
+ this.touchViewEl.show();
- this.el.on({
- "click": this.onClick,
- "dblclick": this.onDblClick,
- "contextmenu": this.onContextMenu,
- scope:this
- });
+ this.touchViewEl.select('.modal-dialog', true).first().setStyle('margin', '0px');
+ this.touchViewEl.select('.modal-dialog > .modal-content', true).first().setSize(Roo.lib.Dom.getViewWidth(true), Roo.lib.Dom.getViewHeight(true));
- this.selections = [];
- this.nodes = [];
- this.cmp = new Roo.CompositeElementLite([]);
- if(this.store){
- this.store = Roo.factory(this.store, Roo.data);
- this.setStore(this.store, true);
- }
-
- if ( this.footer && this.footer.xtype) {
-
- var fctr = this.wrapEl.appendChild(document.createElement("div"));
+ var bodyHeight = Roo.lib.Dom.getViewHeight() - this.touchViewFooterEl.getHeight() + this.touchViewBodyEl.getPadding('tb');
+
+ if(this.fieldLabel.length){
+ bodyHeight = bodyHeight - this.touchViewHeaderEl.getHeight();
+ }
- this.footer.dataSource = this.store
- this.footer.container = fctr;
- this.footer = Roo.factory(this.footer, Roo);
- fctr.insertFirst(this.el);
+ this.touchViewBodyEl.setHeight(bodyHeight);
+
+ if(this.animate){
+ var _this = this;
+ (function(){ _this.touchViewEl.addClass('in'); }).defer(50);
+ }else{
+ this.touchViewEl.addClass('in');
+ }
+
+ this.doTouchViewQuery();
- // this is a bit insane - as the paging toolbar seems to detach the el..
-// dom.parentNode.parentNode.parentNode
- // they get detached?
- }
+ },
+ hideTouchView : function()
+ {
+ this.touchViewEl.removeClass('in');
+
+ if(this.animate){
+ var _this = this;
+ (function(){ _this.touchViewEl.setStyle('display', 'none'); }).defer(150);
+ }else{
+ this.touchViewEl.setStyle('display', 'none');
+ }
+
+ },
- Roo.View.superclass.constructor.call(this);
+ setTouchViewValue : function()
+ {
+ if(this.multiple){
+ this.clearItem();
+
+ var _this = this;
+
+ Roo.each(this.tickItems, function(o){
+ this.addItem(o);
+ }, this);
+ }
+
+ this.hideTouchView();
+ },
+ doTouchViewQuery : function()
+ {
+ var qe = {
+ query: '',
+ forceAll: true,
+ combo: this,
+ cancel:false
+ };
+
+ if(this.fireEvent('beforequery', qe) ===false || qe.cancel){
+ return false;
+ }
+
+ if(!this.alwaysQuery || this.mode == 'local'){
+ this.onTouchViewLoad();
+ return;
+ }
+
+ this.store.load();
+ },
-};
+ onTouchViewBeforeLoad : function(combo,opts)
+ {
+ return;
+ },
-Roo.extend(Roo.View, Roo.util.Observable, {
-
- /**
- * @cfg {Roo.data.Store} store Data store to load data from.
- */
- store : false,
+ // private
+ onTouchViewLoad : function()
+ {
+ if(this.store.getCount() < 1){
+ this.onTouchViewEmptyResults();
+ return;
+ }
+
+ this.clearTouchView();
+
+ var rawValue = this.getRawValue();
+
+ var template = (this.multiple) ? Roo.bootstrap.ComboBox.listItemCheckbox : Roo.bootstrap.ComboBox.listItemRadio;
+
+ this.tickItems = [];
+
+ this.store.data.each(function(d, rowIndex){
+ var row = this.touchViewListGroup.createChild(template);
+
+ if(this.displayField && typeof(d.data[this.displayField]) != 'undefined'){
+ row.select('.roo-combobox-list-group-item-value', true).first().dom.innerHTML = d.data[this.displayField];
+ }
+
+ if(!this.multiple && this.valueField && typeof(d.data[this.valueField]) != 'undefined' && d.data[this.valueField] == this.getValue()){
+ row.select('.roo-combobox-list-group-item-box > input', true).first().attr('checked', true);
+ }
+
+ if(this.multiple && this.valueField && typeof(d.data[this.valueField]) != 'undefined' && this.getValue().indexOf(d.data[this.valueField]) != -1){
+ row.select('.roo-combobox-list-group-item-box > input', true).first().attr('checked', true);
+ this.tickItems.push(d.data);
+ }
+
+ row.on('click', this.onTouchViewClick, this, {row : row, rowIndex : rowIndex});
+
+ }, this);
+
+ var firstChecked = this.touchViewListGroup.select('.list-group-item > .roo-combobox-list-group-item-box > input:checked', true).first();
+
+ var bodyHeight = Roo.lib.Dom.getViewHeight() - this.touchViewFooterEl.getHeight() + this.touchViewBodyEl.getPadding('tb');
+
+ if(this.fieldLabel.length){
+ bodyHeight = bodyHeight - this.touchViewHeaderEl.getHeight();
+ }
+
+ var listHeight = this.touchViewListGroup.getHeight();
+
+ if(firstChecked && listHeight > bodyHeight){
+ (function() { firstChecked.findParent('li').scrollIntoView(this.touchViewListGroup.dom); }).defer(500);
+ }
+
+ },
- /**
- * @cfg {String|Roo.Element} el The container element.
- */
- el : '',
+ onTouchViewLoadException : function()
+ {
+ this.hideTouchView();
+ },
- /**
- * @cfg {String|Roo.Template} tpl The template used by this View
- */
- tpl : false,
- /**
- * @cfg {String} dataName the named area of the template to use as the data area
- * Works with domtemplates roo-name="name"
- */
- dataName: false,
- /**
- * @cfg {String} selectedClass The css class to add to selected nodes
- */
- selectedClass : "x-view-selected",
- /**
- * @cfg {String} emptyText The empty text to show when nothing is loaded.
- */
- emptyText : "",
-
- /**
- * @cfg {String} text to display on mask (default Loading)
- */
- mask : false,
- /**
- * @cfg {Boolean} multiSelect Allow multiple selection
- */
- multiSelect : false,
- /**
- * @cfg {Boolean} singleSelect Allow single selection
- */
- singleSelect: false,
-
- /**
- * @cfg {Boolean} toggleSelect - selecting
- */
- toggleSelect : false,
-
- /**
- * @cfg {Boolean} tickable - selecting
- */
- tickable : false,
-
- /**
- * Returns the element this view is bound to.
- * @return {Roo.Element}
- */
- getEl : function(){
- return this.wrapEl;
+ onTouchViewEmptyResults : function()
+ {
+ this.clearTouchView();
+
+ this.touchViewListGroup.createChild(Roo.bootstrap.ComboBox.emptyResult);
+
+ this.touchViewListGroup.select('.roo-combobox-touch-view-empty-result', true).first().dom.innerHTML = this.emptyResultText;
+
},
+ clearTouchView : function()
+ {
+ this.touchViewListGroup.dom.innerHTML = '';
+ },
-
- /**
- * Refreshes the view. - called by datachanged on the store. - do not call directly.
- */
- refresh : function(){
- //Roo.log('refresh');
- var t = this.tpl;
+ onTouchViewClick : function(e, el, o)
+ {
+ e.preventDefault();
- // if we are using something like 'domtemplate', then
- // the what gets used is:
- // t.applySubtemplate(NAME, data, wrapping data..)
- // the outer template then get' applied with
- // the store 'extra data'
- // and the body get's added to the
- // roo-name="data" node?
- // <span class='roo-tpl-{name}'></span> ?????
+ var row = o.row;
+ var rowIndex = o.rowIndex;
+ var r = this.store.getAt(rowIndex);
+ if(!this.multiple){
+ Roo.each(this.touchViewListGroup.select('.list-group-item > .roo-combobox-list-group-item-box > input:checked', true).elements, function(c){
+ c.dom.removeAttribute('checked');
+ }, this);
+
+ row.select('.roo-combobox-list-group-item-box > input', true).first().attr('checked', true);
- this.clearSelections();
- this.el.update("");
- var html = [];
- var records = this.store.getRange();
- if(records.length < 1) {
+ this.setFromData(r.data);
- // is this valid?? = should it render a template??
+ var close = this.closeTriggerEl();
+
+ if(close){
+ close.show();
+ }
+
+ this.hideTouchView();
- this.el.update(this.emptyText);
return;
}
- var el = this.el;
- if (this.dataName) {
- this.el.update(t.apply(this.store.meta)); //????
- el = this.el.child('.roo-tpl-' + this.dataName);
- }
- for(var i = 0, len = records.length; i < len; i++){
- var data = this.prepareData(records[i].data, i, records[i]);
- this.fireEvent("preparedata", this, data, i, records[i]);
-
- var d = Roo.apply({}, data);
-
- if(this.tickable){
- Roo.apply(d, {'roo-id' : Roo.id()});
-
- var _this = this;
-
- Roo.each(this.parent.item, function(item){
- if(item[_this.parent.valueField] != data[_this.parent.valueField]){
- return;
- }
- Roo.apply(d, {'roo-data-checked' : 'checked'});
- });
- }
-
- html[html.length] = Roo.util.Format.trim(
- this.dataName ?
- t.applySubtemplate(this.dataName, d, this.store.meta) :
- t.apply(d)
- );
+ if(this.valueField && typeof(r.data[this.valueField]) != 'undefined' && this.getValue().indexOf(r.data[this.valueField]) != -1){
+ row.select('.roo-combobox-list-group-item-box > input', true).first().dom.removeAttribute('checked');
+ this.tickItems.splice(this.tickItems.indexOf(r.data), 1);
+ return;
}
+ row.select('.roo-combobox-list-group-item-box > input', true).first().attr('checked', true);
+ this.addItem(r.data);
+ this.tickItems.push(r.data);
- el.update(html.join(""));
- this.nodes = el.dom.childNodes;
- this.updateIndexes(0);
- },
+
+ }
+ /**
+ * @cfg {Boolean} grow
+ * @hide
+ */
+ /**
+ * @cfg {Number} growMin
+ * @hide
+ */
+ /**
+ * @cfg {Number} growMax
+ * @hide
+ */
/**
- * Function to override to reformat the data that is sent to
- * the template for each node.
- * DEPRICATED - use the preparedata event handler.
- * @param {Array/Object} data The raw data (array of colData for a data model bound view or
- * a JSON object for an UpdateManager bound view).
+ * @hide
+ * @method autoSize
*/
- prepareData : function(data, index, record)
- {
- this.fireEvent("preparedata", this, data, index, record);
- return data;
- },
+});
- onUpdate : function(ds, record){
- // Roo.log('on update');
- this.clearSelections();
- var index = this.store.indexOf(record);
- var n = this.nodes[index];
- this.tpl.insertBefore(n, this.prepareData(record.data, index, record));
- n.parentNode.removeChild(n);
- this.updateIndexes(index, index);
+Roo.apply(Roo.bootstrap.ComboBox, {
+
+ header : {
+ tag: 'div',
+ cls: 'modal-header',
+ cn: [
+ {
+ tag: 'h4',
+ cls: 'modal-title'
+ }
+ ]
},
-
+ body : {
+ tag: 'div',
+ cls: 'modal-body',
+ cn: [
+ {
+ tag: 'ul',
+ cls: 'list-group'
+ }
+ ]
+ },
-// --------- FIXME
- onAdd : function(ds, records, index)
- {
- //Roo.log(['on Add', ds, records, index] );
- this.clearSelections();
- if(this.nodes.length == 0){
- this.refresh();
- return;
- }
- var n = this.nodes[index];
- for(var i = 0, len = records.length; i < len; i++){
- var d = this.prepareData(records[i].data, i, records[i]);
- if(n){
- this.tpl.insertBefore(n, d);
- }else{
-
- this.tpl.append(this.el, d);
+ listItemRadio : {
+ tag: 'li',
+ cls: 'list-group-item',
+ cn: [
+ {
+ tag: 'span',
+ cls: 'roo-combobox-list-group-item-value'
+ },
+ {
+ tag: 'div',
+ cls: 'roo-combobox-list-group-item-box pull-xs-right radio-inline radio radio-info',
+ cn: [
+ {
+ tag: 'input',
+ type: 'radio'
+ },
+ {
+ tag: 'label'
+ }
+ ]
}
- }
- this.updateIndexes(index);
+ ]
},
-
- onRemove : function(ds, record, index){
- // Roo.log('onRemove');
- this.clearSelections();
- var el = this.dataName ?
- this.el.child('.roo-tpl-' + this.dataName) :
- this.el;
-
- el.dom.removeChild(this.nodes[index]);
- this.updateIndexes(index);
+
+ listItemCheckbox : {
+ tag: 'li',
+ cls: 'list-group-item',
+ cn: [
+ {
+ tag: 'span',
+ cls: 'roo-combobox-list-group-item-value'
+ },
+ {
+ tag: 'div',
+ cls: 'roo-combobox-list-group-item-box pull-xs-right checkbox-inline checkbox checkbox-info',
+ cn: [
+ {
+ tag: 'input',
+ type: 'checkbox'
+ },
+ {
+ tag: 'label'
+ }
+ ]
+ }
+ ]
},
-
- /**
- * Refresh an individual node.
- * @param {Number} index
- */
- refreshNode : function(index){
- this.onUpdate(this.store, this.store.getAt(index));
+
+ emptyResult : {
+ tag: 'div',
+ cls: 'alert alert-danger roo-combobox-touch-view-empty-result'
},
+
+ footer : {
+ tag: 'div',
+ cls: 'modal-footer',
+ cn: [
+ {
+ tag: 'div',
+ cls: 'row',
+ cn: [
+ {
+ tag: 'div',
+ cls: 'col-xs-6 text-left',
+ cn: {
+ tag: 'button',
+ cls: 'btn btn-danger roo-touch-view-cancel',
+ html: 'Cancel'
+ }
+ },
+ {
+ tag: 'div',
+ cls: 'col-xs-6 text-right',
+ cn: {
+ tag: 'button',
+ cls: 'btn btn-success roo-touch-view-ok',
+ html: 'OK'
+ }
+ }
+ ]
+ }
+ ]
+
+ }
+});
- updateIndexes : function(startIndex, endIndex){
- var ns = this.nodes;
- startIndex = startIndex || 0;
- endIndex = endIndex || ns.length - 1;
- for(var i = startIndex; i <= endIndex; i++){
- ns[i].nodeIndex = i;
- }
- },
+Roo.apply(Roo.bootstrap.ComboBox, {
+
+ touchViewTemplate : {
+ tag: 'div',
+ cls: 'modal fade roo-combobox-touch-view',
+ cn: [
+ {
+ tag: 'div',
+ cls: 'modal-dialog',
+ cn: [
+ {
+ tag: 'div',
+ cls: 'modal-content',
+ cn: [
+ Roo.bootstrap.ComboBox.header,
+ Roo.bootstrap.ComboBox.body,
+ Roo.bootstrap.ComboBox.footer
+ ]
+ }
+ ]
+ }
+ ]
+ }
+});/*
+ * 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">
+ */
- /**
- * Changes the data store this view uses and refresh the view.
- * @param {Store} store
- */
- setStore : function(store, initial){
- if(!initial && this.store){
- this.store.un("datachanged", this.refresh);
- this.store.un("add", this.onAdd);
- this.store.un("remove", this.onRemove);
- this.store.un("update", this.onUpdate);
- this.store.un("clear", this.refresh);
- this.store.un("beforeload", this.onBeforeLoad);
- this.store.un("load", this.onLoad);
- this.store.un("loadexception", this.onLoad);
- }
- if(store){
+/**
+ * @class Roo.View
+ * @extends Roo.util.Observable
+ * Create a "View" for an element based on a data model or UpdateManager and the supplied DomHelper template.
+ * This class also supports single and multi selection modes. <br>
+ * Create a data model bound view:
+ <pre><code>
+ var store = new Roo.data.Store(...);
+
+ var view = new Roo.View({
+ el : "my-element",
+ tpl : '<div id="{0}">{2} - {1}</div>', // auto create template
+
+ singleSelect: true,
+ selectedClass: "ydataview-selected",
+ store: store
+ });
+
+ // listen for node click?
+ view.on("click", function(vw, index, node, e){
+ alert('Node "' + node.id + '" at index: ' + index + " was clicked.");
+ });
+
+ // load XML data
+ dataModel.load("foobar.xml");
+ </code></pre>
+ For an example of creating a JSON/UpdateManager view, see {@link Roo.JsonView}.
+ * <br><br>
+ * <b>Note: The root of your template must be a single node. Table/row implementations may work but are not supported due to
+ * IE"s limited insertion support with tables and Opera"s faulty event bubbling.</b>
+ *
+ * Note: old style constructor is still suported (container, template, config)
+ *
+ * @constructor
+ * Create a new View
+ * @param {Object} config The config object
+ *
+ */
+Roo.View = function(config, depreciated_tpl, depreciated_config){
+
+ this.parent = false;
+
+ if (typeof(depreciated_tpl) == 'undefined') {
+ // new way.. - universal constructor.
+ Roo.apply(this, config);
+ this.el = Roo.get(this.el);
+ } else {
+ // old format..
+ this.el = Roo.get(config);
+ this.tpl = depreciated_tpl;
+ Roo.apply(this, depreciated_config);
+ }
+ this.wrapEl = this.el.wrap().wrap();
+ ///this.el = this.wrapEla.appendChild(document.createElement("div"));
+
+
+ if(typeof(this.tpl) == "string"){
+ this.tpl = new Roo.Template(this.tpl);
+ } else {
+ // support xtype ctors..
+ this.tpl = new Roo.factory(this.tpl, Roo);
+ }
+
+
+ this.tpl.compile();
+
+ /** @private */
+ this.addEvents({
+ /**
+ * @event beforeclick
+ * Fires before a click is processed. Returns false to cancel the default action.
+ * @param {Roo.View} this
+ * @param {Number} index The index of the target node
+ * @param {HTMLElement} node The target node
+ * @param {Roo.EventObject} e The raw event object
+ */
+ "beforeclick" : true,
+ /**
+ * @event click
+ * Fires when a template node is clicked.
+ * @param {Roo.View} this
+ * @param {Number} index The index of the target node
+ * @param {HTMLElement} node The target node
+ * @param {Roo.EventObject} e The raw event object
+ */
+ "click" : true,
+ /**
+ * @event dblclick
+ * Fires when a template node is double clicked.
+ * @param {Roo.View} this
+ * @param {Number} index The index of the target node
+ * @param {HTMLElement} node The target node
+ * @param {Roo.EventObject} e The raw event object
+ */
+ "dblclick" : true,
+ /**
+ * @event contextmenu
+ * Fires when a template node is right clicked.
+ * @param {Roo.View} this
+ * @param {Number} index The index of the target node
+ * @param {HTMLElement} node The target node
+ * @param {Roo.EventObject} e The raw event object
+ */
+ "contextmenu" : true,
+ /**
+ * @event selectionchange
+ * Fires when the selected nodes change.
+ * @param {Roo.View} this
+ * @param {Array} selections Array of the selected nodes
+ */
+ "selectionchange" : true,
+
+ /**
+ * @event beforeselect
+ * Fires before a selection is made. If any handlers return false, the selection is cancelled.
+ * @param {Roo.View} this
+ * @param {HTMLElement} node The node to be selected
+ * @param {Array} selections Array of currently selected nodes
+ */
+ "beforeselect" : true,
+ /**
+ * @event preparedata
+ * Fires on every row to render, to allow you to change the data.
+ * @param {Roo.View} this
+ * @param {Object} data to be rendered (change this)
+ */
+ "preparedata" : true
- store.on("datachanged", this.refresh, this);
- store.on("add", this.onAdd, this);
- store.on("remove", this.onRemove, this);
- store.on("update", this.onUpdate, this);
- store.on("clear", this.refresh, this);
- store.on("beforeload", this.onBeforeLoad, this);
- store.on("load", this.onLoad, this);
- store.on("loadexception", this.onLoad, this);
- }
+
+ });
+
+
+
+ this.el.on({
+ "click": this.onClick,
+ "dblclick": this.onDblClick,
+ "contextmenu": this.onContextMenu,
+ scope:this
+ });
+
+ this.selections = [];
+ this.nodes = [];
+ this.cmp = new Roo.CompositeElementLite([]);
+ if(this.store){
+ this.store = Roo.factory(this.store, Roo.data);
+ this.setStore(this.store, true);
+ }
+
+ if ( this.footer && this.footer.xtype) {
+
+ var fctr = this.wrapEl.appendChild(document.createElement("div"));
- if(store){
- this.refresh();
- }
- },
+ this.footer.dataSource = this.store
+ this.footer.container = fctr;
+ this.footer = Roo.factory(this.footer, Roo);
+ fctr.insertFirst(this.el);
+
+ // this is a bit insane - as the paging toolbar seems to detach the el..
+// dom.parentNode.parentNode.parentNode
+ // they get detached?
+ }
+
+
+ Roo.View.superclass.constructor.call(this);
+
+
+};
+
+Roo.extend(Roo.View, Roo.util.Observable, {
+
+ /**
+ * @cfg {Roo.data.Store} store Data store to load data from.
+ */
+ store : false,
+
/**
- * onbeforeLoad - masks the loading area.
- *
+ * @cfg {String|Roo.Element} el The container element.
*/
- onBeforeLoad : function(store,opts)
- {
- //Roo.log('onBeforeLoad');
- if (!opts.add) {
- this.el.update("");
- }
- this.el.mask(this.mask ? this.mask : "Loading" );
- },
- onLoad : function ()
- {
- this.el.unmask();
- },
+ el : '',
-
/**
- * Returns the template node the passed child belongs to or null if it doesn't belong to one.
- * @param {HTMLElement} node
- * @return {HTMLElement} The template node
+ * @cfg {String|Roo.Template} tpl The template used by this View
*/
- findItemFromChild : function(node){
+ tpl : false,
+ /**
+ * @cfg {String} dataName the named area of the template to use as the data area
+ * Works with domtemplates roo-name="name"
+ */
+ dataName: false,
+ /**
+ * @cfg {String} selectedClass The css class to add to selected nodes
+ */
+ selectedClass : "x-view-selected",
+ /**
+ * @cfg {String} emptyText The empty text to show when nothing is loaded.
+ */
+ emptyText : "",
+
+ /**
+ * @cfg {String} text to display on mask (default Loading)
+ */
+ mask : false,
+ /**
+ * @cfg {Boolean} multiSelect Allow multiple selection
+ */
+ multiSelect : false,
+ /**
+ * @cfg {Boolean} singleSelect Allow single selection
+ */
+ singleSelect: false,
+
+ /**
+ * @cfg {Boolean} toggleSelect - selecting
+ */
+ toggleSelect : false,
+
+ /**
+ * @cfg {Boolean} tickable - selecting
+ */
+ tickable : false,
+
+ /**
+ * Returns the element this view is bound to.
+ * @return {Roo.Element}
+ */
+ getEl : function(){
+ return this.wrapEl;
+ },
+
+
+
+ /**
+ * Refreshes the view. - called by datachanged on the store. - do not call directly.
+ */
+ refresh : function(){
+ //Roo.log('refresh');
+ var t = this.tpl;
+
+ // if we are using something like 'domtemplate', then
+ // the what gets used is:
+ // t.applySubtemplate(NAME, data, wrapping data..)
+ // the outer template then get' applied with
+ // the store 'extra data'
+ // and the body get's added to the
+ // roo-name="data" node?
+ // <span class='roo-tpl-{name}'></span> ?????
+
+
+
+ this.clearSelections();
+ this.el.update("");
+ var html = [];
+ var records = this.store.getRange();
+ if(records.length < 1) {
+
+ // is this valid?? = should it render a template??
+
+ this.el.update(this.emptyText);
+ return;
+ }
+ var el = this.el;
+ if (this.dataName) {
+ this.el.update(t.apply(this.store.meta)); //????
+ el = this.el.child('.roo-tpl-' + this.dataName);
+ }
+
+ for(var i = 0, len = records.length; i < len; i++){
+ var data = this.prepareData(records[i].data, i, records[i]);
+ this.fireEvent("preparedata", this, data, i, records[i]);
+
+ var d = Roo.apply({}, data);
+
+ if(this.tickable){
+ Roo.apply(d, {'roo-id' : Roo.id()});
+
+ var _this = this;
+
+ Roo.each(this.parent.item, function(item){
+ if(item[_this.parent.valueField] != data[_this.parent.valueField]){
+ return;
+ }
+ Roo.apply(d, {'roo-data-checked' : 'checked'});
+ });
+ }
+
+ html[html.length] = Roo.util.Format.trim(
+ this.dataName ?
+ t.applySubtemplate(this.dataName, d, this.store.meta) :
+ t.apply(d)
+ );
+ }
+
+
+
+ el.update(html.join(""));
+ this.nodes = el.dom.childNodes;
+ this.updateIndexes(0);
+ },
+
+
+ /**
+ * Function to override to reformat the data that is sent to
+ * the template for each node.
+ * DEPRICATED - use the preparedata event handler.
+ * @param {Array/Object} data The raw data (array of colData for a data model bound view or
+ * a JSON object for an UpdateManager bound view).
+ */
+ prepareData : function(data, index, record)
+ {
+ this.fireEvent("preparedata", this, data, index, record);
+ return data;
+ },
+
+ onUpdate : function(ds, record){
+ // Roo.log('on update');
+ this.clearSelections();
+ var index = this.store.indexOf(record);
+ var n = this.nodes[index];
+ this.tpl.insertBefore(n, this.prepareData(record.data, index, record));
+ n.parentNode.removeChild(n);
+ this.updateIndexes(index, index);
+ },
+
+
+
+// --------- FIXME
+ onAdd : function(ds, records, index)
+ {
+ //Roo.log(['on Add', ds, records, index] );
+ this.clearSelections();
+ if(this.nodes.length == 0){
+ this.refresh();
+ return;
+ }
+ var n = this.nodes[index];
+ for(var i = 0, len = records.length; i < len; i++){
+ var d = this.prepareData(records[i].data, i, records[i]);
+ if(n){
+ this.tpl.insertBefore(n, d);
+ }else{
+
+ this.tpl.append(this.el, d);
+ }
+ }
+ this.updateIndexes(index);
+ },
+
+ onRemove : function(ds, record, index){
+ // Roo.log('onRemove');
+ this.clearSelections();
+ var el = this.dataName ?
+ this.el.child('.roo-tpl-' + this.dataName) :
+ this.el;
+
+ el.dom.removeChild(this.nodes[index]);
+ this.updateIndexes(index);
+ },
+
+ /**
+ * Refresh an individual node.
+ * @param {Number} index
+ */
+ refreshNode : function(index){
+ this.onUpdate(this.store, this.store.getAt(index));
+ },
+
+ updateIndexes : function(startIndex, endIndex){
+ var ns = this.nodes;
+ startIndex = startIndex || 0;
+ endIndex = endIndex || ns.length - 1;
+ for(var i = startIndex; i <= endIndex; i++){
+ ns[i].nodeIndex = i;
+ }
+ },
+
+ /**
+ * Changes the data store this view uses and refresh the view.
+ * @param {Store} store
+ */
+ setStore : function(store, initial){
+ if(!initial && this.store){
+ this.store.un("datachanged", this.refresh);
+ this.store.un("add", this.onAdd);
+ this.store.un("remove", this.onRemove);
+ this.store.un("update", this.onUpdate);
+ this.store.un("clear", this.refresh);
+ this.store.un("beforeload", this.onBeforeLoad);
+ this.store.un("load", this.onLoad);
+ this.store.un("loadexception", this.onLoad);
+ }
+ if(store){
+
+ store.on("datachanged", this.refresh, this);
+ store.on("add", this.onAdd, this);
+ store.on("remove", this.onRemove, this);
+ store.on("update", this.onUpdate, this);
+ store.on("clear", this.refresh, this);
+ store.on("beforeload", this.onBeforeLoad, this);
+ store.on("load", this.onLoad, this);
+ store.on("loadexception", this.onLoad, this);
+ }
+
+ if(store){
+ this.refresh();
+ }
+ },
+ /**
+ * onbeforeLoad - masks the loading area.
+ *
+ */
+ onBeforeLoad : function(store,opts)
+ {
+ //Roo.log('onBeforeLoad');
+ if (!opts.add) {
+ this.el.update("");
+ }
+ this.el.mask(this.mask ? this.mask : "Loading" );
+ },
+ onLoad : function ()
+ {
+ this.el.unmask();
+ },
+
+
+ /**
+ * Returns the template node the passed child belongs to or null if it doesn't belong to one.
+ * @param {HTMLElement} node
+ * @return {HTMLElement} The template node
+ */
+ findItemFromChild : function(node){
var el = this.dataName ?
this.el.child('.roo-tpl-' + this.dataName,true) :
this.el.dom;
},
setTitle: function(str)
{
+ this.title = str;
this.el.select('.popover-title',true).first().dom.innerHTML = str;
},
setContent: function(str)
{
+ this.html = str;
this.el.select('.popover-content',true).first().dom.innerHTML = str;
},
// as it get's added to the bottom of the page.
// set content.
this.el.select('.popover-title',true).first().dom.innerHtml = this.title;
if (this.html !== false) {
- this.el.select('.popover-content',true).first().dom.innerHtml = this.title;
+ this.el.select('.popover-content',true).first().dom.innerHtml = this.html;
}
this.el.removeClass(['fade','top','bottom', 'left', 'right','in']);
if (!this.title.length) {
//arrow.set(align[2],
this.el.addClass('in');
- this.hoverState = null;
+
if (this.el.hasClass('fade')) {
// fade it?
this.el.setXY([0,0]);
this.el.removeClass('in');
this.el.hide();
+ this.hoverState = null;
}
* @cfg {String} navId the navigation id (for use with navbars) - will be auto generated if it does not exist..
* @cfg {Boolean} carousel true to make the group behave like a carousel
* @cfg {Number} bullets show the panel pointer.. default 0
- * @cfg {Boolena} autoslide (true|false) auto slide .. default false
+ * @cfg {Boolean} autoslide (true|false) auto slide .. default false
+ * @cfg {Boolean} slideOnTouch (true|false) slide on touch .. default false
* @cfg {Number} timer auto slide timer .. default 0 millisecond
*
* @constructor
timer : 0,
autoslide : false,
slideFn : false,
+ slideOnTouch : false,
getAutoCreate : function()
{
cfg.cls += ' tab-content';
+ Roo.log('get auto create...............');
+
if (this.carousel) {
cfg.cls += ' carousel slide';
cls : 'carousel-inner'
}];
- if(this.bullets > 0){
+ if(this.bullets > 0 && !Roo.isTouch){
var bullets = {
cls : 'carousel-bullets',
cn : []
};
+ if(this.bullets_cls){
+ bullets.cls = bullets.cls + ' ' + this.bullets_cls;
+ }
+
for (var i = 0; i < this.bullets; i++){
bullets.cn.push({
cls : 'bullet bullet-' + i
{
Roo.log('-------- init events on tab group ---------');
- var _this = this;
+ if(this.bullets > 0 && !Roo.isTouch){
+ this.initBullet();
+ }
- if(this.bullets > 0){
-
- for (var i = 0; i < this.bullets; i++){
- var bullet = this.el.select('.bullet-' + i, true).first();
-
- if(!bullet){
- continue;
- }
-
- bullet.on('click', (function(e, el, o, ii, t){
-
- e.preventDefault();
-
- _this.showPanel(ii);
-
- }).createDelegate(this, [i, bullet], true));
-
- }
+ Roo.log(this);
+
+ if(Roo.isTouch && this.slideOnTouch){
+ this.el.on("touchstart", this.onTouchStart, this);
}
if(this.autoslide){
+ var _this = this;
+
this.slideFn = window.setInterval(function() {
_this.showPanelNext();
}, this.timer);
}
+
+ },
+
+ onTouchStart : function(e, el, o)
+ {
+ if(!this.slideOnTouch || !Roo.isTouch || Roo.get(e.getTarget()).hasClass('roo-button-text')){
+ return;
+ }
+
+ this.showPanelNext();
},
getChildContainer : function()
return false;
}
- if(this.bullets > 0){
+ if(this.bullets > 0 && !Roo.isTouch){
this.setActiveBullet(this.indexOfPanel(pan));
}
this.showPanel(this.tabs[i-1]);
},
+ initBullet : function()
+ {
+ if(Roo.isTouch){
+ return;
+ }
+
+ var _this = this;
+
+ for (var i = 0; i < this.bullets; i++){
+ var bullet = this.el.select('.bullet-' + i, true).first();
+
+ if(!bullet){
+ continue;
+ }
+
+ bullet.on('click', (function(e, el, o, ii, t){
+
+ e.preventDefault();
+
+ _this.showPanel(ii);
+
+ if(_this.autoslide && _this.slideFn){
+ clearInterval(_this.slideFn);
+ _this.slideFn = window.setInterval(function() {
+ _this.showPanelNext();
+ }, _this.timer);
+ }
+
+ }).createDelegate(this, [i, bullet], true));
+ }
+ },
+
setActiveBullet : function(i)
{
+ if(Roo.isTouch){
+ return;
+ }
+
Roo.each(this.el.select('.bullet', true).elements, function(el){
el.removeClass('selected');
});
this.execCmd('FontSize', v );
},
- onEditorEvent : function(e){
+ onEditorEvent : function(e)
+ {
this.owner.fireEvent('editorevent', this, e);
// this.updateToolbar();
this.syncValue(); //we can not sync so often.. sync cleans, so this breaks stuff
},
+
/**
* Clean up MS wordisms...
*/
cleanWord : function(node)
{
- var _t = this;
- var cleanWordChildren = function()
- {
- if (!node.childNodes.length) {
- return;
- }
- for (var i = node.childNodes.length-1; i > -1 ; i--) {
- _t.cleanWord(node.childNodes[i]);
- }
- }
if (!node) {
node.parentNode.insertBefore(cn, node);
}
node.parentNode.removeChild(node);
- cleanWordChildren();
+ this.iterateChildren(node, this.cleanWord);
return;
}
// clean styles
node.removeAttribute('style');
}
}
+ this.iterateChildren(node, this.cleanWord);
+
+
+
+ },
+ /**
+ * iterateChildren of a Node, calling fn each time, using this as the scole..
+ * @param {DomNode} node node to iterate children of.
+ * @param {Function} fn method of this class to call on each item.
+ */
+ iterateChildren : function(node, fn)
+ {
+ if (!node.childNodes.length) {
+ return;
+ }
+ for (var i = node.childNodes.length-1; i > -1 ; i--) {
+ fn.call(this, node.childNodes[i])
+ }
+ },
+
+
+ /**
+ * cleanTableWidths.
+ *
+ * Quite often pasting from word etc.. results in tables with column and widths.
+ * This does not work well on fluid HTML layouts - like emails. - so this code should hunt an destroy them..
+ *
+ */
+ cleanTableWidths : function(node)
+ {
+
+
+ if (!node) {
+ this.cleanTableWidths(this.doc.body);
+ return;
+ }
+
+ // ignore list...
+ if (node.nodeName == "#text" || node.nodeName == "#comment") {
+ return;
+ }
+ Roo.log(node.tagName);
+ if (!node.tagName.toLowerCase().match(/^(table|td|tr)$/)) {
+ this.iterateChildren(node, this.cleanTableWidths);
+ return;
+ }
+ if (node.hasAttribute('width')) {
+ node.removeAttribute('width');
+ }
+
+
+ if (node.hasAttribute("style")) {
+ // pretty basic...
+
+ var styles = node.getAttribute("style").split(";");
+ var nstyle = [];
+ Roo.each(styles, function(s) {
+ if (!s.match(/:/)) {
+ return;
+ }
+ var kv = s.split(":");
+ if (kv[0].match(/^\s*(width|min-width)\s*$/)) {
+ return;
+ }
+ // what ever is left... we allow.
+ nstyle.push(s);
+ });
+ node.setAttribute("style", nstyle.length ? nstyle.join(';') : '');
+ if (!nstyle.length) {
+ node.removeAttribute('style');
+ }
+ }
- cleanWordChildren();
+ this.iterateChildren(node, this.cleanTableWidths);
},
+
+
+
+
domToHTML : function(currentElement, depth, nopadtext) {
depth = depth || 0;
//html : 'submit'
pressed : toggle ? false : null,
listeners : {}
- }
+ };
a.listeners[toggle ? 'toggle' : 'click'] = function() {
handler ? handler.call(_this,this) :_this.onBtnClick.call(_this, cmd || id);
- }
+ };
children.push(a);
return a;
}
editor.focus();
}
}
-
+
+ });
+ */
+
+
+ this.xtype = 'NavSimplebar';
+
+ for(var i=0;i< children.length;i++) {
+
+ this.buttons.add(this.addxtypeChild(children[i]));
+
+ }
+
+ editor.on('editorevent', this.updateToolbar, this);
+ },
+ onBtnClick : function(id)
+ {
+ this.editorcore.relayCmd(id);
+ this.editorcore.focus();
+ },
+
+ /**
+ * Protected method that will not generally be called directly. It triggers
+ * a toolbar update by reading the markup state of the current selection in the editor.
+ */
+ updateToolbar: function(){
+
+ if(!this.editorcore.activated){
+ this.editor.onFirstFocus(); // is this neeed?
+ return;
+ }
+
+ var btns = this.buttons;
+ var doc = this.editorcore.doc;
+ btns.get('bold').setActive(doc.queryCommandState('bold'));
+ btns.get('italic').setActive(doc.queryCommandState('italic'));
+ //btns.get('underline').setActive(doc.queryCommandState('underline'));
+
+ btns.get('align-left').setActive(doc.queryCommandState('justifyleft'));
+ btns.get('align-center').setActive(doc.queryCommandState('justifycenter'));
+ btns.get('align-right').setActive(doc.queryCommandState('justifyright'));
+
+ //btns[frameId + '-insertorderedlist').setActive(doc.queryCommandState('insertorderedlist'));
+ btns.get('list').setActive(doc.queryCommandState('insertunorderedlist'));
+ /*
+
+ var ans = this.editorcore.getAllAncestors();
+ if (this.formatCombo) {
+
+
+ var store = this.formatCombo.store;
+ this.formatCombo.setValue("");
+ for (var i =0; i < ans.length;i++) {
+ if (ans[i] && store.query('tag',ans[i].tagName.toLowerCase(), false).length) {
+ // select it..
+ this.formatCombo.setValue(ans[i].tagName.toLowerCase());
+ break;
+ }
+ }
+ }
+
+
+
+ // hides menus... - so this cant be on a menu...
+ Roo.bootstrap.MenuMgr.hideAll();
+ */
+ Roo.bootstrap.MenuMgr.hideAll();
+ //this.editorsyncValue();
+ },
+ onFirstFocus: function() {
+ this.buttons.each(function(item){
+ item.enable();
+ });
+ },
+ toggleSourceEdit : function(sourceEditMode){
+
+
+ if(sourceEditMode){
+ Roo.log("disabling buttons");
+ this.buttons.each( function(item){
+ if(item.cmd != 'pencil'){
+ item.disable();
+ }
+ });
+
+ }else{
+ Roo.log("enabling buttons");
+ if(this.editorcore.initialized){
+ this.buttons.each( function(item){
+ item.enable();
+ });
+ }
+
+ }
+ Roo.log("calling toggole on editor");
+ // tell the editor that it's been pressed..
+ this.editor.toggleSourceEdit(sourceEditMode);
+
+ }
+});
+
+
+
+
+
+/**
+ * @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;
+ }
+});
+/**
+ * @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.grid.on("mousedown", this.handleMouseDown, this);
+ }else{ // allow click to work like normal
+ this.grid.on("rowclick", this.handleDragableRowClick, 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
+ });
+
+ 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.dataSource, 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);
+ }
});
- */
-
-
- this.xtype = 'NavSimplebar';
-
- for(var i=0;i< children.length;i++) {
-
- this.buttons.add(this.addxtypeChild(children[i]));
-
+ },
+
+ // private
+ onRemove : function(v, index, r){
+ this.selections.remove(r);
+ },
+
+ // private
+ onRowUpdated : function(v, index, r){
+ if(this.isSelected(r)){
+ v.onRowSelect(index);
}
-
- editor.on('editorevent', this.updateToolbar, this);
},
- onBtnClick : function(id)
- {
- this.editorcore.relayCmd(id);
- this.editorcore.focus();
+
+ /**
+ * 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.dataSource;
+ for(var i = 0, len = records.length; i < len; i++){
+ this.selectRow(ds.indexOf(records[i]), true);
+ }
},
-
+
/**
- * Protected method that will not generally be called directly. It triggers
- * a toolbar update by reading the markup state of the current selection in the editor.
+ * Gets the number of selected rows.
+ * @return {Number}
*/
- updateToolbar: function(){
+ getCount : function(){
+ return this.selections.length;
+ },
- if(!this.editorcore.activated){
- this.editor.onFirstFocus(); // is this neeed?
- return;
+ /**
+ * 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);
+ },
+
+ /**
+ * 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.dataSource.getCount()){
+ this.selectRow(this.last+1, keepExisting);
+ this.grid.getView().focusRow(this.last);
}
+ },
- var btns = this.buttons;
- var doc = this.editorcore.doc;
- btns.get('bold').setActive(doc.queryCommandState('bold'));
- btns.get('italic').setActive(doc.queryCommandState('italic'));
- //btns.get('underline').setActive(doc.queryCommandState('underline'));
-
- btns.get('align-left').setActive(doc.queryCommandState('justifyleft'));
- btns.get('align-center').setActive(doc.queryCommandState('justifycenter'));
- btns.get('align-right').setActive(doc.queryCommandState('justifyright'));
-
- //btns[frameId + '-insertorderedlist').setActive(doc.queryCommandState('insertorderedlist'));
- btns.get('list').setActive(doc.queryCommandState('insertunorderedlist'));
- /*
-
- var ans = this.editorcore.getAllAncestors();
- if (this.formatCombo) {
-
-
- var store = this.formatCombo.store;
- this.formatCombo.setValue("");
- for (var i =0; i < ans.length;i++) {
- if (ans[i] && store.query('tag',ans[i].tagName.toLowerCase(), false).length) {
- // select it..
- this.formatCombo.setValue(ans[i].tagName.toLowerCase());
- break;
- }
- }
+ /**
+ * 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);
}
-
-
-
- // hides menus... - so this cant be on a menu...
- Roo.bootstrap.MenuMgr.hideAll();
- */
- Roo.bootstrap.MenuMgr.hideAll();
- //this.editorsyncValue();
},
- onFirstFocus: function() {
- this.buttons.each(function(item){
- item.enable();
- });
+
+ /**
+ * Returns the selected records
+ * @return {Array} Array of selected records
+ */
+ getSelections : function(){
+ return [].concat(this.selections.items);
},
- toggleSourceEdit : function(sourceEditMode){
-
-
- if(sourceEditMode){
- Roo.log("disabling buttons");
- this.buttons.each( function(item){
- if(item.cmd != 'pencil'){
- item.disable();
- }
- });
-
+
+ /**
+ * 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.dataSource;
+ var s = this.selections;
+ s.each(function(r){
+ this.deselectRow(ds.indexOfId(r.id));
+ }, this);
+ s.clear();
}else{
- Roo.log("enabling buttons");
- if(this.editorcore.initialized){
- this.buttons.each( function(item){
- item.enable();
- });
+ 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.dataSource.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.dataSource.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.getView(), 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);
}
-
}
- Roo.log("calling toggole on editor");
- // tell the editor that it's been pressed..
- this.editor.toggleSourceEdit(sourceEditMode);
-
- }
-});
-
-
-
-
-
-/**
- * @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();
+ 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);
+ }
},
/**
- * Locks the selections.
+ * 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
*/
- lock : function(){
- this.locked = true;
+ 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);
+ }
+ }
},
/**
- * Unlocks the selections.
+ * 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
*/
- unlock : function(){
- this.locked = false;
+ deselectRange : function(startRow, endRow, preventViewNotify){
+ if(this.locked) return;
+ for(var i = startRow; i <= endRow; i++){
+ this.deselectRow(i, preventViewNotify);
+ }
},
/**
- * Returns true if the selections are locked.
- * @return {Boolean}
+ * Selects a row.
+ * @param {Number} row The index of the row to select
+ * @param {Boolean} keepExisting (optional) True to keep existing selections
*/
- isLocked : function(){
- return this.locked;
- }
-});
-/**
- * @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;
-};
+ selectRow : function(index, keepExisting, preventViewNotify){
+ if(this.locked || (index < 0 || index >= this.grid.dataSource.getCount())) return;
+ if(this.fireEvent("beforerowselect", this, index, keepExisting) !== false){
+ if(!keepExisting || this.singleSelect){
+ this.clearSelections();
+ }
+ var r = this.grid.dataSource.getAt(index);
+ this.selections.add(r);
+ this.last = this.lastActive = index;
+ if(!preventViewNotify){
+ this.grid.getView().onRowSelect(index);
+ }
+ this.fireEvent("rowselect", this, index, r);
+ this.fireEvent("selectionchange", this);
+ }
+ },
-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)
+ * Deselects a row.
+ * @param {Number} row The index of the row to deselect
*/
- 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);
+ deselectRow : function(index, preventViewNotify){
+ if(this.locked) return;
+ if(this.last == index){
+ this.last = false;
}
-
- 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
- });
-
- var view = this.grid.view;
- view.on("refresh", this.onRefresh, this);
- view.on("rowupdated", this.onRowUpdated, this);
- view.on("rowremoved", this.onRemove, this);
+ if(this.lastActive == index){
+ this.lastActive = false;
+ }
+ var r = this.grid.dataSource.getAt(index);
+ this.selections.remove(r);
+ if(!preventViewNotify){
+ this.grid.getView().onRowDeselect(index);
+ }
+ this.fireEvent("rowdeselect", this, index);
+ this.fireEvent("selectionchange", this);
},
// private
- onRefresh : function(){
- var ds = this.grid.dataSource, 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);
- }
- });
+ restoreLast : function(){
+ if(this._last){
+ this.last = this._last;
+ }
},
// private
- onRemove : function(v, index, r){
- this.selections.remove(r);
+ acceptsNav : function(row, col, cm){
+ return !cm.isHidden(col) && cm.isCellEditable(col, row);
},
// private
- onRowUpdated : function(v, index, r){
- if(this.isSelected(r)){
- v.onRowSelect(index);
+ 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">
+ */
+
+/**
+ * @class Roo.bootstrap.PagingToolbar
+ * @extends Roo.Row
+ * A specialized toolbar that is bound to a {@link Roo.data.Store} and provides automatic paging controls.
+ * @constructor
+ * Create a new PagingToolbar
+ * @param {Object} config The config object
+ */
+Roo.bootstrap.PagingToolbar = function(config)
+{
+ // old args format still supported... - xtype is prefered..
+ // created from xtype...
+ var ds = config.dataSource;
+ this.toolbarItems = [];
+ if (config.items) {
+ this.toolbarItems = config.items;
+// config.items = [];
+ }
+
+ Roo.bootstrap.PagingToolbar.superclass.constructor.call(this, config);
+ this.ds = ds;
+ this.cursor = 0;
+ if (ds) {
+ this.bind(ds);
+ }
+
+ this.navgroup = new Roo.bootstrap.NavGroup({ cls: 'pagination' });
+
+};
+Roo.extend(Roo.bootstrap.PagingToolbar, Roo.bootstrap.NavSimplebar, {
/**
- * Select records.
- * @param {Array} records The records to select
- * @param {Boolean} keepExisting (optional) True to keep existing selections
+ * @cfg {Roo.data.Store} dataSource
+ * The underlying data store providing the paged data
*/
- selectRecords : function(records, keepExisting){
- if(!keepExisting){
- this.clearSelections();
- }
- var ds = this.grid.dataSource;
- 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}
+ * @cfg {String/HTMLElement/Element} container
+ * container The id or element that will contain the toolbar
*/
- getCount : function(){
- return this.selections.length;
- },
-
/**
- * Selects the first row in the grid.
+ * @cfg {Boolean} displayInfo
+ * True to display the displayMsg (defaults to false)
*/
- selectFirstRow : function(){
- this.selectRow(0);
- },
-
/**
- * Select the last row.
- * @param {Boolean} keepExisting (optional) True to keep existing selections
+ * @cfg {Number} pageSize
+ * The number of records to display per page (defaults to 20)
*/
- selectLastRow : function(keepExisting){
- this.selectRow(this.grid.dataSource.getCount() - 1, keepExisting);
- },
-
+ pageSize: 20,
/**
- * Selects the row immediately following the last selected row.
- * @param {Boolean} keepExisting (optional) True to keep existing selections
+ * @cfg {String} displayMsg
+ * The paging status message to display (defaults to "Displaying {start} - {end} of {total}")
*/
- selectNext : function(keepExisting){
- if(this.last !== false && (this.last+1) < this.grid.dataSource.getCount()){
- this.selectRow(this.last+1, keepExisting);
- this.grid.getView().focusRow(this.last);
- }
- },
-
+ displayMsg : 'Displaying {0} - {1} of {2}',
/**
- * Selects the row that precedes the last selected row.
- * @param {Boolean} keepExisting (optional) True to keep existing selections
+ * @cfg {String} emptyMsg
+ * The message to display when no records are found (defaults to "No data to display")
*/
- selectPrevious : function(keepExisting){
- if(this.last){
- this.selectRow(this.last-1, keepExisting);
- this.grid.getView().focusRow(this.last);
- }
- },
-
+ emptyMsg : 'No data to display',
/**
- * Returns the selected records
- * @return {Array} Array of selected records
+ * Customizable piece of the default paging text (defaults to "Page")
+ * @type String
*/
- getSelections : function(){
- return [].concat(this.selections.items);
- },
-
+ beforePageText : "Page",
/**
- * Returns the first selected record.
- * @return {Record}
+ * Customizable piece of the default paging text (defaults to "of %0")
+ * @type String
*/
- getSelected : function(){
- return this.selections.itemAt(0);
- },
-
-
+ afterPageText : "of {0}",
/**
- * Clears all selections.
+ * Customizable piece of the default paging text (defaults to "First Page")
+ * @type String
*/
- clearSelections : function(fast){
- if(this.locked) return;
- if(fast !== true){
- var ds = this.grid.dataSource;
- var s = this.selections;
- s.each(function(r){
- this.deselectRow(ds.indexOfId(r.id));
- }, this);
- s.clear();
- }else{
- this.selections.clear();
+ firstText : "First Page",
+ /**
+ * Customizable piece of the default paging text (defaults to "Previous Page")
+ * @type String
+ */
+ prevText : "Previous Page",
+ /**
+ * Customizable piece of the default paging text (defaults to "Next Page")
+ * @type String
+ */
+ nextText : "Next Page",
+ /**
+ * Customizable piece of the default paging text (defaults to "Last Page")
+ * @type String
+ */
+ lastText : "Last Page",
+ /**
+ * Customizable piece of the default paging text (defaults to "Refresh")
+ * @type String
+ */
+ refreshText : "Refresh",
+
+ buttons : false,
+ // private
+ onRender : function(ct, position)
+ {
+ Roo.bootstrap.PagingToolbar.superclass.onRender.call(this, ct, position);
+ this.navgroup.parentId = this.id;
+ this.navgroup.onRender(this.el, null);
+ // add the buttons to the navgroup
+
+ if(this.displayInfo){
+ Roo.log(this.el.select('ul.navbar-nav',true).first());
+ this.el.select('ul.navbar-nav',true).first().createChild({cls:'x-paging-info'});
+ this.displayEl = this.el.select('.x-paging-info', true).first();
+// var navel = this.navgroup.addItem( { tagtype : 'span', html : '', cls : 'x-paging-info', preventDefault : true } );
+// this.displayEl = navel.el.select('span',true).first();
}
- this.last = false;
- },
+
+ var _this = this;
+
+ if(this.buttons){
+ Roo.each(_this.buttons, function(e){
+ Roo.factory(e).onRender(_this.el, null);
+ });
+ }
+
+ Roo.each(_this.toolbarItems, function(e) {
+ _this.navgroup.addItem(e);
+ });
+
+
+ this.first = this.navgroup.addItem({
+ tooltip: this.firstText,
+ cls: "prev",
+ icon : 'fa fa-backward',
+ disabled: true,
+ preventDefault: true,
+ listeners : { click : this.onClick.createDelegate(this, ["first"]) }
+ });
+
+ this.prev = this.navgroup.addItem({
+ tooltip: this.prevText,
+ cls: "prev",
+ icon : 'fa fa-step-backward',
+ disabled: true,
+ preventDefault: true,
+ listeners : { click : this.onClick.createDelegate(this, ["prev"]) }
+ });
+ //this.addSeparator();
+
+
+ var field = this.navgroup.addItem( {
+ tagtype : 'span',
+ cls : 'x-paging-position',
+
+ html : this.beforePageText +
+ '<input type="text" size="3" value="1" class="x-grid-page-number">' +
+ '<span class="x-paging-after">' + String.format(this.afterPageText, 1) + '</span>'
+ } ); //?? escaped?
+
+ this.field = field.el.select('input', true).first();
+ this.field.on("keydown", this.onPagingKeydown, this);
+ this.field.on("focus", function(){this.dom.select();});
+
+
+ this.afterTextEl = field.el.select('.x-paging-after',true).first();
+ //this.field.setHeight(18);
+ //this.addSeparator();
+ this.next = this.navgroup.addItem({
+ tooltip: this.nextText,
+ cls: "next",
+ html : ' <i class="fa fa-step-forward">',
+ disabled: true,
+ preventDefault: true,
+ listeners : { click : this.onClick.createDelegate(this, ["next"]) }
+ });
+ this.last = this.navgroup.addItem({
+ tooltip: this.lastText,
+ icon : 'fa fa-forward',
+ cls: "next",
+ disabled: true,
+ preventDefault: true,
+ listeners : { click : this.onClick.createDelegate(this, ["last"]) }
+ });
+ //this.addSeparator();
+ this.loading = this.navgroup.addItem({
+ tooltip: this.refreshText,
+ icon: 'fa fa-refresh',
+ preventDefault: true,
+ listeners : { click : this.onClick.createDelegate(this, ["refresh"]) }
+ });
+ },
- /**
- * Selects all rows.
- */
- selectAll : function(){
- if(this.locked) return;
- this.selections.clear();
- for(var i = 0, len = this.grid.dataSource.getCount(); i < len; i++){
- this.selectRow(i, true);
+ // private
+ updateInfo : function(){
+ if(this.displayEl){
+ var count = (typeof(this.getCount) == 'undefined') ? this.ds.getCount() : this.getCount();
+ var msg = count == 0 ?
+ this.emptyMsg :
+ String.format(
+ this.displayMsg,
+ this.cursor+1, this.cursor+count, this.ds.getTotalCount()
+ );
+ this.displayEl.update(msg);
}
},
- /**
- * Returns True if there is a selection.
- * @return {Boolean}
- */
- hasSelection : function(){
- return this.selections.length > 0;
+ // private
+ onLoad : function(ds, r, o){
+ this.cursor = o.params ? o.params.start : 0;
+ var d = this.getPageData(),
+ ap = d.activePage,
+ ps = d.pages;
+
+ this.afterTextEl.dom.innerHTML = String.format(this.afterPageText, d.pages);
+ this.field.dom.value = ap;
+ this.first.setDisabled(ap == 1);
+ this.prev.setDisabled(ap == 1);
+ this.next.setDisabled(ap == ps);
+ this.last.setDisabled(ap == ps);
+ this.loading.enable();
+ this.updateInfo();
},
- /**
- * 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.dataSource.getAt(index) : index;
- return (r && this.selections.key(r.id) ? true : false);
+ // private
+ getPageData : function(){
+ var total = this.ds.getTotalCount();
+ return {
+ total : total,
+ activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
+ pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
+ };
},
- /**
- * 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
+ onLoadError : function(){
+ this.loading.enable();
},
// private
- handleMouseDown : function(e, t){
- var view = this.grid.getView(), 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);
+ onPagingKeydown : function(e){
+ var k = e.getKey();
+ var d = this.getPageData();
+ if(k == e.RETURN){
+ var v = this.field.dom.value, pageNum;
+ if(!v || isNaN(pageNum = parseInt(v, 10))){
+ this.field.dom.value = d.activePage;
+ return;
}
+ pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
+ this.ds.load({params:{start: pageNum * this.pageSize, limit: this.pageSize}});
+ e.stopEvent();
}
- 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();
+ else if(k == e.HOME || (k == e.UP && e.ctrlKey) || (k == e.PAGEUP && e.ctrlKey) || (k == e.RIGHT && e.ctrlKey) || k == e.END || (k == e.DOWN && e.ctrlKey) || (k == e.LEFT && e.ctrlKey) || (k == e.PAGEDOWN && e.ctrlKey))
+ {
+ var pageNum = (k == e.HOME || (k == e.DOWN && e.ctrlKey) || (k == e.LEFT && e.ctrlKey) || (k == e.PAGEDOWN && e.ctrlKey)) ? 1 : d.pages;
+ this.field.dom.value = pageNum;
+ this.ds.load({params:{start: (pageNum - 1) * this.pageSize, limit: this.pageSize}});
+ e.stopEvent();
}
- for(var i = 0, len = rows.length; i < len; i++){
- this.selectRow(rows[i], true);
+ else if(k == e.UP || k == e.RIGHT || k == e.PAGEUP || k == e.DOWN || k == e.LEFT || k == e.PAGEDOWN)
+ {
+ var v = this.field.dom.value, pageNum;
+ var increment = (e.shiftKey) ? 10 : 1;
+ if(k == e.DOWN || k == e.LEFT || k == e.PAGEDOWN)
+ increment *= -1;
+ if(!v || isNaN(pageNum = parseInt(v, 10))) {
+ this.field.dom.value = d.activePage;
+ return;
+ }
+ else if(parseInt(v, 10) + increment >= 1 & parseInt(v, 10) + increment <= d.pages)
+ {
+ this.field.dom.value = parseInt(v, 10) + increment;
+ pageNum = Math.min(Math.max(1, pageNum + increment), d.pages) - 1;
+ this.ds.load({params:{start: pageNum * this.pageSize, limit: this.pageSize}});
+ }
+ e.stopEvent();
}
},
- /**
- * 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);
- }
+ // private
+ beforeLoad : function(){
+ if(this.loading){
+ this.loading.disable();
}
},
- /**
- * 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);
+ // private
+ onClick : function(which){
+
+ var ds = this.ds;
+ if (!ds) {
+ return;
}
- },
-
- /**
- * 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.dataSource.getCount())) return;
- if(this.fireEvent("beforerowselect", this, index, keepExisting) !== false){
- if(!keepExisting || this.singleSelect){
- this.clearSelections();
- }
- var r = this.grid.dataSource.getAt(index);
- this.selections.add(r);
- this.last = this.lastActive = index;
- if(!preventViewNotify){
- this.grid.getView().onRowSelect(index);
- }
- this.fireEvent("rowselect", this, index, r);
- this.fireEvent("selectionchange", this);
+
+ switch(which){
+ case "first":
+ ds.load({params:{start: 0, limit: this.pageSize}});
+ break;
+ case "prev":
+ ds.load({params:{start: Math.max(0, this.cursor-this.pageSize), limit: this.pageSize}});
+ break;
+ case "next":
+ ds.load({params:{start: this.cursor+this.pageSize, limit: this.pageSize}});
+ break;
+ case "last":
+ var total = ds.getTotalCount();
+ var extra = total % this.pageSize;
+ var lastStart = extra ? (total - extra) : total-this.pageSize;
+ ds.load({params:{start: lastStart, limit: this.pageSize}});
+ break;
+ case "refresh":
+ ds.load({params:{start: this.cursor, limit: this.pageSize}});
+ break;
}
},
/**
- * Deselects a row.
- * @param {Number} row The index of the row to deselect
+ * Unbinds the paging toolbar from the specified {@link Roo.data.Store}
+ * @param {Roo.data.Store} store The data store to unbind
*/
- 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.dataSource.getAt(index);
- this.selections.remove(r);
- if(!preventViewNotify){
- this.grid.getView().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);
+ unbind : function(ds){
+ ds.un("beforeload", this.beforeLoad, this);
+ ds.un("load", this.onLoad, this);
+ ds.un("loadexception", this.onLoadError, this);
+ ds.un("remove", this.updateInfo, this);
+ ds.un("add", this.updateInfo, this);
+ this.ds = undefined;
},
- // 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]);
- }
+ /**
+ * Binds the paging toolbar to the specified {@link Roo.data.Store}
+ * @param {Roo.data.Store} store The data store to bind
+ */
+ bind : function(ds){
+ ds.on("beforeload", this.beforeLoad, this);
+ ds.on("load", this.onLoad, this);
+ ds.on("loadexception", this.onLoadError, this);
+ ds.on("remove", this.updateInfo, this);
+ ds.on("add", this.updateInfo, this);
+ this.ds = ds;
}
});/*
- * 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.
+ * - LGPL
*
- * Fork - LGPL
- * <script type="text/javascript">
+ * element
+ *
*/
-
+
/**
- * @class Roo.bootstrap.PagingToolbar
- * @extends Roo.Row
- * A specialized toolbar that is bound to a {@link Roo.data.Store} and provides automatic paging controls.
+ * @class Roo.bootstrap.MessageBar
+ * @extends Roo.bootstrap.Component
+ * Bootstrap MessageBar class
+ * @cfg {String} html contents of the MessageBar
+ * @cfg {String} weight (info | success | warning | danger) default info
+ * @cfg {String} beforeClass insert the bar before the given class
+ * @cfg {Boolean} closable (true | false) default false
+ * @cfg {Boolean} fixed (true | false) default false, fix the bar at the top
+ *
* @constructor
- * Create a new PagingToolbar
+ * Create a new Element
* @param {Object} config The config object
*/
-Roo.bootstrap.PagingToolbar = function(config)
-{
- // old args format still supported... - xtype is prefered..
- // created from xtype...
- var ds = config.dataSource;
- this.toolbarItems = [];
- if (config.items) {
- this.toolbarItems = config.items;
-// config.items = [];
- }
-
- Roo.bootstrap.PagingToolbar.superclass.constructor.call(this, config);
- this.ds = ds;
- this.cursor = 0;
- if (ds) {
- this.bind(ds);
- }
-
- this.navgroup = new Roo.bootstrap.NavGroup({ cls: 'pagination' });
-
-};
-Roo.extend(Roo.bootstrap.PagingToolbar, Roo.bootstrap.NavSimplebar, {
- /**
- * @cfg {Roo.data.Store} dataSource
- * The underlying data store providing the paged data
- */
- /**
- * @cfg {String/HTMLElement/Element} container
- * container The id or element that will contain the toolbar
- */
- /**
- * @cfg {Boolean} displayInfo
- * True to display the displayMsg (defaults to false)
- */
- /**
- * @cfg {Number} pageSize
- * The number of records to display per page (defaults to 20)
- */
- pageSize: 20,
- /**
- * @cfg {String} displayMsg
- * The paging status message to display (defaults to "Displaying {start} - {end} of {total}")
- */
- displayMsg : 'Displaying {0} - {1} of {2}',
- /**
- * @cfg {String} emptyMsg
- * The message to display when no records are found (defaults to "No data to display")
- */
- emptyMsg : 'No data to display',
- /**
- * Customizable piece of the default paging text (defaults to "Page")
- * @type String
- */
- beforePageText : "Page",
- /**
- * Customizable piece of the default paging text (defaults to "of %0")
- * @type String
- */
- afterPageText : "of {0}",
- /**
- * Customizable piece of the default paging text (defaults to "First Page")
- * @type String
- */
- firstText : "First Page",
- /**
- * Customizable piece of the default paging text (defaults to "Previous Page")
- * @type String
- */
- prevText : "Previous Page",
- /**
- * Customizable piece of the default paging text (defaults to "Next Page")
- * @type String
- */
- nextText : "Next Page",
- /**
- * Customizable piece of the default paging text (defaults to "Last Page")
- * @type String
- */
- lastText : "Last Page",
- /**
- * Customizable piece of the default paging text (defaults to "Refresh")
- * @type String
- */
- refreshText : "Refresh",
+Roo.bootstrap.MessageBar = function(config){
+ Roo.bootstrap.MessageBar.superclass.constructor.call(this, config);
+};
- buttons : false,
- // private
- onRender : function(ct, position)
- {
- Roo.bootstrap.PagingToolbar.superclass.onRender.call(this, ct, position);
- this.navgroup.parentId = this.id;
- this.navgroup.onRender(this.el, null);
- // add the buttons to the navgroup
+Roo.extend(Roo.bootstrap.MessageBar, Roo.bootstrap.Component, {
+
+ html: '',
+ weight: 'info',
+ closable: false,
+ fixed: false,
+ beforeClass: 'bootstrap-sticky-wrap',
+
+ getAutoCreate : function(){
- if(this.displayInfo){
- Roo.log(this.el.select('ul.navbar-nav',true).first());
- this.el.select('ul.navbar-nav',true).first().createChild({cls:'x-paging-info'});
- this.displayEl = this.el.select('.x-paging-info', true).first();
-// var navel = this.navgroup.addItem( { tagtype : 'span', html : '', cls : 'x-paging-info', preventDefault : true } );
-// this.displayEl = navel.el.select('span',true).first();
+ var cfg = {
+ tag: 'div',
+ cls: 'alert alert-dismissable alert-' + this.weight,
+ cn: [
+ {
+ tag: 'span',
+ cls: 'message',
+ html: this.html || ''
+ }
+ ]
}
- var _this = this;
+ if(this.fixed){
+ cfg.cls += ' alert-messages-fixed';
+ }
- if(this.buttons){
- Roo.each(_this.buttons, function(e){
- Roo.factory(e).onRender(_this.el, null);
+ if(this.closable){
+ cfg.cn.push({
+ tag: 'button',
+ cls: 'close',
+ html: 'x'
});
}
+
+ return cfg;
+ },
+
+ onRender : function(ct, position)
+ {
+ Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
+
+ if(!this.el){
+ var cfg = Roo.apply({}, this.getAutoCreate());
+ cfg.id = Roo.id();
- Roo.each(_this.toolbarItems, function(e) {
- _this.navgroup.addItem(e);
- });
+ if (this.cls) {
+ cfg.cls += ' ' + this.cls;
+ }
+ if (this.style) {
+ cfg.style = this.style;
+ }
+ this.el = Roo.get(document.body).createChild(cfg, Roo.select('.'+this.beforeClass, true).first());
+
+ this.el.setVisibilityMode(Roo.Element.DISPLAY);
+ }
+ this.el.select('>button.close').on('click', this.hide, this);
- this.first = this.navgroup.addItem({
- tooltip: this.firstText,
- cls: "prev",
- icon : 'fa fa-backward',
- disabled: true,
- preventDefault: true,
- listeners : { click : this.onClick.createDelegate(this, ["first"]) }
- });
+ },
+
+ show : function()
+ {
+ if (!this.rendered) {
+ this.render();
+ }
- this.prev = this.navgroup.addItem({
- tooltip: this.prevText,
- cls: "prev",
- icon : 'fa fa-step-backward',
- disabled: true,
- preventDefault: true,
- listeners : { click : this.onClick.createDelegate(this, ["prev"]) }
- });
- //this.addSeparator();
+ this.el.show();
+
+ this.fireEvent('show', this);
+ },
+
+ hide : function()
+ {
+ if (!this.rendered) {
+ this.render();
+ }
- var field = this.navgroup.addItem( {
- tagtype : 'span',
- cls : 'x-paging-position',
-
- html : this.beforePageText +
- '<input type="text" size="3" value="1" class="x-grid-page-number">' +
- '<span class="x-paging-after">' + String.format(this.afterPageText, 1) + '</span>'
- } ); //?? escaped?
+ this.el.hide();
- this.field = field.el.select('input', true).first();
- this.field.on("keydown", this.onPagingKeydown, this);
- this.field.on("focus", function(){this.dom.select();});
+ this.fireEvent('hide', this);
+ },
+ update : function()
+ {
+// var e = this.el.dom.firstChild;
+//
+// if(this.closable){
+// e = e.nextSibling;
+// }
+//
+// e.data = this.html || '';
+
+ this.el.select('>.message', true).first().dom.innerHTML = this.html || '';
+ }
+
+});
+
+
+
+ /*
+ * - LGPL
+ *
+ * Graph
+ *
+ */
+
+
+/**
+ * @class Roo.bootstrap.Graph
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Graph class
+> Prameters
+ -sm {number} sm 4
+ -md {number} md 5
+ @cfg {String} graphtype bar | vbar | pie
+ @cfg {number} g_x coodinator | centre x (pie)
+ @cfg {number} g_y coodinator | centre y (pie)
+ @cfg {number} g_r radius (pie)
+ @cfg {number} g_height height of the chart (respected by all elements in the set)
+ @cfg {number} g_width width of the chart (respected by all elements in the set)
+ @cfg {Object} title The title of the chart
- this.afterTextEl = field.el.select('.x-paging-after',true).first();
- //this.field.setHeight(18);
- //this.addSeparator();
- this.next = this.navgroup.addItem({
- tooltip: this.nextText,
- cls: "next",
- html : ' <i class="fa fa-step-forward">',
- disabled: true,
- preventDefault: true,
- listeners : { click : this.onClick.createDelegate(this, ["next"]) }
- });
- this.last = this.navgroup.addItem({
- tooltip: this.lastText,
- icon : 'fa fa-forward',
- cls: "next",
- disabled: true,
- preventDefault: true,
- listeners : { click : this.onClick.createDelegate(this, ["last"]) }
- });
- //this.addSeparator();
- this.loading = this.navgroup.addItem({
- tooltip: this.refreshText,
- icon: 'fa fa-refresh',
- preventDefault: true,
- listeners : { click : this.onClick.createDelegate(this, ["refresh"]) }
- });
+ -{Array} values
+ -opts (object) options for the chart
+ o {
+ o type (string) type of endings of the bar. Default: 'square'. Other options are: 'round', 'sharp', 'soft'.
+ o gutter (number)(string) default '20%' (WHAT DOES IT DO?)
+ o vgutter (number)
+ o colors (array) colors be used repeatedly to plot the bars. If multicolumn bar is used each sequence of bars with use a different color.
+ o stacked (boolean) whether or not to tread values as in a stacked bar chart
+ o to
+ o stretch (boolean)
+ o }
+ -opts (object) options for the pie
+ o{
+ o cut
+ o startAngle (number)
+ o endAngle (number)
+ }
+ *
+ * @constructor
+ * Create a new Input
+ * @param {Object} config The config object
+ */
- },
+Roo.bootstrap.Graph = function(config){
+ Roo.bootstrap.Graph.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.Graph, Roo.bootstrap.Component, {
+
+ sm: 4,
+ md: 5,
+ graphtype: 'bar',
+ g_height: 250,
+ g_width: 400,
+ g_x: 50,
+ g_y: 50,
+ g_r: 30,
+ opts:{
+ //g_colors: this.colors,
+ g_type: 'soft',
+ g_gutter: '20%'
- // private
- updateInfo : function(){
- if(this.displayEl){
- var count = (typeof(this.getCount) == 'undefined') ? this.ds.getCount() : this.getCount();
- var msg = count == 0 ?
- this.emptyMsg :
- String.format(
- this.displayMsg,
- this.cursor+1, this.cursor+count, this.ds.getTotalCount()
- );
- this.displayEl.update(msg);
- }
},
+ title : false,
- // private
- onLoad : function(ds, r, o){
- this.cursor = o.params ? o.params.start : 0;
- var d = this.getPageData(),
- ap = d.activePage,
- ps = d.pages;
+ getAutoCreate : function(){
- this.afterTextEl.dom.innerHTML = String.format(this.afterPageText, d.pages);
- this.field.dom.value = ap;
- this.first.setDisabled(ap == 1);
- this.prev.setDisabled(ap == 1);
- this.next.setDisabled(ap == ps);
- this.last.setDisabled(ap == ps);
- this.loading.enable();
- this.updateInfo();
+ var cfg = {
+ tag: 'div',
+ html : null
+ }
+
+
+ return cfg;
},
- // private
- getPageData : function(){
- var total = this.ds.getTotalCount();
- return {
- total : total,
- activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
- pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
- };
- },
+ onRender : function(ct,position){
+ Roo.bootstrap.Graph.superclass.onRender.call(this,ct,position);
+ this.raphael = Raphael(this.el.dom);
+
+ // data1 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
+ // data2 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
+ // data3 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
+ // txtattr = { font: "12px 'Fontin Sans', Fontin-Sans, sans-serif" };
+ /*
+ r.text(160, 10, "Single Series Chart").attr(txtattr);
+ r.text(480, 10, "Multiline Series Chart").attr(txtattr);
+ r.text(160, 250, "Multiple Series Stacked Chart").attr(txtattr);
+ r.text(480, 250, 'Multiline Series Stacked Vertical Chart. Type "round"').attr(txtattr);
+
+ r.barchart(10, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10]], 0, {type: "sharp"});
+ r.barchart(330, 10, 300, 220, data1);
+ r.barchart(10, 250, 300, 220, data2, {stacked: true});
+ r.barchart(330, 250, 300, 220, data3, {stacked: true, type: "round"});
+ */
+
+ // var xdata = [55, 20, 13, 32, 5, 1, 2, 10,5 , 10];
+ // r.barchart(30, 30, 560, 250, xdata, {
+ // labels : [55, 20, 13, 32, 5, 1, 2, 10,5 , 10],
+ // axis : "0 0 1 1",
+ // axisxlabels : xdata
+ // //yvalues : cols,
+
+ // });
+// var xdata = [55, 20, 13, 32, 5, 1, 2, 10,5 , 10];
+//
+// this.load(null,xdata,{
+// axis : "0 0 1 1",
+// axisxlabels : xdata
+// });
- // private
- onLoadError : function(){
- this.loading.enable();
},
- // private
- onPagingKeydown : function(e){
- var k = e.getKey();
- var d = this.getPageData();
- if(k == e.RETURN){
- var v = this.field.dom.value, pageNum;
- if(!v || isNaN(pageNum = parseInt(v, 10))){
- this.field.dom.value = d.activePage;
- return;
- }
- pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
- this.ds.load({params:{start: pageNum * this.pageSize, limit: this.pageSize}});
- e.stopEvent();
- }
- else if(k == e.HOME || (k == e.UP && e.ctrlKey) || (k == e.PAGEUP && e.ctrlKey) || (k == e.RIGHT && e.ctrlKey) || k == e.END || (k == e.DOWN && e.ctrlKey) || (k == e.LEFT && e.ctrlKey) || (k == e.PAGEDOWN && e.ctrlKey))
- {
- var pageNum = (k == e.HOME || (k == e.DOWN && e.ctrlKey) || (k == e.LEFT && e.ctrlKey) || (k == e.PAGEDOWN && e.ctrlKey)) ? 1 : d.pages;
- this.field.dom.value = pageNum;
- this.ds.load({params:{start: (pageNum - 1) * this.pageSize, limit: this.pageSize}});
- e.stopEvent();
- }
- else if(k == e.UP || k == e.RIGHT || k == e.PAGEUP || k == e.DOWN || k == e.LEFT || k == e.PAGEDOWN)
- {
- var v = this.field.dom.value, pageNum;
- var increment = (e.shiftKey) ? 10 : 1;
- if(k == e.DOWN || k == e.LEFT || k == e.PAGEDOWN)
- increment *= -1;
- if(!v || isNaN(pageNum = parseInt(v, 10))) {
- this.field.dom.value = d.activePage;
- return;
- }
- else if(parseInt(v, 10) + increment >= 1 & parseInt(v, 10) + increment <= d.pages)
- {
- this.field.dom.value = parseInt(v, 10) + increment;
- pageNum = Math.min(Math.max(1, pageNum + increment), d.pages) - 1;
- this.ds.load({params:{start: pageNum * this.pageSize, limit: this.pageSize}});
- }
- e.stopEvent();
+ load : function(graphtype,xdata,opts){
+ this.raphael.clear();
+ if(!graphtype) {
+ graphtype = this.graphtype;
}
- },
-
- // private
- beforeLoad : function(){
- if(this.loading){
- this.loading.disable();
+ if(!opts){
+ opts = this.opts;
}
- },
+ var r = this.raphael,
+ fin = function () {
+ this.flag = r.popup(this.bar.x, this.bar.y, this.bar.value || "0").insertBefore(this);
+ },
+ fout = function () {
+ this.flag.animate({opacity: 0}, 300, function () {this.remove();});
+ },
+ pfin = function() {
+ this.sector.stop();
+ this.sector.scale(1.1, 1.1, this.cx, this.cy);
+
+ if (this.label) {
+ this.label[0].stop();
+ this.label[0].attr({ r: 7.5 });
+ this.label[1].attr({ "font-weight": 800 });
+ }
+ },
+ pfout = function() {
+ this.sector.animate({ transform: 's1 1 ' + this.cx + ' ' + this.cy }, 500, "bounce");
+
+ if (this.label) {
+ this.label[0].animate({ r: 5 }, 500, "bounce");
+ this.label[1].attr({ "font-weight": 400 });
+ }
+ };
+
+ switch(graphtype){
+ case 'bar':
+ this.raphael.barchart(this.g_x,this.g_y,this.g_width,this.g_height,xdata,opts).hover(fin,fout);
+ break;
+ case 'hbar':
+ this.raphael.hbarchart(this.g_x,this.g_y,this.g_width,this.g_height,xdata,opts).hover(fin,fout);
+ break;
+ case 'pie':
+// opts = { legend: ["%% - Enterprise Users", "% - ddd","Chrome Users"], legendpos: "west",
+// href: ["http://raphaeljs.com", "http://g.raphaeljs.com"]};
+//
+ this.raphael.piechart(this.g_x,this.g_y,this.g_r,xdata,opts).hover(pfin, pfout);
+
+ break;
- // private
- onClick : function(which){
-
- var ds = this.ds;
- if (!ds) {
- return;
}
- switch(which){
- case "first":
- ds.load({params:{start: 0, limit: this.pageSize}});
- break;
- case "prev":
- ds.load({params:{start: Math.max(0, this.cursor-this.pageSize), limit: this.pageSize}});
- break;
- case "next":
- ds.load({params:{start: this.cursor+this.pageSize, limit: this.pageSize}});
- break;
- case "last":
- var total = ds.getTotalCount();
- var extra = total % this.pageSize;
- var lastStart = extra ? (total - extra) : total-this.pageSize;
- ds.load({params:{start: lastStart, limit: this.pageSize}});
- break;
- case "refresh":
- ds.load({params:{start: this.cursor, limit: this.pageSize}});
- break;
+ if(this.title){
+ this.raphael.text(this.title.x, this.title.y, this.title.text).attr(this.title.attr);
}
+
},
-
- /**
- * Unbinds the paging toolbar from the specified {@link Roo.data.Store}
- * @param {Roo.data.Store} store The data store to unbind
- */
- unbind : function(ds){
- ds.un("beforeload", this.beforeLoad, this);
- ds.un("load", this.onLoad, this);
- ds.un("loadexception", this.onLoadError, this);
- ds.un("remove", this.updateInfo, this);
- ds.un("add", this.updateInfo, this);
- this.ds = undefined;
+
+ setTitle: function(o)
+ {
+ this.title = o;
},
-
- /**
- * Binds the paging toolbar to the specified {@link Roo.data.Store}
- * @param {Roo.data.Store} store The data store to bind
- */
- bind : function(ds){
- ds.on("beforeload", this.beforeLoad, this);
- ds.on("load", this.onLoad, this);
- ds.on("loadexception", this.onLoadError, this);
- ds.on("remove", this.updateInfo, this);
- ds.on("add", this.updateInfo, this);
- this.ds = ds;
+
+ initEvents: function() {
+
+ if(!this.href){
+ this.el.on('click', this.onClick, this);
+ }
+ },
+
+ onClick : function(e)
+ {
+ Roo.log('img onclick');
+ this.fireEvent('click', this, e);
}
-});/*
+
+});
+
+
+/*
* - LGPL
*
- * element
+ * numberBox
*
*/
+Roo.bootstrap.dash = Roo.bootstrap.dash || {};
/**
- * @class Roo.bootstrap.MessageBar
+ * @class Roo.bootstrap.dash.NumberBox
* @extends Roo.bootstrap.Component
- * Bootstrap MessageBar class
- * @cfg {String} html contents of the MessageBar
- * @cfg {String} weight (info | success | warning | danger) default info
- * @cfg {String} beforeClass insert the bar before the given class
- * @cfg {Boolean} closable (true | false) default false
- * @cfg {Boolean} fixed (true | false) default false, fix the bar at the top
+ * Bootstrap NumberBox class
+ * @cfg {String} headline Box headline
+ * @cfg {String} content Box content
+ * @cfg {String} icon Box icon
+ * @cfg {String} footer Footer text
+ * @cfg {String} fhref Footer href
*
* @constructor
- * Create a new Element
+ * Create a new NumberBox
* @param {Object} config The config object
*/
-Roo.bootstrap.MessageBar = function(config){
- Roo.bootstrap.MessageBar.superclass.constructor.call(this, config);
+
+Roo.bootstrap.dash.NumberBox = function(config){
+ Roo.bootstrap.dash.NumberBox.superclass.constructor.call(this, config);
+
};
-Roo.extend(Roo.bootstrap.MessageBar, Roo.bootstrap.Component, {
+Roo.extend(Roo.bootstrap.dash.NumberBox, Roo.bootstrap.Component, {
- html: '',
- weight: 'info',
- closable: false,
- fixed: false,
- beforeClass: 'bootstrap-sticky-wrap',
+ headline : '',
+ content : '',
+ icon : '',
+ footer : '',
+ fhref : '',
+ ficon : '',
getAutoCreate : function(){
var cfg = {
- tag: 'div',
- cls: 'alert alert-dismissable alert-' + this.weight,
- cn: [
+ tag : 'div',
+ cls : 'small-box ',
+ cn : [
{
- tag: 'span',
- cls: 'message',
- html: this.html || ''
+ tag : 'div',
+ cls : 'inner',
+ cn :[
+ {
+ tag : 'h3',
+ cls : 'roo-headline',
+ html : this.headline
+ },
+ {
+ tag : 'p',
+ cls : 'roo-content',
+ html : this.content
+ }
+ ]
}
]
}
- if(this.fixed){
- cfg.cls += ' alert-messages-fixed';
- }
-
- if(this.closable){
+ if(this.icon){
cfg.cn.push({
- tag: 'button',
- cls: 'close',
- html: 'x'
+ tag : 'div',
+ cls : 'icon',
+ cn :[
+ {
+ tag : 'i',
+ cls : 'ion ' + this.icon
+ }
+ ]
});
}
- return cfg;
- },
-
- onRender : function(ct, position)
- {
- Roo.bootstrap.Component.superclass.onRender.call(this, ct, position);
-
- if(!this.el){
- var cfg = Roo.apply({}, this.getAutoCreate());
- cfg.id = Roo.id();
+ if(this.footer){
+ var footer = {
+ tag : 'a',
+ cls : 'small-box-footer',
+ href : this.fhref || '#',
+ html : this.footer
+ };
- if (this.cls) {
- cfg.cls += ' ' + this.cls;
- }
- if (this.style) {
- cfg.style = this.style;
- }
- this.el = Roo.get(document.body).createChild(cfg, Roo.select('.'+this.beforeClass, true).first());
+ cfg.cn.push(footer);
- this.el.setVisibilityMode(Roo.Element.DISPLAY);
}
- this.el.select('>button.close').on('click', this.hide, this);
-
+ return cfg;
},
-
- show : function()
+
+ onRender : function(ct,position){
+ Roo.bootstrap.dash.NumberBox.superclass.onRender.call(this,ct,position);
+
+
+
+
+ },
+
+ setHeadline: function (value)
{
- if (!this.rendered) {
- this.render();
- }
-
- this.el.show();
-
- this.fireEvent('show', this);
-
+ this.el.select('.roo-headline',true).first().dom.innerHTML = value;
},
- hide : function()
+ setFooter: function (value, href)
{
- if (!this.rendered) {
- this.render();
- }
+ this.el.select('a.small-box-footer',true).first().dom.innerHTML = value;
- this.el.hide();
+ if(href){
+ this.el.select('a.small-box-footer',true).first().attr('href', href);
+ }
- this.fireEvent('hide', this);
},
-
- update : function()
+
+ setContent: function (value)
{
-// var e = this.el.dom.firstChild;
-//
-// if(this.closable){
-// e = e.nextSibling;
-// }
-//
-// e.data = this.html || '';
+ this.el.select('.roo-content',true).first().dom.innerHTML = value;
+ },
- this.el.select('>.message', true).first().dom.innerHTML = this.html || '';
+ initEvents: function()
+ {
+
}
-
+
});
-
- /*
+/*
* - LGPL
*
- * Graph
+ * TabBox
*
*/
-
+Roo.bootstrap.dash = Roo.bootstrap.dash || {};
/**
- * @class Roo.bootstrap.Graph
+ * @class Roo.bootstrap.dash.TabBox
* @extends Roo.bootstrap.Component
- * Bootstrap Graph class
-> Prameters
- -sm {number} sm 4
- -md {number} md 5
- @cfg {String} graphtype bar | vbar | pie
- @cfg {number} g_x coodinator | centre x (pie)
- @cfg {number} g_y coodinator | centre y (pie)
- @cfg {number} g_r radius (pie)
- @cfg {number} g_height height of the chart (respected by all elements in the set)
- @cfg {number} g_width width of the chart (respected by all elements in the set)
- @cfg {Object} title The title of the chart
-
- -{Array} values
- -opts (object) options for the chart
- o {
- o type (string) type of endings of the bar. Default: 'square'. Other options are: 'round', 'sharp', 'soft'.
- o gutter (number)(string) default '20%' (WHAT DOES IT DO?)
- o vgutter (number)
- o colors (array) colors be used repeatedly to plot the bars. If multicolumn bar is used each sequence of bars with use a different color.
- o stacked (boolean) whether or not to tread values as in a stacked bar chart
- o to
- o stretch (boolean)
- o }
- -opts (object) options for the pie
- o{
- o cut
- o startAngle (number)
- o endAngle (number)
- }
- *
+ * Bootstrap TabBox class
+ * @cfg {String} title Title of the TabBox
+ * @cfg {String} icon Icon of the TabBox
+ * @cfg {Boolean} showtabs (true|false) show the tabs default true
+ * @cfg {Boolean} tabScrollable (true|false) tab scrollable when mobile view default false
+ *
* @constructor
- * Create a new Input
+ * Create a new TabBox
* @param {Object} config The config object
*/
-Roo.bootstrap.Graph = function(config){
- Roo.bootstrap.Graph.superclass.constructor.call(this, config);
-
+
+Roo.bootstrap.dash.TabBox = function(config){
+ Roo.bootstrap.dash.TabBox.superclass.constructor.call(this, config);
this.addEvents({
- // img events
+ // raw events
/**
- * @event click
- * The img click event for the img.
- * @param {Roo.EventObject} e
+ * @event addpane
+ * When a pane is added
+ * @param {Roo.bootstrap.dash.TabPane} pane
*/
- "click" : true
+ "addpane" : true,
+ /**
+ * @event activatepane
+ * When a pane is activated
+ * @param {Roo.bootstrap.dash.TabPane} pane
+ */
+ "activatepane" : true
+
+
});
+
+ this.panes = [];
};
-Roo.extend(Roo.bootstrap.Graph, Roo.bootstrap.Component, {
-
- sm: 4,
- md: 5,
- graphtype: 'bar',
- g_height: 250,
- g_width: 400,
- g_x: 50,
- g_y: 50,
- g_r: 30,
- opts:{
- //g_colors: this.colors,
- g_type: 'soft',
- g_gutter: '20%'
+Roo.extend(Roo.bootstrap.dash.TabBox, Roo.bootstrap.Component, {
+ title : '',
+ icon : false,
+ showtabs : true,
+ tabScrollable : false,
+
+ getChildContainer : function()
+ {
+ return this.el.select('.tab-content', true).first();
},
- title : false,
-
+
getAutoCreate : function(){
- var cfg = {
- tag: 'div',
- html : null
- }
+ var header = {
+ tag: 'li',
+ cls: 'pull-left header',
+ html: this.title,
+ cn : []
+ };
+ if(this.icon){
+ header.cn.push({
+ tag: 'i',
+ cls: 'fa ' + this.icon
+ });
+ }
- return cfg;
- },
-
- onRender : function(ct,position){
- Roo.bootstrap.Graph.superclass.onRender.call(this,ct,position);
- this.raphael = Raphael(this.el.dom);
+ var h = {
+ tag: 'ul',
+ cls: 'nav nav-tabs pull-right',
+ cn: [
+ header
+ ]
+ };
- // data1 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
- // data2 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
- // data3 = [[55, 20, 13, 32, 5, 1, 2, 10], [10, 2, 1, 5, 32, 13, 20, 55], [12, 20, 30]],
- // txtattr = { font: "12px 'Fontin Sans', Fontin-Sans, sans-serif" };
- /*
- r.text(160, 10, "Single Series Chart").attr(txtattr);
- r.text(480, 10, "Multiline Series Chart").attr(txtattr);
- r.text(160, 250, "Multiple Series Stacked Chart").attr(txtattr);
- r.text(480, 250, 'Multiline Series Stacked Vertical Chart. Type "round"').attr(txtattr);
-
- r.barchart(10, 10, 300, 220, [[55, 20, 13, 32, 5, 1, 2, 10]], 0, {type: "sharp"});
- r.barchart(330, 10, 300, 220, data1);
- r.barchart(10, 250, 300, 220, data2, {stacked: true});
- r.barchart(330, 250, 300, 220, data3, {stacked: true, type: "round"});
- */
-
- // var xdata = [55, 20, 13, 32, 5, 1, 2, 10,5 , 10];
- // r.barchart(30, 30, 560, 250, xdata, {
- // labels : [55, 20, 13, 32, 5, 1, 2, 10,5 , 10],
- // axis : "0 0 1 1",
- // axisxlabels : xdata
- // //yvalues : cols,
-
- // });
-// var xdata = [55, 20, 13, 32, 5, 1, 2, 10,5 , 10];
-//
-// this.load(null,xdata,{
-// axis : "0 0 1 1",
-// axisxlabels : xdata
-// });
-
- },
-
- load : function(graphtype,xdata,opts){
- this.raphael.clear();
- if(!graphtype) {
- graphtype = this.graphtype;
- }
- if(!opts){
- opts = this.opts;
+ if(this.tabScrollable){
+ h = {
+ tag: 'div',
+ cls: 'tab-header',
+ cn: [
+ {
+ tag: 'ul',
+ cls: 'nav nav-tabs pull-right',
+ cn: [
+ header
+ ]
+ }
+ ]
+ }
+ }
+
+ var cfg = {
+ tag: 'div',
+ cls: 'nav-tabs-custom',
+ cn: [
+ h,
+ {
+ tag: 'div',
+ cls: 'tab-content no-padding',
+ cn: []
+ }
+ ]
}
- var r = this.raphael,
- fin = function () {
- this.flag = r.popup(this.bar.x, this.bar.y, this.bar.value || "0").insertBefore(this);
- },
- fout = function () {
- this.flag.animate({opacity: 0}, 300, function () {this.remove();});
- },
- pfin = function() {
- this.sector.stop();
- this.sector.scale(1.1, 1.1, this.cx, this.cy);
-
- if (this.label) {
- this.label[0].stop();
- this.label[0].attr({ r: 7.5 });
- this.label[1].attr({ "font-weight": 800 });
- }
- },
- pfout = function() {
- this.sector.animate({ transform: 's1 1 ' + this.cx + ' ' + this.cy }, 500, "bounce");
-
- if (this.label) {
- this.label[0].animate({ r: 5 }, 500, "bounce");
- this.label[1].attr({ "font-weight": 400 });
- }
- };
-
- switch(graphtype){
- case 'bar':
- this.raphael.barchart(this.g_x,this.g_y,this.g_width,this.g_height,xdata,opts).hover(fin,fout);
- break;
- case 'hbar':
- this.raphael.hbarchart(this.g_x,this.g_y,this.g_width,this.g_height,xdata,opts).hover(fin,fout);
- break;
- case 'pie':
-// opts = { legend: ["%% - Enterprise Users", "% - ddd","Chrome Users"], legendpos: "west",
-// href: ["http://raphaeljs.com", "http://g.raphaeljs.com"]};
-//
- this.raphael.piechart(this.g_x,this.g_y,this.g_r,xdata,opts).hover(pfin, pfout);
-
- break;
+ return cfg;
+ },
+ initEvents : function()
+ {
+ //Roo.log('add add pane handler');
+ this.on('addpane', this.onAddPane, this);
+ },
+ /**
+ * Updates the box title
+ * @param {String} html to set the title to.
+ */
+ setTitle : function(value)
+ {
+ this.el.select('.nav-tabs .header', true).first().dom.innerHTML = value;
+ },
+ onAddPane : function(pane)
+ {
+ this.panes.push(pane);
+ //Roo.log('addpane');
+ //Roo.log(pane);
+ // tabs are rendere left to right..
+ if(!this.showtabs){
+ return;
}
- if(this.title){
- this.raphael.text(this.title.x, this.title.y, this.title.text).attr(this.title.attr);
+ var ctr = this.el.select('.nav-tabs', true).first();
+
+
+ var existing = ctr.select('.nav-tab',true);
+ var qty = existing.getCount();;
+
+
+ var tab = ctr.createChild({
+ tag : 'li',
+ cls : 'nav-tab' + (qty ? '' : ' active'),
+ cn : [
+ {
+ tag : 'a',
+ href:'#',
+ html : pane.title
+ }
+ ]
+ }, qty ? existing.first().dom : ctr.select('.header', true).first().dom );
+ pane.tab = tab;
+
+ tab.on('click', this.onTabClick.createDelegate(this, [pane], true));
+ if (!qty) {
+ pane.el.addClass('active');
}
+
},
-
- setTitle: function(o)
+ onTabClick : function(ev,un,ob,pane)
{
- this.title = o;
- },
-
- initEvents: function() {
+ //Roo.log('tab - prev default');
+ ev.preventDefault();
+
+
+ this.el.select('.nav-tabs li.nav-tab', true).removeClass('active');
+ pane.tab.addClass('active');
+ //Roo.log(pane.title);
+ this.getChildContainer().select('.tab-pane',true).removeClass('active');
+ // technically we should have a deactivate event.. but maybe add later.
+ // and it should not de-activate the selected tab...
+ this.fireEvent('activatepane', pane);
+ pane.el.addClass('active');
+ pane.fireEvent('activate');
+
- if(!this.href){
- this.el.on('click', this.onClick, this);
- }
},
- onClick : function(e)
+ getActivePane : function()
{
- Roo.log('img onclick');
- this.fireEvent('click', this, e);
+ var r = false;
+ Roo.each(this.panes, function(p) {
+ if(p.el.hasClass('active')){
+ r = p;
+ return false;
+ }
+
+ return;
+ });
+
+ return r;
}
-
+
+
});
/*
* - LGPL
*
- * numberBox
+ * Tab pane
*
*/
Roo.bootstrap.dash = Roo.bootstrap.dash || {};
-
/**
- * @class Roo.bootstrap.dash.NumberBox
+ * @class Roo.bootstrap.TabPane
* @extends Roo.bootstrap.Component
- * Bootstrap NumberBox class
- * @cfg {String} headline Box headline
- * @cfg {String} content Box content
- * @cfg {String} icon Box icon
- * @cfg {String} footer Footer text
- * @cfg {String} fhref Footer href
+ * Bootstrap TabPane class
+ * @cfg {Boolean} active (false | true) Default false
+ * @cfg {String} title title of panel
+
*
* @constructor
- * Create a new NumberBox
+ * Create a new TabPane
* @param {Object} config The config object
*/
-
-Roo.bootstrap.dash.NumberBox = function(config){
- Roo.bootstrap.dash.NumberBox.superclass.constructor.call(this, config);
+Roo.bootstrap.dash.TabPane = function(config){
+ Roo.bootstrap.dash.TabPane.superclass.constructor.call(this, config);
+ this.addEvents({
+ // raw events
+ /**
+ * @event activate
+ * When a pane is activated
+ * @param {Roo.bootstrap.dash.TabPane} pane
+ */
+ "activate" : true
+
+ });
};
-Roo.extend(Roo.bootstrap.dash.NumberBox, Roo.bootstrap.Component, {
+Roo.extend(Roo.bootstrap.dash.TabPane, Roo.bootstrap.Component, {
- headline : '',
- content : '',
- icon : '',
- footer : '',
- fhref : '',
- ficon : '',
+ active : false,
+ title : '',
- getAutoCreate : function(){
-
+ // the tabBox that this is attached to.
+ tab : false,
+
+ getAutoCreate : function()
+ {
var cfg = {
- tag : 'div',
- cls : 'small-box ',
- cn : [
- {
- tag : 'div',
- cls : 'inner',
- cn :[
- {
- tag : 'h3',
- cls : 'roo-headline',
- html : this.headline
- },
- {
- tag : 'p',
- cls : 'roo-content',
- html : this.content
- }
- ]
- }
- ]
- }
-
- if(this.icon){
- cfg.cn.push({
- tag : 'div',
- cls : 'icon',
- cn :[
- {
- tag : 'i',
- cls : 'ion ' + this.icon
- }
- ]
- });
+ tag: 'div',
+ cls: 'tab-pane'
}
- if(this.footer){
- var footer = {
- tag : 'a',
- cls : 'small-box-footer',
- href : this.fhref || '#',
- html : this.footer
- };
-
- cfg.cn.push(footer);
-
+ if(this.active){
+ cfg.cls += ' active';
}
- return cfg;
- },
-
- onRender : function(ct,position){
- Roo.bootstrap.dash.NumberBox.superclass.onRender.call(this,ct,position);
-
-
-
-
+ return cfg;
},
-
- setHeadline: function (value)
+ initEvents : function()
{
- this.el.select('.roo-headline',true).first().dom.innerHTML = value;
+ //Roo.log('trigger add pane handler');
+ this.parent().fireEvent('addpane', this)
},
- setFooter: function (value, href)
+ /**
+ * Updates the tab title
+ * @param {String} html to set the title to.
+ */
+ setTitle: function(str)
{
- this.el.select('a.small-box-footer',true).first().dom.innerHTML = value;
-
- if(href){
- this.el.select('a.small-box-footer',true).first().attr('href', href);
+ if (!this.tab) {
+ return;
}
-
- },
-
- setContent: function (value)
- {
- this.el.select('.roo-content',true).first().dom.innerHTML = value;
- },
-
- initEvents: function()
- {
+ this.title = str;
+ this.tab.select('a', true).first().dom.innerHTML = str;
}
+
+
});
-/*
+
+
+ /*
* - LGPL
*
- * TabBox
+ * menu
*
*/
-Roo.bootstrap.dash = Roo.bootstrap.dash || {};
+Roo.bootstrap.menu = Roo.bootstrap.menu || {};
/**
- * @class Roo.bootstrap.dash.TabBox
+ * @class Roo.bootstrap.menu.Menu
* @extends Roo.bootstrap.Component
- * Bootstrap TabBox class
- * @cfg {String} title Title of the TabBox
- * @cfg {String} icon Icon of the TabBox
- * @cfg {Boolean} showtabs (true|false) show the tabs default true
- * @cfg {Boolean} tabScrollable (true|false) tab scrollable when mobile view default false
+ * Bootstrap Menu class - container for Menu
+ * @cfg {String} html Text of the menu
+ * @cfg {String} weight (default | primary | success | info | warning | danger | inverse)
+ * @cfg {String} icon Font awesome icon
+ * @cfg {String} pos Menu align to (top | bottom) default bottom
+ *
*
* @constructor
- * Create a new TabBox
+ * Create a new Menu
* @param {Object} config The config object
*/
-Roo.bootstrap.dash.TabBox = function(config){
- Roo.bootstrap.dash.TabBox.superclass.constructor.call(this, config);
+Roo.bootstrap.menu.Menu = function(config){
+ Roo.bootstrap.menu.Menu.superclass.constructor.call(this, config);
+
this.addEvents({
- // raw events
/**
- * @event addpane
- * When a pane is added
- * @param {Roo.bootstrap.dash.TabPane} pane
+ * @event beforeshow
+ * Fires before this menu is displayed
+ * @param {Roo.bootstrap.menu.Menu} this
*/
- "addpane" : true,
+ beforeshow : true,
/**
- * @event activatepane
- * When a pane is activated
- * @param {Roo.bootstrap.dash.TabPane} pane
+ * @event beforehide
+ * Fires before this menu is hidden
+ * @param {Roo.bootstrap.menu.Menu} this
*/
- "activatepane" : true
-
-
+ beforehide : true,
+ /**
+ * @event show
+ * Fires after this menu is displayed
+ * @param {Roo.bootstrap.menu.Menu} this
+ */
+ show : true,
+ /**
+ * @event hide
+ * Fires after this menu is hidden
+ * @param {Roo.bootstrap.menu.Menu} this
+ */
+ hide : true,
+ /**
+ * @event click
+ * Fires when this menu is clicked (or when the enter key is pressed while it is active)
+ * @param {Roo.bootstrap.menu.Menu} this
+ * @param {Roo.EventObject} e
+ */
+ click : true
});
- this.panes = [];
};
-Roo.extend(Roo.bootstrap.dash.TabBox, Roo.bootstrap.Component, {
-
- title : '',
+Roo.extend(Roo.bootstrap.menu.Menu, Roo.bootstrap.Component, {
+
+ submenu : false,
+ html : '',
+ weight : 'default',
icon : false,
- showtabs : true,
- tabScrollable : false,
+ pos : 'bottom',
- getChildContainer : function()
- {
- return this.el.select('.tab-content', true).first();
- },
- getAutoCreate : function(){
+ getChildContainer : function() {
+ if(this.isSubMenu){
+ return this.el;
+ }
- var header = {
- tag: 'li',
- cls: 'pull-left header',
- html: this.title,
- cn : []
- };
+ return this.el.select('ul.dropdown-menu', true).first();
+ },
+
+ getAutoCreate : function()
+ {
+ var text = [
+ {
+ tag : 'span',
+ cls : 'roo-menu-text',
+ html : this.html
+ }
+ ];
if(this.icon){
- header.cn.push({
- tag: 'i',
- cls: 'fa ' + this.icon
- });
+ text.unshift({
+ tag : 'i',
+ cls : 'fa ' + this.icon
+ })
}
- var h = {
- tag: 'ul',
- cls: 'nav nav-tabs pull-right',
- cn: [
- header
- ]
- };
-
- if(this.tabScrollable){
- h = {
- tag: 'div',
- cls: 'tab-header',
- cn: [
- {
- tag: 'ul',
- cls: 'nav nav-tabs pull-right',
- cn: [
- header
- ]
- }
- ]
- }
- }
var cfg = {
- tag: 'div',
- cls: 'nav-tabs-custom',
- cn: [
- h,
+ tag : 'div',
+ cls : 'btn-group',
+ cn : [
{
- tag: 'div',
- cls: 'tab-content no-padding',
- cn: []
+ tag : 'button',
+ cls : 'dropdown-button btn btn-' + this.weight,
+ cn : text
+ },
+ {
+ tag : 'button',
+ cls : 'dropdown-toggle btn btn-' + this.weight,
+ cn : [
+ {
+ tag : 'span',
+ cls : 'caret'
+ }
+ ]
+ },
+ {
+ tag : 'ul',
+ cls : 'dropdown-menu'
}
]
+
+ };
+
+ if(this.pos == 'top'){
+ cfg.cls += ' dropup';
}
-
- return cfg;
- },
- initEvents : function()
- {
- //Roo.log('add add pane handler');
- this.on('addpane', this.onAddPane, this);
+
+ if(this.isSubMenu){
+ cfg = {
+ tag : 'ul',
+ cls : 'dropdown-menu'
+ }
+ }
+
+ return cfg;
},
- /**
- * Updates the box title
- * @param {String} html to set the title to.
- */
- setTitle : function(value)
+
+ onRender : function(ct, position)
{
- this.el.select('.nav-tabs .header', true).first().dom.innerHTML = value;
+ this.isSubMenu = ct.hasClass('dropdown-submenu');
+
+ Roo.bootstrap.menu.Menu.superclass.onRender.call(this, ct, position);
},
- onAddPane : function(pane)
+
+ initEvents : function()
{
- this.panes.push(pane);
- //Roo.log('addpane');
- //Roo.log(pane);
- // tabs are rendere left to right..
- if(!this.showtabs){
+ if(this.isSubMenu){
return;
}
- var ctr = this.el.select('.nav-tabs', true).first();
-
-
- var existing = ctr.select('.nav-tab',true);
- var qty = existing.getCount();;
+ this.hidden = true;
+ this.triggerEl = this.el.select('button.dropdown-toggle', true).first();
+ this.triggerEl.on('click', this.onTriggerPress, this);
- var tab = ctr.createChild({
- tag : 'li',
- cls : 'nav-tab' + (qty ? '' : ' active'),
- cn : [
- {
- tag : 'a',
- href:'#',
- html : pane.title
- }
- ]
- }, qty ? existing.first().dom : ctr.select('.header', true).first().dom );
- pane.tab = tab;
+ this.buttonEl = this.el.select('button.dropdown-button', true).first();
+ this.buttonEl.on('click', this.onClick, this);
- tab.on('click', this.onTabClick.createDelegate(this, [pane], true));
- if (!qty) {
- pane.el.addClass('active');
+ },
+
+ list : function()
+ {
+ if(this.isSubMenu){
+ return this.el;
}
-
+ return this.el.select('ul.dropdown-menu', true).first();
},
- onTabClick : function(ev,un,ob,pane)
+
+ onClick : function(e)
{
- //Roo.log('tab - prev default');
- ev.preventDefault();
+ this.fireEvent("click", this, e);
+ },
+
+ onTriggerPress : function(e)
+ {
+ if (this.isVisible()) {
+ this.hide();
+ } else {
+ this.show();
+ }
+ },
+
+ isVisible : function(){
+ return !this.hidden;
+ },
+
+ show : function()
+ {
+ this.fireEvent("beforeshow", this);
+
+ this.hidden = false;
+ this.el.addClass('open');
+ Roo.get(document).on("mouseup", this.onMouseUp, this);
- this.el.select('.nav-tabs li.nav-tab', true).removeClass('active');
- pane.tab.addClass('active');
- //Roo.log(pane.title);
- this.getChildContainer().select('.tab-pane',true).removeClass('active');
- // technically we should have a deactivate event.. but maybe add later.
- // and it should not de-activate the selected tab...
- this.fireEvent('activatepane', pane);
- pane.el.addClass('active');
- pane.fireEvent('activate');
+ this.fireEvent("show", this);
+
+
+ },
+
+ hide : function()
+ {
+ this.fireEvent("beforehide", this);
+
+ this.hidden = true;
+ this.el.removeClass('open');
+ Roo.get(document).un("mouseup", this.onMouseUp);
+ this.fireEvent("hide", this);
},
- getActivePane : function()
+ onMouseUp : function()
{
- var r = false;
- Roo.each(this.panes, function(p) {
- if(p.el.hasClass('active')){
- r = p;
- return false;
- }
-
- return;
- });
-
- return r;
+ this.hide();
}
-
});
-/*
+ /*
* - LGPL
*
- * Tab pane
+ * menu item
*
*/
-Roo.bootstrap.dash = Roo.bootstrap.dash || {};
+Roo.bootstrap.menu = Roo.bootstrap.menu || {};
+
/**
- * @class Roo.bootstrap.TabPane
+ * @class Roo.bootstrap.menu.Item
* @extends Roo.bootstrap.Component
- * Bootstrap TabPane class
- * @cfg {Boolean} active (false | true) Default false
- * @cfg {String} title title of panel
-
+ * Bootstrap MenuItem class
+ * @cfg {Boolean} submenu (true | false) default false
+ * @cfg {String} html text of the item
+ * @cfg {String} href the link
+ * @cfg {Boolean} disable (true | false) default false
+ * @cfg {Boolean} preventDefault (true | false) default true
+ * @cfg {String} icon Font awesome icon
+ * @cfg {String} pos Submenu align to (left | right) default right
+ *
*
* @constructor
- * Create a new TabPane
+ * Create a new Item
* @param {Object} config The config object
*/
-Roo.bootstrap.dash.TabPane = function(config){
- Roo.bootstrap.dash.TabPane.superclass.constructor.call(this, config);
-
+
+Roo.bootstrap.menu.Item = function(config){
+ Roo.bootstrap.menu.Item.superclass.constructor.call(this, config);
this.addEvents({
+ /**
+ * @event mouseover
+ * Fires when the mouse is hovering over this menu
+ * @param {Roo.bootstrap.menu.Item} this
+ * @param {Roo.EventObject} e
+ */
+ mouseover : true,
+ /**
+ * @event mouseout
+ * Fires when the mouse exits this menu
+ * @param {Roo.bootstrap.menu.Item} this
+ * @param {Roo.EventObject} e
+ */
+ mouseout : true,
// raw events
/**
- * @event activate
- * When a pane is activated
- * @param {Roo.bootstrap.dash.TabPane} pane
+ * @event click
+ * The raw click event for the entire grid.
+ * @param {Roo.EventObject} e
*/
- "activate" : true
-
+ click : true
});
};
-Roo.extend(Roo.bootstrap.dash.TabPane, Roo.bootstrap.Component, {
+Roo.extend(Roo.bootstrap.menu.Item, Roo.bootstrap.Component, {
- active : false,
- title : '',
+ submenu : false,
+ href : '',
+ html : '',
+ preventDefault: true,
+ disable : false,
+ icon : false,
+ pos : 'right',
- // the tabBox that this is attached to.
- tab : false,
-
- getAutoCreate : function()
+ getAutoCreate : function()
{
+ var text = [
+ {
+ tag : 'span',
+ cls : 'roo-menu-item-text',
+ html : this.html
+ }
+ ];
+
+ if(this.icon){
+ text.unshift({
+ tag : 'i',
+ cls : 'fa ' + this.icon
+ })
+ }
+
var cfg = {
- tag: 'div',
- cls: 'tab-pane'
+ tag : 'li',
+ cn : [
+ {
+ tag : 'a',
+ href : this.href || '#',
+ cn : text
+ }
+ ]
+ };
+
+ if(this.disable){
+ cfg.cls = (typeof(cfg.cls) == 'undefined') ? 'disabled' : (cfg.cls + ' disabled');
}
- if(this.active){
- cfg.cls += ' active';
+ if(this.submenu){
+ cfg.cls = (typeof(cfg.cls) == 'undefined') ? 'dropdown-submenu' : (cfg.cls + ' dropdown-submenu');
+
+ if(this.pos == 'left'){
+ cfg.cls = (typeof(cfg.cls) == 'undefined') ? 'pull-left' : (cfg.cls + ' pull-left');
+ }
}
return cfg;
},
- initEvents : function()
+
+ initEvents : function()
{
- //Roo.log('trigger add pane handler');
- this.parent().fireEvent('addpane', this)
+ this.el.on('mouseover', this.onMouseOver, this);
+ this.el.on('mouseout', this.onMouseOut, this);
+
+ this.el.select('a', true).first().on('click', this.onClick, this);
+
},
- /**
- * Updates the tab title
- * @param {String} html to set the title to.
- */
- setTitle: function(str)
+ onClick : function(e)
{
- if (!this.tab) {
- return;
+ if(this.preventDefault){
+ e.preventDefault();
}
- this.title = str;
- this.tab.select('a', true).first().dom.innerHTML = str;
- }
-
+ this.fireEvent("click", this, e);
+ },
+ onMouseOver : function(e)
+ {
+ if(this.submenu && this.pos == 'left'){
+ this.el.select('ul.dropdown-menu', true).first().setLeft(this.el.select('ul.dropdown-menu', true).first().getWidth() * -1);
+ }
+
+ this.fireEvent("mouseover", this, e);
+ },
+ onMouseOut : function(e)
+ {
+ this.fireEvent("mouseout", this, e);
+ }
});
-
/*
* - LGPL
*
- * menu
+ * menu separator
*
*/
Roo.bootstrap.menu = Roo.bootstrap.menu || {};
/**
- * @class Roo.bootstrap.menu.Menu
+ * @class Roo.bootstrap.menu.Separator
* @extends Roo.bootstrap.Component
- * Bootstrap Menu class - container for Menu
- * @cfg {String} html Text of the menu
- * @cfg {String} weight (default | primary | success | info | warning | danger | inverse)
- * @cfg {String} icon Font awesome icon
- * @cfg {String} pos Menu align to (top | bottom) default bottom
- *
+ * Bootstrap Separator class
*
* @constructor
- * Create a new Menu
+ * Create a new Separator
* @param {Object} config The config object
*/
-Roo.bootstrap.menu.Menu = function(config){
- Roo.bootstrap.menu.Menu.superclass.constructor.call(this, config);
-
- this.addEvents({
- /**
- * @event beforeshow
- * Fires before this menu is displayed
- * @param {Roo.bootstrap.menu.Menu} this
- */
- beforeshow : true,
- /**
- * @event beforehide
- * Fires before this menu is hidden
- * @param {Roo.bootstrap.menu.Menu} this
- */
- beforehide : true,
- /**
- * @event show
- * Fires after this menu is displayed
- * @param {Roo.bootstrap.menu.Menu} this
- */
- show : true,
- /**
- * @event hide
- * Fires after this menu is hidden
- * @param {Roo.bootstrap.menu.Menu} this
- */
- hide : true,
- /**
- * @event click
- * Fires when this menu is clicked (or when the enter key is pressed while it is active)
- * @param {Roo.bootstrap.menu.Menu} this
- * @param {Roo.EventObject} e
- */
- click : true
- });
+Roo.bootstrap.menu.Separator = function(config){
+ Roo.bootstrap.menu.Separator.superclass.constructor.call(this, config);
+};
+
+Roo.extend(Roo.bootstrap.menu.Separator, Roo.bootstrap.Component, {
+ getAutoCreate : function(){
+ var cfg = {
+ tag : 'li',
+ cls: 'divider'
+ };
+
+ return cfg;
+ }
+
+});
+
+
+
+ /*
+ * - LGPL
+ *
+ * Tooltip
+ *
+ */
+
+/**
+ * @class Roo.bootstrap.Tooltip
+ * Bootstrap Tooltip class
+ * This is basic at present - all componets support it by default, however they should add tooltipEl() method
+ * to determine which dom element triggers the tooltip.
+ *
+ * It needs to add support for additional attributes like tooltip-position
+ *
+ * @constructor
+ * Create a new Toolti
+ * @param {Object} config The config object
+ */
+
+Roo.bootstrap.Tooltip = function(config){
+ Roo.bootstrap.Tooltip.superclass.constructor.call(this, config);
};
-Roo.extend(Roo.bootstrap.menu.Menu, Roo.bootstrap.Component, {
-
- submenu : false,
- html : '',
- weight : 'default',
- icon : false,
- pos : 'bottom',
+Roo.apply(Roo.bootstrap.Tooltip, {
+ /**
+ * @function init initialize tooltip monitoring.
+ * @static
+ */
+ currentEl : false,
+ currentTip : false,
+ currentRegion : false,
+ // init : delay?
- getChildContainer : function() {
- if(this.isSubMenu){
- return this.el;
- }
+ init : function()
+ {
+ Roo.get(document).on('mouseover', this.enter ,this);
+ Roo.get(document).on('mouseout', this.leave, this);
+
- return this.el.select('ul.dropdown-menu', true).first();
+ this.currentTip = new Roo.bootstrap.Tooltip();
},
- getAutoCreate : function()
+ enter : function(ev)
{
- var text = [
- {
- tag : 'span',
- cls : 'roo-menu-text',
- html : this.html
- }
- ];
+ var dom = ev.getTarget();
- if(this.icon){
- text.unshift({
- tag : 'i',
- cls : 'fa ' + this.icon
- })
+ //Roo.log(['enter',dom]);
+ var el = Roo.fly(dom);
+ if (this.currentEl) {
+ //Roo.log(dom);
+ //Roo.log(this.currentEl);
+ //Roo.log(this.currentEl.contains(dom));
+ if (this.currentEl == el) {
+ return;
+ }
+ if (dom != this.currentEl.dom && this.currentEl.contains(dom)) {
+ return;
+ }
+
}
- var cfg = {
- tag : 'div',
- cls : 'btn-group',
- cn : [
- {
- tag : 'button',
- cls : 'dropdown-button btn btn-' + this.weight,
- cn : text
- },
- {
- tag : 'button',
- cls : 'dropdown-toggle btn btn-' + this.weight,
- cn : [
- {
- tag : 'span',
- cls : 'caret'
- }
- ]
- },
- {
- tag : 'ul',
- cls : 'dropdown-menu'
- }
- ]
-
- };
- if(this.pos == 'top'){
- cfg.cls += ' dropup';
- }
+ if (this.currentTip.el) {
+ this.currentTip.el.hide(); // force hiding...
+ }
+ //Roo.log(ev);
+ var bindEl = el;
- if(this.isSubMenu){
- cfg = {
- tag : 'ul',
- cls : 'dropdown-menu'
+ // you can not look for children, as if el is the body.. then everythign is the child..
+ if (!el.attr('tooltip')) { //
+ if (!el.select("[tooltip]").elements.length) {
+ return;
+ }
+ // is the mouse over this child...?
+ bindEl = el.select("[tooltip]").first();
+ var xy = ev.getXY();
+ if (!bindEl.getRegion().contains( { top : xy[1] ,right : xy[0] , bottom : xy[1], left : xy[0]})) {
+ //Roo.log("not in region.");
+ return;
}
+ //Roo.log("child element over..");
+
}
-
- return cfg;
- },
-
- onRender : function(ct, position)
- {
- this.isSubMenu = ct.hasClass('dropdown-submenu');
+ this.currentEl = bindEl;
+ this.currentTip.bind(bindEl);
+ this.currentRegion = Roo.lib.Region.getRegion(dom);
+ this.currentTip.enter();
- Roo.bootstrap.menu.Menu.superclass.onRender.call(this, ct, position);
},
-
- initEvents : function()
+ leave : function(ev)
{
- if(this.isSubMenu){
+ var dom = ev.getTarget();
+ //Roo.log(['leave',dom]);
+ if (!this.currentEl) {
return;
}
- this.hidden = true;
- this.triggerEl = this.el.select('button.dropdown-toggle', true).first();
- this.triggerEl.on('click', this.onTriggerPress, this);
+ if (dom != this.currentEl.dom) {
+ return;
+ }
+ var xy = ev.getXY();
+ if (this.currentRegion.contains( new Roo.lib.Region( xy[1], xy[0] ,xy[1], xy[0] ))) {
+ return;
+ }
+ // only activate leave if mouse cursor is outside... bounding box..
- this.buttonEl = this.el.select('button.dropdown-button', true).first();
- this.buttonEl.on('click', this.onClick, this);
- },
-
- list : function()
- {
- if(this.isSubMenu){
- return this.el;
+
+
+ if (this.currentTip) {
+ this.currentTip.leave();
}
+ //Roo.log('clear currentEl');
+ this.currentEl = false;
+
- return this.el.select('ul.dropdown-menu', true).first();
},
+ alignment : {
+ 'left' : ['r-l', [-2,0], 'right'],
+ 'right' : ['l-r', [2,0], 'left'],
+ 'bottom' : ['t-b', [0,2], 'top'],
+ 'top' : [ 'b-t', [0,-2], 'bottom']
+ }
- onClick : function(e)
+});
+
+
+Roo.extend(Roo.bootstrap.Tooltip, Roo.bootstrap.Component, {
+
+
+ bindEl : false,
+
+ delay : null, // can be { show : 300 , hide: 500}
+
+ timeout : null,
+
+ hoverState : null, //???
+
+ placement : 'bottom',
+
+ getAutoCreate : function(){
+
+ var cfg = {
+ cls : 'tooltip',
+ role : 'tooltip',
+ cn : [
+ {
+ cls : 'tooltip-arrow'
+ },
+ {
+ cls : 'tooltip-inner'
+ }
+ ]
+ };
+
+ return cfg;
+ },
+ bind : function(el)
{
- this.fireEvent("click", this, e);
+ this.bindEl = el;
},
+
- onTriggerPress : function(e)
- {
- if (this.isVisible()) {
- this.hide();
- } else {
+ enter : function () {
+
+ if (this.timeout != null) {
+ clearTimeout(this.timeout);
+ }
+
+ this.hoverState = 'in';
+ //Roo.log("enter - show");
+ if (!this.delay || !this.delay.show) {
this.show();
+ return;
}
+ var _t = this;
+ this.timeout = setTimeout(function () {
+ if (_t.hoverState == 'in') {
+ _t.show();
+ }
+ }, this.delay.show);
},
+ leave : function()
+ {
+ clearTimeout(this.timeout);
- isVisible : function(){
- return !this.hidden;
+ this.hoverState = 'out';
+ if (!this.delay || !this.delay.hide) {
+ this.hide();
+ return;
+ }
+
+ var _t = this;
+ this.timeout = setTimeout(function () {
+ //Roo.log("leave - timeout");
+
+ if (_t.hoverState == 'out') {
+ _t.hide();
+ Roo.bootstrap.Tooltip.currentEl = false;
+ }
+ }, delay);
},
- show : function()
+ show : function ()
{
- this.fireEvent("beforeshow", this);
+ if (!this.el) {
+ this.render(document.body);
+ }
+ // set content.
+ //Roo.log([this.bindEl, this.bindEl.attr('tooltip')]);
- this.hidden = false;
- this.el.addClass('open');
+ var tip = this.bindEl.attr('tooltip') || this.bindEl.select("[tooltip]").first().attr('tooltip');
+
+ this.el.select('.tooltip-inner',true).first().dom.innerHTML = tip;
+
+ this.el.removeClass(['fade','top','bottom', 'left', 'right','in']);
+
+ var placement = typeof this.placement == 'function' ?
+ this.placement.call(this, this.el, on_el) :
+ this.placement;
+
+ var autoToken = /\s?auto?\s?/i;
+ var autoPlace = autoToken.test(placement);
+ if (autoPlace) {
+ placement = placement.replace(autoToken, '') || 'top';
+ }
- Roo.get(document).on("mouseup", this.onMouseUp, this);
+ //this.el.detach()
+ //this.el.setXY([0,0]);
+ this.el.show();
+ //this.el.dom.style.display='block';
+ this.el.addClass(placement);
- this.fireEvent("show", this);
+ //this.el.appendTo(on_el);
+ var p = this.getPosition();
+ var box = this.el.getBox();
- },
-
- hide : function()
- {
- this.fireEvent("beforehide", this);
+ if (autoPlace) {
+ // fixme..
+ }
+ var align = Roo.bootstrap.Tooltip.alignment[placement];
+ this.el.alignTo(this.bindEl, align[0],align[1]);
+ //var arrow = this.el.select('.arrow',true).first();
+ //arrow.set(align[2],
- this.hidden = true;
- this.el.removeClass('open');
+ this.el.addClass('in fade');
+ this.hoverState = null;
- Roo.get(document).un("mouseup", this.onMouseUp);
+ if (this.el.hasClass('fade')) {
+ // fade it?
+ }
- this.fireEvent("hide", this);
},
-
- onMouseUp : function()
+ hide : function()
{
- this.hide();
+
+ if (!this.el) {
+ return;
+ }
+ //this.el.setXY([0,0]);
+ this.el.removeClass('in');
+ //this.el.hide();
+
}
});
-
+
/*
* - LGPL
*
- * menu item
+ * Location Picker
*
*/
-Roo.bootstrap.menu = Roo.bootstrap.menu || {};
/**
- * @class Roo.bootstrap.menu.Item
+ * @class Roo.bootstrap.LocationPicker
* @extends Roo.bootstrap.Component
- * Bootstrap MenuItem class
- * @cfg {Boolean} submenu (true | false) default false
- * @cfg {String} html text of the item
- * @cfg {String} href the link
- * @cfg {Boolean} disable (true | false) default false
- * @cfg {Boolean} preventDefault (true | false) default true
- * @cfg {String} icon Font awesome icon
- * @cfg {String} pos Submenu align to (left | right) default right
- *
+ * Bootstrap LocationPicker class
+ * @cfg {Number} latitude Position when init default 0
+ * @cfg {Number} longitude Position when init default 0
+ * @cfg {Number} zoom default 15
+ * @cfg {String} mapTypeId default google.maps.MapTypeId.ROADMAP
+ * @cfg {Boolean} mapTypeControl default false
+ * @cfg {Boolean} disableDoubleClickZoom default false
+ * @cfg {Boolean} scrollwheel default true
+ * @cfg {Boolean} streetViewControl default false
+ * @cfg {Number} radius default 0
+ * @cfg {String} locationName
+ * @cfg {Boolean} draggable default true
+ * @cfg {Boolean} enableAutocomplete default false
+ * @cfg {Boolean} enableReverseGeocode default true
+ * @cfg {String} markerTitle
*
* @constructor
- * Create a new Item
+ * Create a new LocationPicker
* @param {Object} config The config object
*/
-Roo.bootstrap.menu.Item = function(config){
- Roo.bootstrap.menu.Item.superclass.constructor.call(this, config);
+Roo.bootstrap.LocationPicker = function(config){
+
+ Roo.bootstrap.LocationPicker.superclass.constructor.call(this, config);
+
this.addEvents({
/**
- * @event mouseover
- * Fires when the mouse is hovering over this menu
- * @param {Roo.bootstrap.menu.Item} this
- * @param {Roo.EventObject} e
+ * @event initial
+ * Fires when the picker initialized.
+ * @param {Roo.bootstrap.LocationPicker} this
+ * @param {Google Location} location
*/
- mouseover : true,
+ initial : true,
/**
- * @event mouseout
- * Fires when the mouse exits this menu
- * @param {Roo.bootstrap.menu.Item} this
- * @param {Roo.EventObject} e
+ * @event positionchanged
+ * Fires when the picker position changed.
+ * @param {Roo.bootstrap.LocationPicker} this
+ * @param {Google Location} location
*/
- mouseout : true,
- // raw events
+ positionchanged : true,
/**
- * @event click
- * The raw click event for the entire grid.
- * @param {Roo.EventObject} e
+ * @event resize
+ * Fires when the map resize.
+ * @param {Roo.bootstrap.LocationPicker} this
*/
- click : true
+ resize : true,
+ /**
+ * @event show
+ * Fires when the map show.
+ * @param {Roo.bootstrap.LocationPicker} this
+ */
+ show : true,
+ /**
+ * @event hide
+ * Fires when the map hide.
+ * @param {Roo.bootstrap.LocationPicker} this
+ */
+ hide : true,
+ /**
+ * @event mapClick
+ * Fires when click the map.
+ * @param {Roo.bootstrap.LocationPicker} this
+ * @param {Map event} e
+ */
+ mapClick : true,
+ /**
+ * @event mapRightClick
+ * Fires when right click the map.
+ * @param {Roo.bootstrap.LocationPicker} this
+ * @param {Map event} e
+ */
+ mapRightClick : true,
+ /**
+ * @event markerClick
+ * Fires when click the marker.
+ * @param {Roo.bootstrap.LocationPicker} this
+ * @param {Map event} e
+ */
+ markerClick : true,
+ /**
+ * @event markerRightClick
+ * Fires when right click the marker.
+ * @param {Roo.bootstrap.LocationPicker} this
+ * @param {Map event} e
+ */
+ markerRightClick : true,
+ /**
+ * @event OverlayViewDraw
+ * Fires when OverlayView Draw
+ * @param {Roo.bootstrap.LocationPicker} this
+ */
+ OverlayViewDraw : true,
+ /**
+ * @event OverlayViewOnAdd
+ * Fires when OverlayView Draw
+ * @param {Roo.bootstrap.LocationPicker} this
+ */
+ OverlayViewOnAdd : true,
+ /**
+ * @event OverlayViewOnRemove
+ * Fires when OverlayView Draw
+ * @param {Roo.bootstrap.LocationPicker} this
+ */
+ OverlayViewOnRemove : true,
+ /**
+ * @event OverlayViewShow
+ * Fires when OverlayView Draw
+ * @param {Roo.bootstrap.LocationPicker} this
+ * @param {Pixel} cpx
+ */
+ OverlayViewShow : true,
+ /**
+ * @event OverlayViewHide
+ * Fires when OverlayView Draw
+ * @param {Roo.bootstrap.LocationPicker} this
+ */
+ OverlayViewHide : true
});
+
};
-Roo.extend(Roo.bootstrap.menu.Item, Roo.bootstrap.Component, {
+Roo.extend(Roo.bootstrap.LocationPicker, Roo.bootstrap.Component, {
- submenu : false,
- href : '',
- html : '',
- preventDefault: true,
- disable : false,
- icon : false,
- pos : 'right',
+ gMapContext: false,
- getAutoCreate : function()
+ latitude: 0,
+ longitude: 0,
+ zoom: 15,
+ mapTypeId: false,
+ mapTypeControl: false,
+ disableDoubleClickZoom: false,
+ scrollwheel: true,
+ streetViewControl: false,
+ radius: 0,
+ locationName: '',
+ draggable: true,
+ enableAutocomplete: false,
+ enableReverseGeocode: true,
+ markerTitle: '',
+
+ getAutoCreate: function()
{
- var text = [
- {
- tag : 'span',
- cls : 'roo-menu-item-text',
- html : this.html
- }
- ];
-
- if(this.icon){
- text.unshift({
- tag : 'i',
- cls : 'fa ' + this.icon
- })
- }
-
+
var cfg = {
- tag : 'li',
- cn : [
- {
- tag : 'a',
- href : this.href || '#',
- cn : text
- }
- ]
- };
-
- if(this.disable){
- cfg.cls = (typeof(cfg.cls) == 'undefined') ? 'disabled' : (cfg.cls + ' disabled');
- }
-
- if(this.submenu){
- cfg.cls = (typeof(cfg.cls) == 'undefined') ? 'dropdown-submenu' : (cfg.cls + ' dropdown-submenu');
-
- if(this.pos == 'left'){
- cfg.cls = (typeof(cfg.cls) == 'undefined') ? 'pull-left' : (cfg.cls + ' pull-left');
- }
- }
+ tag: 'div',
+ cls: 'roo-location-picker'
+ };
- return cfg;
+ return cfg
},
- initEvents : function()
- {
- this.el.on('mouseover', this.onMouseOver, this);
- this.el.on('mouseout', this.onMouseOut, this);
+ initEvents: function(ct, position)
+ {
+ if(!this.el.getWidth() || this.isApplied()){
+ return;
+ }
- this.el.select('a', true).first().on('click', this.onClick, this);
+ this.el.setVisibilityMode(Roo.Element.DISPLAY);
+ this.initial();
},
- onClick : function(e)
+ initial: function()
{
- if(this.preventDefault){
- e.preventDefault();
+ if(!this.mapTypeId){
+ this.mapTypeId = google.maps.MapTypeId.ROADMAP;
}
- this.fireEvent("click", this, e);
+ this.gMapContext = this.GMapContext();
+
+ this.initOverlayView();
+
+ this.OverlayView = new Roo.bootstrap.LocationPicker.OverlayView(this.gMapContext.map);
+
+ var _this = this;
+
+ google.maps.event.addListener(this.gMapContext.marker, "dragend", function(event) {
+ _this.setPosition(_this.gMapContext.marker.position);
+ });
+
+ google.maps.event.addListener(this.gMapContext.map, 'click', function(event){
+ _this.fireEvent('mapClick', this, event);
+
+ });
+
+ google.maps.event.addListener(this.gMapContext.map, 'rightclick', function(event){
+ _this.fireEvent('mapRightClick', this, event);
+
+ });
+
+ google.maps.event.addListener(this.gMapContext.marker, 'click', function(event){
+ _this.fireEvent('markerClick', this, event);
+
+ });
+
+ google.maps.event.addListener(this.gMapContext.marker, 'rightclick', function(event){
+ _this.fireEvent('markerRightClick', this, event);
+
+ });
+
+ this.setPosition(this.gMapContext.location);
+
+ this.fireEvent('initial', this, this.gMapContext.location);
},
- onMouseOver : function(e)
+ initOverlayView: function()
{
- if(this.submenu && this.pos == 'left'){
- this.el.select('ul.dropdown-menu', true).first().setLeft(this.el.select('ul.dropdown-menu', true).first().getWidth() * -1);
- }
+ var _this = this;
- this.fireEvent("mouseover", this, e);
+ Roo.bootstrap.LocationPicker.OverlayView.prototype = Roo.apply(new google.maps.OverlayView(), {
+
+ draw: function()
+ {
+ _this.fireEvent('OverlayViewDraw', _this);
+ },
+
+ onAdd: function()
+ {
+ _this.fireEvent('OverlayViewOnAdd', _this);
+ },
+
+ onRemove: function()
+ {
+ _this.fireEvent('OverlayViewOnRemove', _this);
+ },
+
+ show: function(cpx)
+ {
+ _this.fireEvent('OverlayViewShow', _this, cpx);
+ },
+
+ hide: function()
+ {
+ _this.fireEvent('OverlayViewHide', _this);
+ }
+
+ });
},
- onMouseOut : function(e)
+ fromLatLngToContainerPixel: function(event)
{
- this.fireEvent("mouseout", this, e);
- }
-});
-
-
-
- /*
- * - LGPL
- *
- * menu separator
- *
- */
-Roo.bootstrap.menu = Roo.bootstrap.menu || {};
-
-/**
- * @class Roo.bootstrap.menu.Separator
- * @extends Roo.bootstrap.Component
- * Bootstrap Separator class
- *
- * @constructor
- * Create a new Separator
- * @param {Object} config The config object
- */
-
-
-Roo.bootstrap.menu.Separator = function(config){
- Roo.bootstrap.menu.Separator.superclass.constructor.call(this, config);
-};
-
-Roo.extend(Roo.bootstrap.menu.Separator, Roo.bootstrap.Component, {
+ return this.OverlayView.getProjection().fromLatLngToContainerPixel(event.latLng);
+ },
- getAutoCreate : function(){
- var cfg = {
- tag : 'li',
- cls: 'divider'
- };
-
- return cfg;
- }
-
-});
-
-
-
- /*
- * - LGPL
- *
- * Tooltip
- *
- */
-
-/**
- * @class Roo.bootstrap.Tooltip
- * Bootstrap Tooltip class
- * This is basic at present - all componets support it by default, however they should add tooltipEl() method
- * to determine which dom element triggers the tooltip.
- *
- * It needs to add support for additional attributes like tooltip-position
- *
- * @constructor
- * Create a new Toolti
- * @param {Object} config The config object
- */
-
-Roo.bootstrap.Tooltip = function(config){
- Roo.bootstrap.Tooltip.superclass.constructor.call(this, config);
-};
-
-Roo.apply(Roo.bootstrap.Tooltip, {
- /**
- * @function init initialize tooltip monitoring.
- * @static
- */
- currentEl : false,
- currentTip : false,
- currentRegion : false,
+ isApplied: function()
+ {
+ return this.getGmapContext() == false ? false : true;
+ },
- // init : delay?
+ getGmapContext: function()
+ {
+ return this.gMapContext
+ },
- init : function()
+ GMapContext: function()
{
- Roo.get(document).on('mouseover', this.enter ,this);
- Roo.get(document).on('mouseout', this.leave, this);
-
+ var position = new google.maps.LatLng(this.latitude, this.longitude);
- this.currentTip = new Roo.bootstrap.Tooltip();
+ var _map = new google.maps.Map(this.el.dom, {
+ center: position,
+ zoom: this.zoom,
+ mapTypeId: this.mapTypeId,
+ mapTypeControl: this.mapTypeControl,
+ disableDoubleClickZoom: this.disableDoubleClickZoom,
+ scrollwheel: this.scrollwheel,
+ streetViewControl: this.streetViewControl,
+ locationName: this.locationName,
+ draggable: this.draggable,
+ enableAutocomplete: this.enableAutocomplete,
+ enableReverseGeocode: this.enableReverseGeocode
+ });
+
+ var _marker = new google.maps.Marker({
+ position: position,
+ map: _map,
+ title: this.markerTitle,
+ draggable: this.draggable
+ });
+
+ return {
+ map: _map,
+ marker: _marker,
+ circle: null,
+ location: position,
+ radius: this.radius,
+ locationName: this.locationName,
+ addressComponents: {
+ formatted_address: null,
+ addressLine1: null,
+ addressLine2: null,
+ streetName: null,
+ streetNumber: null,
+ city: null,
+ district: null,
+ state: null,
+ stateOrProvince: null
+ },
+ settings: this,
+ domContainer: this.el.dom,
+ geodecoder: new google.maps.Geocoder()
+ };
},
- enter : function(ev)
+ drawCircle: function(center, radius, options)
{
- var dom = ev.getTarget();
-
- //Roo.log(['enter',dom]);
- var el = Roo.fly(dom);
- if (this.currentEl) {
- //Roo.log(dom);
- //Roo.log(this.currentEl);
- //Roo.log(this.currentEl.contains(dom));
- if (this.currentEl == el) {
- return;
- }
- if (dom != this.currentEl.dom && this.currentEl.contains(dom)) {
- return;
- }
-
+ if (this.gMapContext.circle != null) {
+ this.gMapContext.circle.setMap(null);
+ }
+ if (radius > 0) {
+ radius *= 1;
+ options = Roo.apply({}, options, {
+ strokeColor: "#0000FF",
+ strokeOpacity: .35,
+ strokeWeight: 2,
+ fillColor: "#0000FF",
+ fillOpacity: .2
+ });
+
+ options.map = this.gMapContext.map;
+ options.radius = radius;
+ options.center = center;
+ this.gMapContext.circle = new google.maps.Circle(options);
+ return this.gMapContext.circle;
}
+ return null;
+ },
+
+ setPosition: function(location)
+ {
+ this.gMapContext.location = location;
+ this.gMapContext.marker.setPosition(location);
+ this.gMapContext.map.panTo(location);
+ this.drawCircle(location, this.gMapContext.radius, {});
+ var _this = this;
- if (this.currentTip.el) {
- this.currentTip.el.hide(); // force hiding...
- }
- //Roo.log(ev);
- var bindEl = el;
-
- // you can not look for children, as if el is the body.. then everythign is the child..
- if (!el.attr('tooltip')) { //
- if (!el.select("[tooltip]").elements.length) {
- return;
- }
- // is the mouse over this child...?
- bindEl = el.select("[tooltip]").first();
- var xy = ev.getXY();
- if (!bindEl.getRegion().contains( { top : xy[1] ,right : xy[0] , bottom : xy[1], left : xy[0]})) {
- //Roo.log("not in region.");
- return;
- }
- //Roo.log("child element over..");
+ if (this.gMapContext.settings.enableReverseGeocode) {
+ this.gMapContext.geodecoder.geocode({
+ latLng: this.gMapContext.location
+ }, function(results, status) {
+
+ if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
+ _this.gMapContext.locationName = results[0].formatted_address;
+ _this.gMapContext.addressComponents = _this.address_component_from_google_geocode(results[0].address_components);
+
+ _this.fireEvent('positionchanged', this, location);
+ }
+ });
+ return;
}
- this.currentEl = bindEl;
- this.currentTip.bind(bindEl);
- this.currentRegion = Roo.lib.Region.getRegion(dom);
- this.currentTip.enter();
+ this.fireEvent('positionchanged', this, location);
},
- leave : function(ev)
+
+ resize: function()
{
- var dom = ev.getTarget();
- //Roo.log(['leave',dom]);
- if (!this.currentEl) {
- return;
- }
+ google.maps.event.trigger(this.gMapContext.map, "resize");
+ this.gMapContext.map.setCenter(this.gMapContext.marker.position);
- if (dom != this.currentEl.dom) {
- return;
+ this.fireEvent('resize', this);
+ },
+
+ setPositionByLatLng: function(latitude, longitude)
+ {
+ this.setPosition(new google.maps.LatLng(latitude, longitude));
+ },
+
+ getCurrentPosition: function()
+ {
+ return {
+ latitude: this.gMapContext.location.lat(),
+ longitude: this.gMapContext.location.lng()
+ };
+ },
+
+ getAddressName: function()
+ {
+ return this.gMapContext.locationName;
+ },
+
+ getAddressComponents: function()
+ {
+ return this.gMapContext.addressComponents;
+ },
+
+ address_component_from_google_geocode: function(address_components)
+ {
+ var result = {};
+
+ for (var i = 0; i < address_components.length; i++) {
+ var component = address_components[i];
+ if (component.types.indexOf("postal_code") >= 0) {
+ result.postalCode = component.short_name;
+ } else if (component.types.indexOf("street_number") >= 0) {
+ result.streetNumber = component.short_name;
+ } else if (component.types.indexOf("route") >= 0) {
+ result.streetName = component.short_name;
+ } else if (component.types.indexOf("neighborhood") >= 0) {
+ result.city = component.short_name;
+ } else if (component.types.indexOf("locality") >= 0) {
+ result.city = component.short_name;
+ } else if (component.types.indexOf("sublocality") >= 0) {
+ result.district = component.short_name;
+ } else if (component.types.indexOf("administrative_area_level_1") >= 0) {
+ result.stateOrProvince = component.short_name;
+ } else if (component.types.indexOf("country") >= 0) {
+ result.country = component.short_name;
+ }
}
- var xy = ev.getXY();
- if (this.currentRegion.contains( new Roo.lib.Region( xy[1], xy[0] ,xy[1], xy[0] ))) {
+
+ result.addressLine1 = [ result.streetNumber, result.streetName ].join(" ").trim();
+ result.addressLine2 = "";
+ return result;
+ },
+
+ setZoomLevel: function(zoom)
+ {
+ this.gMapContext.map.setZoom(zoom);
+ },
+
+ show: function()
+ {
+ if(!this.el){
return;
}
- // only activate leave if mouse cursor is outside... bounding box..
-
+ this.el.show();
+ this.resize();
- if (this.currentTip) {
- this.currentTip.leave();
+ this.fireEvent('show', this);
+ },
+
+ hide: function()
+ {
+ if(!this.el){
+ return;
}
- //Roo.log('clear currentEl');
- this.currentEl = false;
+ this.el.hide();
- },
- alignment : {
- 'left' : ['r-l', [-2,0], 'right'],
- 'right' : ['l-r', [2,0], 'left'],
- 'bottom' : ['t-b', [0,2], 'top'],
- 'top' : [ 'b-t', [0,-2], 'bottom']
+ this.fireEvent('hide', this);
}
});
-
-Roo.extend(Roo.bootstrap.Tooltip, Roo.bootstrap.Component, {
-
-
- bindEl : false,
+Roo.apply(Roo.bootstrap.LocationPicker, {
- delay : null, // can be { show : 300 , hide: 500}
+ OverlayView : function(map, options)
+ {
+ options = options || {};
+
+ this.setMap(map);
+ }
- timeout : null,
- hoverState : null, //???
+});/*
+ * - LGPL
+ *
+ * Alert
+ *
+ */
+
+/**
+ * @class Roo.bootstrap.Alert
+ * @extends Roo.bootstrap.Component
+ * Bootstrap Alert class
+ * @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
+ *
+ * @constructor
+ * Create a new alert
+ * @param {Object} config The config object
+ */
+
+
+Roo.bootstrap.Alert = function(config){
+ Roo.bootstrap.Alert.superclass.constructor.call(this, config);
- placement : 'bottom',
+};
+
+Roo.extend(Roo.bootstrap.Alert, Roo.bootstrap.Component, {
- getAutoCreate : function(){
+ title: '',
+ html: '',
+ weight: false,
+ faicon: false,
+ getAutoCreate : function()
+ {
+
var cfg = {
- cls : 'tooltip',
- role : 'tooltip',
- cn : [
+ tag : 'div',
+ cls : 'alert',
+ cn : [
{
- cls : 'tooltip-arrow'
+ tag : 'i',
+ cls : 'roo-alert-icon'
+
},
{
- cls : 'tooltip-inner'
+ tag : 'b',
+ cls : 'roo-alert-title',
+ html : this.title
+ },
+ {
+ tag : 'span',
+ cls : 'roo-alert-text',
+ html : this.html
}
- ]
+ ]
};
- return cfg;
- },
- bind : function(el)
- {
- this.bindEl = el;
- },
-
-
- enter : function () {
-
- if (this.timeout != null) {
- clearTimeout(this.timeout);
- }
-
- this.hoverState = 'in';
- //Roo.log("enter - show");
- if (!this.delay || !this.delay.show) {
- this.show();
- return;
- }
- var _t = this;
- this.timeout = setTimeout(function () {
- if (_t.hoverState == 'in') {
- _t.show();
- }
- }, this.delay.show);
+ if(this.faicon){
+ cfg.cn[0].cls += ' fa ' + this.faicon;
+ }
+
+ if(this.weight){
+ cfg.cls += ' alert-' + this.weight;
+ }
+
+ return cfg;
},
- leave : function()
+
+ initEvents: function()
{
- clearTimeout(this.timeout);
+ this.el.setVisibilityMode(Roo.Element.DISPLAY);
+ },
- this.hoverState = 'out';
- if (!this.delay || !this.delay.hide) {
- this.hide();
- return;
- }
-
- var _t = this;
- this.timeout = setTimeout(function () {
- //Roo.log("leave - timeout");
-
- if (_t.hoverState == 'out') {
- _t.hide();
- Roo.bootstrap.Tooltip.currentEl = false;
- }
- }, delay);
+ setTitle : function(str)
+ {
+ this.el.select('.roo-alert-title',true).first().dom.innerHTML = str;
},
- show : function ()
+ setText : function(str)
{
- if (!this.el) {
- this.render(document.body);
- }
- // set content.
- //Roo.log([this.bindEl, this.bindEl.attr('tooltip')]);
-
- var tip = this.bindEl.attr('tooltip') || this.bindEl.select("[tooltip]").first().attr('tooltip');
-
- this.el.select('.tooltip-inner',true).first().dom.innerHTML = tip;
-
- this.el.removeClass(['fade','top','bottom', 'left', 'right','in']);
-
- var placement = typeof this.placement == 'function' ?
- this.placement.call(this, this.el, on_el) :
- this.placement;
-
- var autoToken = /\s?auto?\s?/i;
- var autoPlace = autoToken.test(placement);
- if (autoPlace) {
- placement = placement.replace(autoToken, '') || 'top';
+ this.el.select('.roo-alert-text',true).first().dom.innerHTML = str;
+ },
+
+ setWeight : function(weight)
+ {
+ if(this.weight){
+ this.el.select('.alert',true).first().removeClass('alert-' + this.weight);
}
- //this.el.detach()
- //this.el.setXY([0,0]);
- this.el.show();
- //this.el.dom.style.display='block';
- this.el.addClass(placement);
-
- //this.el.appendTo(on_el);
-
- var p = this.getPosition();
- var box = this.el.getBox();
+ this.weight = weight;
- if (autoPlace) {
- // fixme..
+ this.el.select('.alert',true).first().addClass('alert-' + this.weight);
+ },
+
+ setIcon : function(icon)
+ {
+ if(this.faicon){
+ this.el.select('.roo-alert-icon',true).first().removeClass(['fa', 'fa-' + this.faicon]);
}
- var align = Roo.bootstrap.Tooltip.alignment[placement];
- this.el.alignTo(this.bindEl, align[0],align[1]);
- //var arrow = this.el.select('.arrow',true).first();
- //arrow.set(align[2],
- this.el.addClass('in fade');
- this.hoverState = null;
-
- if (this.el.hasClass('fade')) {
- // fade it?
- }
+ this.faicon = icon
+ this.el.select('.roo-alert-icon',true).first().addClass(['fa', 'fa-' + this.faicon]);
},
- hide : function()
+
+ hide: function()
{
-
- if (!this.el) {
- return;
- }
- //this.el.setXY([0,0]);
- this.el.removeClass('in');
- //this.el.hide();
-
+ this.el.hide();
+ },
+
+ show: function()
+ {
+ this.el.show();
}
});
-
- /*
- * - LGPL
- *
- * Location Picker
- *
- */
+
+/*
+* Licence: LGPL
+*/
/**
- * @class Roo.bootstrap.LocationPicker
+ * @class Roo.bootstrap.UploadCropbox
* @extends Roo.bootstrap.Component
- * Bootstrap LocationPicker class
- * @cfg {Number} latitude Position when init default 0
- * @cfg {Number} longitude Position when init default 0
- * @cfg {Number} zoom default 15
- * @cfg {String} mapTypeId default google.maps.MapTypeId.ROADMAP
- * @cfg {Boolean} mapTypeControl default false
- * @cfg {Boolean} disableDoubleClickZoom default false
- * @cfg {Boolean} scrollwheel default true
- * @cfg {Boolean} streetViewControl default false
- * @cfg {Number} radius default 0
- * @cfg {String} locationName
- * @cfg {Boolean} draggable default true
- * @cfg {Boolean} enableAutocomplete default false
- * @cfg {Boolean} enableReverseGeocode default true
- * @cfg {String} markerTitle
+ * Bootstrap UploadCropbox class
+ * @cfg {String} emptyText show when image has been loaded
+ * @cfg {Number} minWidth default 300
+ * @cfg {Number} minHeight default 300
*
* @constructor
- * Create a new LocationPicker
+ * Create a new UploadCropbox
* @param {Object} config The config object
*/
-
-Roo.bootstrap.LocationPicker = function(config){
-
- Roo.bootstrap.LocationPicker.superclass.constructor.call(this, config);
+Roo.bootstrap.UploadCropbox = function(config){
+ Roo.bootstrap.UploadCropbox.superclass.constructor.call(this, config);
this.addEvents({
/**
- * @event initial
- * Fires when the picker initialized.
- * @param {Roo.bootstrap.LocationPicker} this
- * @param {Google Location} location
- */
- initial : true,
- /**
- * @event positionchanged
- * Fires when the picker position changed.
- * @param {Roo.bootstrap.LocationPicker} this
- * @param {Google Location} location
- */
- positionchanged : true,
- /**
- * @event resize
- * Fires when the map resize.
- * @param {Roo.bootstrap.LocationPicker} this
- */
- resize : true,
- /**
- * @event show
- * Fires when the map show.
- * @param {Roo.bootstrap.LocationPicker} this
- */
- show : true,
- /**
- * @event hide
- * Fires when the map hide.
- * @param {Roo.bootstrap.LocationPicker} this
- */
- hide : true,
- /**
- * @event mapClick
- * Fires when click the map.
- * @param {Roo.bootstrap.LocationPicker} this
- * @param {Map event} e
- */
- mapClick : true,
- /**
- * @event mapRightClick
- * Fires when right click the map.
- * @param {Roo.bootstrap.LocationPicker} this
- * @param {Map event} e
- */
- mapRightClick : true,
- /**
- * @event markerClick
- * Fires when click the marker.
- * @param {Roo.bootstrap.LocationPicker} this
- * @param {Map event} e
- */
- markerClick : true,
- /**
- * @event markerRightClick
- * Fires when right click the marker.
- * @param {Roo.bootstrap.LocationPicker} this
- * @param {Map event} e
- */
- markerRightClick : true,
- /**
- * @event OverlayViewDraw
- * Fires when OverlayView Draw
- * @param {Roo.bootstrap.LocationPicker} this
- */
- OverlayViewDraw : true,
- /**
- * @event OverlayViewOnAdd
- * Fires when OverlayView Draw
- * @param {Roo.bootstrap.LocationPicker} this
- */
- OverlayViewOnAdd : true,
- /**
- * @event OverlayViewOnRemove
- * Fires when OverlayView Draw
- * @param {Roo.bootstrap.LocationPicker} this
+ * @event beforeSelectFile
+ * Fire before select file
+ * @param {Roo.bootstrap.UploadCropbox} this
*/
- OverlayViewOnRemove : true,
+ "beforeSelectFile" : true,
/**
- * @event OverlayViewShow
- * Fires when OverlayView Draw
- * @param {Roo.bootstrap.LocationPicker} this
- * @param {Pixel} cpx
+ * @event initial
+ * Fire after initEvent
+ * @param {Roo.bootstrap.UploadCropbox} this
*/
- OverlayViewShow : true,
+ "initial" : true,
/**
- * @event OverlayViewHide
- * Fires when OverlayView Draw
- * @param {Roo.bootstrap.LocationPicker} this
+ * @event crop
+ * Fire after initEvent
+ * @param {Roo.bootstrap.UploadCropbox} this
+ * @param {String} imageData
*/
- OverlayViewHide : true
- });
+ "crop" : true
+ });
};
-Roo.extend(Roo.bootstrap.LocationPicker, Roo.bootstrap.Component, {
-
- gMapContext: false,
+Roo.extend(Roo.bootstrap.UploadCropbox, Roo.bootstrap.Component, {
- latitude: 0,
- longitude: 0,
- zoom: 15,
- mapTypeId: false,
- mapTypeControl: false,
- disableDoubleClickZoom: false,
- scrollwheel: true,
- streetViewControl: false,
- radius: 0,
- locationName: '',
- draggable: true,
- enableAutocomplete: false,
- enableReverseGeocode: true,
- markerTitle: '',
+ emptyText : 'Click to upload image',
+ scale : 0,
+ baseScale : 1,
+ rotate : 0,
+ dragable : false,
+ mouseX : 0,
+ mouseY : 0,
+ cropImageData : false,
+ cropType : 'image/png',
+ minWidth : 300,
+ minHeight : 300,
- getAutoCreate: function()
+ getAutoCreate : function()
{
-
var cfg = {
- tag: 'div',
- cls: 'roo-location-picker'
+ tag : 'div',
+ cls : 'roo-upload-cropbox',
+ cn : [
+ {
+ tag : 'div',
+ cls : 'roo-upload-cropbox-image-section',
+ cn : [
+ {
+ tag : 'div',
+ cls : 'roo-upload-cropbox-canvas',
+ cn : [
+ {
+ tag : 'img',
+ cls : 'roo-upload-cropbox-image'
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'roo-upload-cropbox-thumb'
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'roo-upload-cropbox-footer-section',
+ cn : {
+ tag : 'div',
+ cls : 'btn-group btn-group-justified roo-upload-cropbox-btn-group',
+ cn : [
+ {
+ tag : 'div',
+ cls : 'btn-group',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default roo-upload-cropbox-rotate-left',
+ html : '<i class="fa fa-undo"></i>'
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'btn-group',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default roo-upload-cropbox-picture',
+ html : '<i class="fa fa-picture-o"></i>'
+ }
+ ]
+ },
+ {
+ tag : 'div',
+ cls : 'btn-group',
+ cn : [
+ {
+ tag : 'button',
+ cls : 'btn btn-default roo-upload-cropbox-rotate-right',
+ html : '<i class="fa fa-repeat"></i>'
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
};
- return cfg
+ return cfg;
},
- initEvents: function(ct, position)
- {
- if(!this.el.getWidth() || this.isApplied()){
- return;
- }
+ initEvents : function()
+ {
+ this.imageSection = this.el.select('.roo-upload-cropbox-image-section', true).first();
+ this.imageSection.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
- this.el.setVisibilityMode(Roo.Element.DISPLAY);
+ this.imageCanvas = this.el.select('.roo-upload-cropbox-canvas', true).first();
+ this.imageCanvas.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
- this.initial();
- },
-
- initial: function()
- {
- if(!this.mapTypeId){
- this.mapTypeId = google.maps.MapTypeId.ROADMAP;
- }
+ this.image = this.el.select('.roo-upload-cropbox-image', true).first();
+ this.image.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
- this.gMapContext = this.GMapContext();
+ this.thumb = this.el.select('.roo-upload-cropbox-thumb', true).first();
+ this.thumb.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
- this.initOverlayView();
+ this.footerSection = this.el.select('.roo-upload-cropbox-footer-section', true).first();
+ this.footerSection.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
+ this.footerSection.hide();
- this.OverlayView = new Roo.bootstrap.LocationPicker.OverlayView(this.gMapContext.map);
+ this.rotateLeft = this.el.select('.roo-upload-cropbox-rotate-left', true).first();
+ this.rotateLeft.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
- var _this = this;
-
- google.maps.event.addListener(this.gMapContext.marker, "dragend", function(event) {
- _this.setPosition(_this.gMapContext.marker.position);
- });
+ this.pictureBtn = this.el.select('.roo-upload-cropbox-picture', true).first();
+ this.pictureBtn.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
- google.maps.event.addListener(this.gMapContext.map, 'click', function(event){
- _this.fireEvent('mapClick', this, event);
-
- });
-
- google.maps.event.addListener(this.gMapContext.map, 'rightclick', function(event){
- _this.fireEvent('mapRightClick', this, event);
-
- });
+ this.rotateRight = this.el.select('.roo-upload-cropbox-rotate-right', true).first();
+ this.rotateRight.setVisibilityMode(Roo.Element.DISPLAY).originalDisplay = 'block';
- google.maps.event.addListener(this.gMapContext.marker, 'click', function(event){
- _this.fireEvent('markerClick', this, event);
-
- });
-
- google.maps.event.addListener(this.gMapContext.marker, 'rightclick', function(event){
- _this.fireEvent('markerRightClick', this, event);
-
- });
+ this.calcThumbBoxSize();
- this.setPosition(this.gMapContext.location);
+ this.bind();
- this.fireEvent('initial', this, this.gMapContext.location);
+ this.fireEvent('initial', this);
},
-
- initOverlayView: function()
+
+ bind : function()
{
- var _this = this;
+ this.image.on('load', this.onLoadCanvasImage, this);
- Roo.bootstrap.LocationPicker.OverlayView.prototype = Roo.apply(new google.maps.OverlayView(), {
-
- draw: function()
- {
- _this.fireEvent('OverlayViewDraw', _this);
- },
-
- onAdd: function()
- {
- _this.fireEvent('OverlayViewOnAdd', _this);
- },
-
- onRemove: function()
- {
- _this.fireEvent('OverlayViewOnRemove', _this);
- },
-
- show: function(cpx)
- {
- _this.fireEvent('OverlayViewShow', _this, cpx);
- },
-
- hide: function()
- {
- _this.fireEvent('OverlayViewHide', _this);
- }
-
- });
- },
-
- fromLatLngToContainerPixel: function(event)
- {
- return this.OverlayView.getProjection().fromLatLngToContainerPixel(event.latLng);
- },
-
- isApplied: function()
- {
- return this.getGmapContext() == false ? false : true;
- },
-
- getGmapContext: function()
- {
- return this.gMapContext
- },
-
- GMapContext: function()
- {
- var position = new google.maps.LatLng(this.latitude, this.longitude);
+ if(!this.imageSectionHasOnClickEvent){
+ this.imageSection.on('click', this.beforeSelectFile, this);
+ this.imageSectionHasOnClickEvent = true;
+ }
- var _map = new google.maps.Map(this.el.dom, {
- center: position,
- zoom: this.zoom,
- mapTypeId: this.mapTypeId,
- mapTypeControl: this.mapTypeControl,
- disableDoubleClickZoom: this.disableDoubleClickZoom,
- scrollwheel: this.scrollwheel,
- streetViewControl: this.streetViewControl,
- locationName: this.locationName,
- draggable: this.draggable,
- enableAutocomplete: this.enableAutocomplete,
- enableReverseGeocode: this.enableReverseGeocode
- });
+ this.imageSection.on('mousedown', this.onMouseDown, this);
- var _marker = new google.maps.Marker({
- position: position,
- map: _map,
- title: this.markerTitle,
- draggable: this.draggable
- });
+ this.imageSection.on('mousemove', this.onMouseMove, this);
+
+ var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel';
+
+ this.imageSection.on(mousewheel, this.onMouseWheel, this);
+
+ Roo.get(document).on('mouseup', this.onMouseUp, this);
+
+ this.pictureBtn.on('click', this.beforeSelectFile, this);
+
+ this.rotateLeft.on('click', this.onRotateLeft, this);
+
+ this.rotateRight.on('click', this.onRotateRight, this);
- return {
- map: _map,
- marker: _marker,
- circle: null,
- location: position,
- radius: this.radius,
- locationName: this.locationName,
- addressComponents: {
- formatted_address: null,
- addressLine1: null,
- addressLine2: null,
- streetName: null,
- streetNumber: null,
- city: null,
- district: null,
- state: null,
- stateOrProvince: null
- },
- settings: this,
- domContainer: this.el.dom,
- geodecoder: new google.maps.Geocoder()
- };
},
- drawCircle: function(center, radius, options)
+ unbind : function()
{
- if (this.gMapContext.circle != null) {
- this.gMapContext.circle.setMap(null);
- }
- if (radius > 0) {
- radius *= 1;
- options = Roo.apply({}, options, {
- strokeColor: "#0000FF",
- strokeOpacity: .35,
- strokeWeight: 2,
- fillColor: "#0000FF",
- fillOpacity: .2
- });
-
- options.map = this.gMapContext.map;
- options.radius = radius;
- options.center = center;
- this.gMapContext.circle = new google.maps.Circle(options);
- return this.gMapContext.circle;
+ this.image.un('load', this.onLoadCanvasImage, this);
+
+ if(this.imageSectionHasOnClickEvent){
+ this.imageSection.un('click', this.beforeSelectFile, this);
+ this.imageSectionHasOnClickEvent = false;
}
- return null;
+ this.imageSection.un('mousedown', this.onMouseDown, this);
+
+ this.imageSection.un('mousemove', this.onMouseMove, this);
+
+ var mousewheel = (/Firefox/i.test(navigator.userAgent))? 'DOMMouseScroll' : 'mousewheel';
+
+ this.imageSection.un(mousewheel, this.onMouseWheel, this);
+
+ Roo.get(document).un('mouseup', this.onMouseUp, this);
+
+ this.pictureBtn.un('click', this.beforeSelectFile, this);
+
+ this.rotateLeft.un('click', this.onRotateLeft, this);
+
+ this.rotateRight.un('click', this.onRotateRight, this);
},
- setPosition: function(location)
- {
- this.gMapContext.location = location;
- this.gMapContext.marker.setPosition(location);
- this.gMapContext.map.panTo(location);
- this.drawCircle(location, this.gMapContext.radius, {});
+ reset : function()
+ {
+ this.scale = 0;
+ this.baseScale = 1;
+ this.rotate = 0;
+ this.dragable = false;
+ this.mouseX = 0;
+ this.mouseY = 0;
+ this.cropImageData = false;
- var _this = this;
+ this.imageCanvas.dom.removeAttribute('style');
+ this.image.dom.removeAttribute('style');
+ this.image.attr('src', '');
- if (this.gMapContext.settings.enableReverseGeocode) {
- this.gMapContext.geodecoder.geocode({
- latLng: this.gMapContext.location
- }, function(results, status) {
-
- if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
- _this.gMapContext.locationName = results[0].formatted_address;
- _this.gMapContext.addressComponents = _this.address_component_from_google_geocode(results[0].address_components);
-
- _this.fireEvent('positionchanged', this, location);
- }
- });
-
- return;
+ if(!this.imageSectionHasOnClickEvent){
+ this.imageSection.on('click', this.beforeSelectFile, this);
+ this.imageSectionHasOnClickEvent = true;
}
- this.fireEvent('positionchanged', this, location);
},
- resize: function()
+ beforeSelectFile : function(e)
{
- google.maps.event.trigger(this.gMapContext.map, "resize");
-
- this.gMapContext.map.setCenter(this.gMapContext.marker.position);
-
- this.fireEvent('resize', this);
+ e.preventDefault();
+ this.fireEvent('beforeSelectFile', this);
},
- setPositionByLatLng: function(latitude, longitude)
- {
- this.setPosition(new google.maps.LatLng(latitude, longitude));
+ loadCanvasImage : function(src)
+ {
+ this.reset();
+
+ this.image.attr('src', src);
},
- getCurrentPosition: function()
- {
- return {
- latitude: this.gMapContext.location.lat(),
- longitude: this.gMapContext.location.lng()
- };
+ onLoadCanvasImage : function(src)
+ {
+ if(this.imageSectionHasOnClickEvent){
+ this.imageSection.un('click', this.beforeSelectFile, this);
+ this.imageSectionHasOnClickEvent = false;
+ }
+
+ this.image.OriginWidth = this.image.getWidth();
+ this.image.OriginHeight = this.image.getHeight();
+
+ this.fitThumbBox();
+
+ this.image.setWidth(this.image.OriginWidth * this.getScaleLevel(false));
+ this.image.setHeight(this.image.OriginHeight * this.getScaleLevel(false));
+
+ this.footerSection.show();
+
+ this.setCanvasPosition();
},
- getAddressName: function()
- {
- return this.gMapContext.locationName;
+ setCanvasPosition : function()
+ {
+ var pw = (this.imageSection.getWidth(true) - this.image.getWidth()) / 2;
+ var ph = (this.imageSection.getHeight(true) - this.image.getHeight()) / 2;
+
+ this.imageCanvas.setLeft(pw);
+ this.imageCanvas.setTop(ph);
},
- getAddressComponents: function()
- {
- return this.gMapContext.addressComponents;
+ onMouseDown : function(e)
+ {
+ e.stopEvent();
+
+ this.dragable = true;
+ this.mouseX = e.getPageX();
+ this.mouseY = e.getPageY();
+
},
- address_component_from_google_geocode: function(address_components)
- {
- var result = {};
+ onMouseMove : function(e)
+ {
+ e.stopEvent();
- for (var i = 0; i < address_components.length; i++) {
- var component = address_components[i];
- if (component.types.indexOf("postal_code") >= 0) {
- result.postalCode = component.short_name;
- } else if (component.types.indexOf("street_number") >= 0) {
- result.streetNumber = component.short_name;
- } else if (component.types.indexOf("route") >= 0) {
- result.streetName = component.short_name;
- } else if (component.types.indexOf("neighborhood") >= 0) {
- result.city = component.short_name;
- } else if (component.types.indexOf("locality") >= 0) {
- result.city = component.short_name;
- } else if (component.types.indexOf("sublocality") >= 0) {
- result.district = component.short_name;
- } else if (component.types.indexOf("administrative_area_level_1") >= 0) {
- result.stateOrProvince = component.short_name;
- } else if (component.types.indexOf("country") >= 0) {
- result.country = component.short_name;
- }
+ if (!this.dragable){
+ return;
}
- result.addressLine1 = [ result.streetNumber, result.streetName ].join(" ").trim();
- result.addressLine2 = "";
- return result;
+ var transform = new WebKitCSSMatrix(window.getComputedStyle(this.thumb.dom).webkitTransform);
+
+ var minX = this.thumb.getLeft(true) + transform.m41;
+ var minY = this.thumb.getTop(true) + transform.m42;
+
+ var maxX = minX + this.thumb.getWidth() - this.image.getWidth();
+ var maxY = minY + this.thumb.getHeight() - this.image.getHeight();
+
+ if(this.rotate == 90 || this.rotate == 270){
+ minX = this.thumb.getLeft(true) + transform.m41 - (this.image.getWidth() - this.image.getHeight()) / 2;
+ minY = this.thumb.getTop(true) + transform.m42 + (this.image.getWidth() - this.image.getHeight()) / 2;
+
+ maxX = minX + this.thumb.getWidth() - this.image.getHeight();
+ maxY = minY + this.thumb.getHeight() - this.image.getWidth();
+ }
+
+ var x = e.getPageX() - this.mouseX;
+ var y = e.getPageY() - this.mouseY;
+
+ var bgX = x + this.imageCanvas.getLeft(true);
+ var bgY = y + this.imageCanvas.getTop(true);
+
+ bgX = (minX < bgX) ? minX : ((maxX > bgX) ? maxX : bgX);
+ bgY = (minY < bgY) ? minY : ((maxY > bgY) ? maxY : bgY);
+
+ this.imageCanvas.setLeft(bgX);
+ this.imageCanvas.setTop(bgY);
+
+ this.mouseX = e.getPageX();
+ this.mouseY = e.getPageY();
},
- setZoomLevel: function(zoom)
- {
- this.gMapContext.map.setZoom(zoom);
+ onMouseUp : function(e)
+ {
+ e.stopEvent();
+
+ this.dragable = false;
},
- show: function()
- {
- if(!this.el){
+ onMouseWheel : function(e)
+ {
+ e.stopEvent();
+
+ this.scale = (e.getWheelDelta() == 1) ? (this.scale + 1) : (this.scale - 1);
+
+ var width = this.image.OriginWidth * this.getScaleLevel(false);
+ var height = this.image.OriginHeight * this.getScaleLevel(false);
+
+ if(
+ e.getWheelDelta() == -1 &&
+ (
+ (
+ (this.rotate == 0 || this.rotate == 180) && (width < this.thumb.getWidth() || height < this.thumb.getHeight())
+ )
+ ||
+ (
+ (this.rotate == 90 || this.rotate == 270) && (height < this.thumb.getWidth() || width < this.thumb.getHeight())
+ )
+ )
+ ){
+ this.scale = (e.getWheelDelta() == 1) ? (this.scale - 1) : (this.scale + 1);
return;
}
- this.el.show();
+ this.image.setWidth(width);
+ this.image.setHeight(height);
- this.resize();
+ this.setCanvasPosition();
- this.fireEvent('show', this);
},
- hide: function()
+ onRotateLeft : function(e)
{
- if(!this.el){
+ e.stopEvent();
+
+ if(
+ (
+ (this.rotate == 0 || this.rotate == 180)
+ &&
+ (this.image.getHeight() < this.thumb.getWidth() || this.image.getWidth() < this.thumb.getHeight())
+ )
+ ||
+ (
+ (this.rotate == 90 || this.rotate == 270)
+ &&
+ (this.image.getWidth() < this.thumb.getWidth() || this.image.getHeight() < this.thumb.getHeight())
+ )
+
+ ){
return;
}
- this.el.hide();
-
- this.fireEvent('hide', this);
- }
-
-});
+ this.rotate = (this.rotate < 90) ? 270 : this.rotate - 90;
-Roo.apply(Roo.bootstrap.LocationPicker, {
+ this.imageCanvas.setStyle({
+ '-ms-transform' : 'rotate(' + this.rotate + 'deg)',
+ '-webkit-transform' : 'rotate(' + this.rotate + 'deg)',
+ 'transform' : 'rotate(' + this.rotate + 'deg)'
+ });
+
+ this.setCanvasPosition();
+
+ },
- OverlayView : function(map, options)
+ onRotateRight : function(e)
{
- options = options || {};
+ e.stopEvent();
- this.setMap(map);
- }
-
-
-});/*
- * - LGPL
- *
- * Alert
- *
- */
-
-/**
- * @class Roo.bootstrap.Alert
- * @extends Roo.bootstrap.Component
- * Bootstrap Alert class
- * @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
- *
- * @constructor
- * Create a new alert
- * @param {Object} config The config object
- */
+ if(
+ (
+ (this.rotate == 0 || this.rotate == 180)
+ &&
+ (this.image.getHeight() < this.thumb.getWidth() || this.image.getWidth() < this.thumb.getHeight())
+ )
+ ||
+ (
+ (this.rotate == 90 || this.rotate == 270)
+ &&
+ (this.image.getWidth() < this.thumb.getWidth() || this.image.getHeight() < this.thumb.getHeight())
+ )
+
+ ){
+ return false;
+ }
+
+ this.rotate = (this.rotate > 180) ? 0 : this.rotate + 90;
+ this.imageCanvas.setStyle({
+ '-ms-transform' : 'rotate(' + this.rotate + 'deg)',
+ '-webkit-transform' : 'rotate(' + this.rotate + 'deg)',
+ 'transform' : 'rotate(' + this.rotate + 'deg)'
+ });
-Roo.bootstrap.Alert = function(config){
- Roo.bootstrap.Alert.superclass.constructor.call(this, config);
+ this.setCanvasPosition();
+
+
+ },
-};
+ crop : function()
+ {
+ var canvas = document.createElement("canvas");
+
+ var context = canvas.getContext("2d");
+
+ canvas.width = this.minWidth;
+ canvas.height = this.minHeight;
+
+ var centerX = this.minWidth / 2;
+ var centerY = this.minHeight / 2;
+
+ var cropWidth = this.thumb.getWidth() * this.getScaleLevel(true);
+ var cropHeight = this.thumb.getHeight() * this.getScaleLevel(true);
+
+ var transform = new WebKitCSSMatrix(window.getComputedStyle(this.thumb.dom).webkitTransform);
+ var thumbX = this.thumb.getLeft(true) + transform.m41;
+ var thumbY = this.thumb.getTop(true) + transform.m42;
+
+ var x = (thumbX - this.imageCanvas.getLeft(true)) * this.getScaleLevel(true);
+ var y = (thumbY - this.imageCanvas.getTop(true)) * this.getScaleLevel(true);
+
+ if(this.rotate == 90){
+
+ x = thumbY + (this.image.getWidth() - this.image.getHeight()) / 2 - this.imageCanvas.getTop(true);
+ y = this.image.getHeight() - this.thumb.getWidth() - (thumbX - (this.image.getWidth() - this.image.getHeight()) / 2 - this.imageCanvas.getLeft(true));
+
+ x = x * this.getScaleLevel(true);
+ y = y * this.getScaleLevel(true);
+
+ x = x < 0 ? 0 : x;
+ y = y < 0 ? 0 : y;
+
+ cropWidth = this.thumb.getHeight() * this.getScaleLevel(true);
+ cropHeight = this.thumb.getWidth() * this.getScaleLevel(true);
+
+ canvas.width = this.minWidth > this.minHeight ? this.minWidth : this.minHeight;
+ canvas.height = this.minWidth > this.minHeight ? this.minWidth : this.minHeight;
-Roo.extend(Roo.bootstrap.Alert, Roo.bootstrap.Component, {
-
- title: '',
- html: '',
- weight: false,
- faicon: false,
+ centerX = this.minWidth > this.minHeight ? (this.minWidth / 2) : (this.minHeight / 2);
+ centerY = this.minWidth > this.minHeight ? (this.minWidth / 2) : (this.minHeight / 2);
+
+ context.translate(centerX, centerY);
+ context.rotate(this.rotate * Math.PI / 180);
+
+ context.drawImage(this.image.dom, x, y, cropWidth, cropHeight, centerX * -1, centerY * -1, this.minHeight, this.minWidth);
+
+ var canvas2 = document.createElement("canvas");
+ var context2 = canvas2.getContext("2d");
+
+ canvas2.width = this.minWidth;
+ canvas2.height = this.minHeight;
+
+ context2.drawImage(canvas, Math.abs(this.minWidth - this.minHeight), 0, this.minWidth, this.minHeight, 0, 0, this.minWidth, this.minHeight);
- getAutoCreate : function()
- {
+ this.cropImageData = canvas2.toDataURL(this.cropType);
+
+ this.fireEvent('crop', this, this.cropImageData);
+
+ return;
+
+ }
- var cfg = {
- tag : 'div',
- cls : 'alert',
- cn : [
- {
- tag : 'i',
- cls : 'roo-alert-icon'
-
- },
- {
- tag : 'b',
- cls : 'roo-alert-title',
- html : this.title
- },
- {
- tag : 'span',
- cls : 'roo-alert-text',
- html : this.html
- }
- ]
- };
+ if(this.rotate == 270){
+
+ x = thumbY + (this.image.getWidth() - this.image.getHeight()) / 2 - this.imageCanvas.getTop(true);
+ y = thumbX - (this.image.getWidth() - this.image.getHeight()) / 2 - this.imageCanvas.getLeft(true);
+
+ x = (this.image.getWidth() - this.thumb.getHeight() - x) * this.getScaleLevel(true);
+ y = y * this.getScaleLevel(true);
+
+ x = x < 0 ? 0 : x;
+ y = y < 0 ? 0 : y;
+
+ cropWidth = this.thumb.getHeight() * this.getScaleLevel(true);
+ cropHeight = this.thumb.getWidth() * this.getScaleLevel(true);
+
+ canvas.width = this.minWidth > this.minHeight ? this.minWidth : this.minHeight;
+ canvas.height = this.minWidth > this.minHeight ? this.minWidth : this.minHeight;
+
+ centerX = this.minWidth > this.minHeight ? (this.minWidth / 2) : (this.minHeight / 2);
+ centerY = this.minWidth > this.minHeight ? (this.minWidth / 2) : (this.minHeight / 2);
+
+ context.translate(centerX, centerY);
+ context.rotate(this.rotate * Math.PI / 180);
+
+ context.drawImage(this.image.dom, x, y, cropWidth, cropHeight, centerX * -1, centerY * -1, this.minHeight, this.minWidth);
- if(this.faicon){
- cfg.cn[0].cls += ' fa ' + this.faicon;
+ var canvas2 = document.createElement("canvas");
+ var context2 = canvas2.getContext("2d");
+
+ canvas2.width = this.minWidth;
+ canvas2.height = this.minHeight;
+
+ context2.drawImage(canvas, 0, 0, this.minWidth, this.minHeight, 0, 0, this.minWidth, this.minHeight);
+
+ this.cropImageData = canvas2.toDataURL(this.cropType);
+
+ this.fireEvent('crop', this, this.cropImageData);
+
+ return;
+
}
- if(this.weight){
- cfg.cls += ' alert-' + this.weight;
+ if(this.rotate == 180){
+ x = this.image.OriginWidth - this.thumb.getWidth() * this.getScaleLevel(true) - x;
+ y = this.image.OriginHeight - this.thumb.getHeight() * this.getScaleLevel(true) - y;
}
- return cfg;
- },
-
- initEvents: function()
- {
- this.el.setVisibilityMode(Roo.Element.DISPLAY);
- },
-
- setTitle : function(str)
- {
- this.el.select('.roo-alert-title',true).first().dom.innerHTML = str;
- },
-
- setText : function(str)
- {
- this.el.select('.roo-alert-text',true).first().dom.innerHTML = str;
+ x = x < 0 ? 0 : x;
+ y = y < 0 ? 0 : y;
+
+ context.translate(centerX, centerY);
+
+ context.rotate(this.rotate * Math.PI / 180);
+
+ context.drawImage(this.image.dom, x, y, cropWidth, cropHeight, centerX * -1, centerY * -1, canvas.width, canvas.height);
+
+ this.cropImageData = canvas.toDataURL(this.cropType);
+
+ this.fireEvent('crop', this, this.cropImageData);
},
- setWeight : function(weight)
+ calcThumbBoxSize : function()
{
- if(this.weight){
- this.el.select('.alert',true).first().removeClass('alert-' + this.weight);
- }
+ var width, height;
- this.weight = weight;
+ height = 300;
+ width = this.minWidth * height / this.minHeight;
- this.el.select('.alert',true).first().addClass('alert-' + this.weight);
+ if(this.minWidth > this.minHeight){
+ width = 300;
+ height = this.minHeight * width / this.minWidth;
+ }
+
+ this.thumb.setStyle({
+ width : width + 'px',
+ height : height + 'px'
+ });
+
+ return;
+
},
- setIcon : function(icon)
+ fitThumbBox : function()
{
- if(this.faicon){
- this.el.select('.roo-alert-icon',true).first().removeClass(['fa', 'fa-' + this.faicon]);
- }
+ var width = this.thumb.getWidth();
+ var height = this.image.OriginHeight * width / this.image.OriginWidth;
- this.faicon = icon
+ this.baseScale = width / this.image.OriginWidth;
- this.el.select('.roo-alert-icon',true).first().addClass(['fa', 'fa-' + this.faicon]);
+ if(this.image.OriginWidth > this.image.OriginHeight){
+ height = this.thumb.getHeight();
+ width = this.image.OriginWidth * height / this.image.OriginHeight;
+
+ this.baseScale = height / this.image.OriginHeight;
+ }
+
+ return;
},
- hide: function()
+ getScaleLevel : function(reverse)
{
- this.el.hide();
- },
-
- show: function()
- {
- this.el.show();
+ if(reverse){
+ return Math.pow(1.1, this.scale * -1) / this.baseScale;
+ }
+
+ return this.baseScale * Math.pow(1.1, this.scale);
}
});
-
-
\ No newline at end of file