* you may want to set this to true.
* @type Boolean
*/
- useShims : ((isIE && !isIE7) || (isGecko && isMac))
+ useShims : ((isIE && !isIE7) || (isGecko && isMac)),
+
+
+
+ /**
+ * Selects a single element as a Roo Element
+ * This is about as close as you can get to jQuery's $('do crazy stuff')
+ * @param {String} selector The selector/xpath query
+ * @param {Node} root (optional) The start of the query (defaults to document).
+ * @return {Roo.Element}
+ */
+ selectNode : function(selector, root)
+ {
+ var node = Roo.DomQuery.selectNode(selector,root);
+ return node ? Roo.get(node) : new Roo.Element(false);
+ }
+
});
* @param {Object} options (optional)An object with standard {@link Roo.EventManager#addListener} options
*/
addListener : function(eventName, fn, scope, options){
- Roo.EventManager.on(this.dom, eventName, fn, scope || this, options);
+ if (this.dom) {
+ Roo.EventManager.on(this.dom, eventName, fn, scope || this, options);
+ }
},
/**
this.fireEvent("add", this.length-1, o, key);
return o;
},
-
+
/**
* MixedCollection has a generic way to fetch keys if you implement getKey.
<pre><code>
* @param {Mixed} o The variable to encode
* @return {String} The JSON string
*/
- this.encode = function(o){
+ this.encode = function(o)
+ {
+ // should this be extended to fully wrap stringify..
+
if(typeof o == "undefined" || o === null){
return "null";
}else if(o instanceof Array){
*/
this.decode = function(json){
- return /** eval:var:json */ eval("(" + json + ')');
+ return /** eval:var:json */ eval("(" + json + ')');
};
})();
/**
* Shorthand for {@link Roo.util.JSON#encode}
* @member Roo encode
* @method */
-Roo.encode = Roo.util.JSON.encode;
+Roo.encode = typeof(JSON) != 'undefined' && JSON.stringify ? JSON.stringify : Roo.util.JSON.encode;
/**
* Shorthand for {@link Roo.util.JSON#decode}
* @member Roo decode
* @method */
-Roo.decode = Roo.util.JSON.decode;
+Roo.decode = typeof(JSON) != 'undefined' && JSON.parse ? JSON.parse : Roo.util.JSON.decode;
/*
* Based on:
* Ext JS Library 1.1.1
}
},
+
+ /**
+ * safer version of Math.toFixed..??/
+ * @param {Number/String} value The numeric value to format
+ * @param {Number/String} value Decimal places
+ * @return {String} The formatted currency string
+ */
+ toFixed : function(v, n)
+ {
+ // why not use to fixed - precision is buggered???
+ if (!n) {
+ return Math.round(v-0);
+ }
+ var fact = Math.pow(10,n+1);
+ v = (Math.round((v-0)*fact))/fact;
+ var z = (''+fact).substring(2);
+ if (v == Math.floor(v)) {
+ return Math.floor(v) + '.' + z;
+ }
+
+ // now just padd decimals..
+ var ps = String(v).split('.');
+ var fd = (ps[1] + z);
+ var r = fd.substring(0,n);
+ var rm = fd.substring(n);
+ if (rm < 5) {
+ return ps[0] + '.' + r;
+ }
+ r*=1; // turn it into a number;
+ r++;
+ if (String(r).length != n) {
+ ps[0]*=1;
+ ps[0]++;
+ r = String(r).substring(1); // chop the end off.
+ }
+
+ return ps[0] + '.' + r;
+
+ },
+
/**
* Format a number as US currency
* @param {Number/String} value The numeric value to format
}
return "$" + whole + sub ;
},
-
+
/**
* Parse a value into a formatted date using the specified format pattern.
* @param {Mixed} value The value to format
/**
* @class Roo.dd.DragDrop
+ * @extends Roo.util.Observable
* Defines the interface and base operation of items that that can be
* dragged or can be drop targets. It was designed to be extended, overriding
* the event handlers for startDrag, onDrag, onDragOver and onDragOut.
if (id) {
this.init(id, sGroup, config);
}
+
};
-Roo.dd.DragDrop.prototype = {
+Roo.extend(Roo.dd.DragDrop, Roo.util.Observable , {
/**
* The id of the element associated with this object. This is what we
return ("DragDrop " + this.id);
}
-};
+});
})();
/*
if (id) {
this.initTarget(id, sGroup, config);
}
+ if (config.listeners || config.events) {
+ Roo.dd.DragDrop.superclass.constructor.call(this, {
+ listeners : config.listeners || {},
+ events : config.events || {}
+ });
+ }
};
// Roo.dd.DDTarget.prototype = new Roo.dd.DragDrop();
Roo.dd.DropTarget = function(el, config){
this.el = Roo.get(el);
+ var listeners = false; ;
+ if (config && config.listeners) {
+ listeners= config.listeners;
+ delete config.listeners;
+ }
Roo.apply(this, config);
if(this.containerScroll){
Roo.dd.ScrollManager.register(this.el);
}
-
- Roo.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
- {isTarget: true});
+ this.addEvents( {
+ /**
+ * @scope Roo.dd.DropTarget
+ */
+
+ /**
+ * @event enter
+ * The function a {@link Roo.dd.DragSource} calls once to notify this drop target that the source is now over the
+ * target. This default implementation adds the CSS class specified by overClass (if any) to the drop element
+ * and returns the dropAllowed config value. This method should be overridden if drop validation is required.
+ *
+ * IMPORTANT : it should set this.overClass and this.dropAllowed
+ *
+ * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
+ * @param {Event} e The event
+ * @param {Object} data An object containing arbitrary data supplied by the drag source
+ */
+ "enter" : true,
+
+ /**
+ * @event over
+ * The function a {@link Roo.dd.DragSource} calls continuously while it is being dragged over the target.
+ * This method will be called on every mouse movement while the drag source is over the drop target.
+ * This default implementation simply returns the dropAllowed config value.
+ *
+ * IMPORTANT : it should set this.dropAllowed
+ *
+ * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
+ * @param {Event} e The event
+ * @param {Object} data An object containing arbitrary data supplied by the drag source
+
+ */
+ "over" : true,
+ /**
+ * @event out
+ * The function a {@link Roo.dd.DragSource} calls once to notify this drop target that the source has been dragged
+ * out of the target without dropping. This default implementation simply removes the CSS class specified by
+ * overClass (if any) from the drop element.
+ * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
+ * @param {Event} e The event
+ * @param {Object} data An object containing arbitrary data supplied by the drag source
+ */
+ "out" : true,
+
+ /**
+ * @event drop
+ * The function a {@link Roo.dd.DragSource} calls once to notify this drop target that the dragged item has
+ * been dropped on it. This method has no default implementation and returns false, so you must provide an
+ * implementation that does something to process the drop event and returns true so that the drag source's
+ * repair action does not run.
+ *
+ * IMPORTANT : it should set this.success
+ *
+ * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
+ * @param {Event} e The event
+ * @param {Object} data An object containing arbitrary data supplied by the drag source
+ */
+ "drop" : true
+ });
+
+
+ Roo.dd.DropTarget.superclass.constructor.call( this,
+ this.el.dom,
+ this.ddGroup || this.group,
+ {
+ isTarget: true,
+ listeners : listeners || {}
+
+
+ }
+ );
};
* @cfg {String} overClass
* The CSS class applied to the drop target element while the drag source is over it (defaults to "").
*/
+ /**
+ * @cfg {String} ddGroup
+ * The drag drop group to handle drop events for
+ */
+
/**
* @cfg {String} dropAllowed
* The CSS class returned to the drag source when drop is allowed (defaults to "x-dd-drop-ok").
* The CSS class returned to the drag source when drop is not allowed (defaults to "x-dd-drop-nodrop").
*/
dropNotAllowed : "x-dd-drop-nodrop",
-
+ /**
+ * @cfg {boolean} success
+ * set this after drop listener..
+ */
+ success : false,
+ /**
+ * @cfg {boolean|String} valid true/false or string (ok-add/ok-sub/ok/nodrop)
+ * if the drop point is valid for over/enter..
+ */
+ valid : false,
// private
isTarget : true,
// private
isNotifyTarget : true,
-
+
/**
- * The function a {@link Roo.dd.DragSource} calls once to notify this drop target that the source is now over the
- * target. This default implementation adds the CSS class specified by overClass (if any) to the drop element
- * and returns the dropAllowed config value. This method should be overridden if drop validation is required.
- * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
- * @param {Event} e The event
- * @param {Object} data An object containing arbitrary data supplied by the drag source
- * @return {String} status The CSS class that communicates the drop status back to the source so that the
- * underlying {@link Roo.dd.StatusProxy} can be updated
+ * @hide
*/
- notifyEnter : function(dd, e, data){
+ notifyEnter : function(dd, e, data)
+ {
+ this.valid = true;
+ this.fireEvent('enter', dd, e, data);
if(this.overClass){
this.el.addClass(this.overClass);
}
- return this.dropAllowed;
+ return typeof(this.valid) == 'string' ? 'x-dd-drop-' + this.valid : (
+ this.valid ? this.dropAllowed : this.dropNotAllowed
+ );
},
/**
- * The function a {@link Roo.dd.DragSource} calls continuously while it is being dragged over the target.
- * This method will be called on every mouse movement while the drag source is over the drop target.
- * This default implementation simply returns the dropAllowed config value.
- * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
- * @param {Event} e The event
- * @param {Object} data An object containing arbitrary data supplied by the drag source
- * @return {String} status The CSS class that communicates the drop status back to the source so that the
- * underlying {@link Roo.dd.StatusProxy} can be updated
+ * @hide
*/
- notifyOver : function(dd, e, data){
- return this.dropAllowed;
+ notifyOver : function(dd, e, data)
+ {
+ this.valid = true;
+ this.fireEvent('over', dd, e, data);
+ return typeof(this.valid) == 'string' ? 'x-dd-drop-' + this.valid : (
+ this.valid ? this.dropAllowed : this.dropNotAllowed
+ );
},
/**
- * The function a {@link Roo.dd.DragSource} calls once to notify this drop target that the source has been dragged
- * out of the target without dropping. This default implementation simply removes the CSS class specified by
- * overClass (if any) from the drop element.
- * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
- * @param {Event} e The event
- * @param {Object} data An object containing arbitrary data supplied by the drag source
+ * @hide
*/
- notifyOut : function(dd, e, data){
+ notifyOut : function(dd, e, data)
+ {
+ this.fireEvent('out', dd, e, data);
if(this.overClass){
this.el.removeClass(this.overClass);
}
},
/**
- * The function a {@link Roo.dd.DragSource} calls once to notify this drop target that the dragged item has
- * been dropped on it. This method has no default implementation and returns false, so you must provide an
- * implementation that does something to process the drop event and returns true so that the drag source's
- * repair action does not run.
- * @param {Roo.dd.DragSource} source The drag source that was dragged over this drop target
- * @param {Event} e The event
- * @param {Object} data An object containing arbitrary data supplied by the drag source
- * @return {Boolean} True if the drop was valid, else false
+ * @hide
*/
- notifyDrop : function(dd, e, data){
- return false;
+ notifyDrop : function(dd, e, data)
+ {
+ this.success = false;
+ this.fireEvent('drop', dd, e, data);
+ return this.success;
}
});/*
* Based on:
this.recordType = rtype;
this.fields = rtype.prototype.fields;
delete this.snapshot;
- this.sortInfo = meta.sortInfo;
+ this.sortInfo = meta.sortInfo || this.sortInfo;
this.modified = [];
this.fireEvent('metachange', this, this.reader.meta);
}
* @extends Roo.data.DataReader
* Data reader class to create an Array of Roo.data.Record objects from a JSON response
* based on mappings in a provided Roo.data.Record constructor.
+ *
+ * The default behaviour of a store is to send ?_requestMeta=1, unless the class has recieved 'metaData' property
+ * in the reply previously.
+ *
* <p>
* Example code:
* <pre><code>
for(var j = 0; j < fl; j++){
f = fi[j];
var v = this.ef[j](n);
+ if (!f.convert) {
+ Roo.log('missing convert for ' + f.name);
+ Roo.log(f);
+ continue;
+ }
values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue);
}
var record = new Record(values, id);
s.left = (l+a.l)+"px";
s.top = (t+a.t)+"px";
var sw = (w+a.w), sh = (h+a.h), sws = sw +"px", shs = sh + "px";
+
if(s.width != sws || s.height != shs){
s.width = sws;
s.height = shs;
var today = (new Date()).dateFormat(this.format);
var baseTb = new Roo.Toolbar(this.el.child("td.x-date-bottom", true));
+ if (this.showClear) {
+ baseTb.add( new Roo.Toolbar.Fill());
+ }
baseTb.add({
text: String.format(this.todayText, today),
tooltip: String.format(this.todayTip, today),
if(this.menu){
this.menu = Roo.menu.MenuMgr.get(this.menu);
}
+ // register listeners first!! - so render can be captured..
+ Roo.util.Observable.call(this);
if(renderTo){
this.render(renderTo);
}
- Roo.util.Observable.call(this);
+
};
Roo.extend(Roo.Button, Roo.util.Observable, {
);
repeater.on("click", this.onClick, this);
}
+
this.fireEvent('render', this);
},
ds = el.dataSource;
el = config.container;
}
-
+ var items = [];
+ if (config.items) {
+ items = config.items;
+ config.items = [];
+ }
Roo.PagingToolbar.superclass.constructor.call(this, el, null, config);
this.ds = ds;
this.cursor = 0;
this.renderButtons(this.el);
this.bind(ds);
+
+ // supprot items array.
+
+ Roo.each(items, function(e) {
+ this.add(Roo.factory(e));
+ },this);
+
};
Roo.extend(Roo.PagingToolbar, Roo.Toolbar, {
disabled: true,
handler: this.onClick.createDelegate(this, ["prev"])
});
- this.addSeparator();
+ //this.addSeparator();
this.add(this.beforePageText);
this.field = Roo.get(this.addDom({
tag: "input",
this.field.on("focus", function(){this.dom.select();});
this.afterTextEl = this.addText(String.format(this.afterPageText, 1));
this.field.setHeight(18);
- this.addSeparator();
+ //this.addSeparator();
this.next = this.addButton({
tooltip: this.nextText,
cls: "x-btn-icon x-grid-page-next",
disabled: true,
handler: this.onClick.createDelegate(this, ["last"])
});
- this.addSeparator();
+ //this.addSeparator();
this.loading = this.addButton({
tooltip: this.refreshText,
cls: "x-btn-icon x-grid-loading",
'sw' southwest
'se' southeast
'ne' northeast
+ 'hd' horizontal drag
'all' all
</pre>
* <p>Here's an example showing the creation of a typical Resizable:</p>
* @param {String/HTMLElement/Roo.Element} el The id or element to resize
* @param {Object} config configuration options
*/
-Roo.Resizable = function(el, config){
+Roo.Resizable = function(el, config)
+{
this.el = Roo.get(el);
if(config && config.wrap){
}
// legacy
this.corner = this.southeast;
-
- if(this.handles.indexOf("n") != -1 || this.handles.indexOf("w") != -1){
+
+ // updateBox = the box can move..
+ if(this.handles.indexOf("n") != -1 || this.handles.indexOf("w") != -1 || this.handles.indexOf("hd") != -1) {
this.updateBox = true;
}
this.resizeChild = Roo.get(this.resizeChild, true);
}
}
-
+
if(this.adjustments == "auto"){
var rc = this.resizeChild;
var hw = this.west, he = this.east, hn = this.north, hs = this.south;
w += diffX;
w = Math.min(Math.max(mw, w), mxw);
break;
+
case "south":
h += diffY;
h = Math.min(Math.max(mh, h), mxh);
y += diffY;
h -= diffY;
break;
+ case "hdrag":
+
+ if (wi) {
+ var adiffX = Math.abs(diffX);
+ var sub = (adiffX % wi); // how much
+ if (sub > (wi/2)) { // far enough to snap
+ diffX = (diffX > 0) ? diffX-sub + wi : diffX+sub - wi;
+ } else {
+ // remove difference..
+ diffX = (diffX > 0) ? diffX-sub : diffX+sub;
+ }
+ }
+ x += diffX;
+ x = Math.max(this.minX, x);
+ break;
case "west":
diffX = this.constrain(w, diffX, mw, mxw);
x += diffX;
h = Math.min(Math.max(mh, h), mxh);
w = ow * (h/oh);
y += th - h;
- x += tw - w;
+ x += tw - w;
break;
}
}
+ if (pos == 'hdrag') {
+ w = ow;
+ }
this.proxy.setBounds(x, y, w, h);
if(this.dynamic){
this.resizeElement();
// private
// hash to map config positions to true positions
Roo.Resizable.positions = {
- n: "north", s: "south", e: "east", w: "west", se: "southeast", sw: "southwest", nw: "northwest", ne: "northeast"
+ n: "north", s: "south", e: "east", w: "west", se: "southeast", sw: "southwest", nw: "northwest", ne: "northeast",
+ hd: "hdrag"
};
// private
}
this.position = pos;
this.rz = rz;
- this.el = this.tpl.append(rz.el.dom, [this.position], true);
+ // show north drag fro topdra
+ var handlepos = pos == 'hdrag' ? 'north' : pos;
+
+ this.el = this.tpl.append(rz.el.dom, [handlepos], true);
+ if (pos == 'hdrag') {
+ this.el.setStyle('cursor', 'pointer');
+ }
this.el.unselectable();
if(transparent){
this.el.setOpacity(0);
}
},
- onSpecialKey : function(field, e){
+ onSpecialKey : function(field, e)
+ {
//Roo.log('editor onSpecialKey');
if(this.completeOnEnter && e.getKey() == e.ENTER){
e.stopEvent();
this.completeEdit();
- }else if(this.cancelOnEsc && e.getKey() == e.ESC){
- this.cancelEdit();
- }else{
- this.fireEvent('specialkey', field, e);
+ return;
+ }
+ // do not fire special key otherwise it might hide close the editor...
+ if(e.getKey() == e.ENTER){
+ return;
}
+ if(this.cancelOnEsc && e.getKey() == e.ESC){
+ this.cancelEdit();
+ return;
+ }
+ this.fireEvent('specialkey', field, e);
+
},
/**
// private
animShow : function(){
- var b = Roo.get(this.animateTarget, true).getBox();
+ var b = Roo.get(this.animateTarget).getBox();
this.proxy.setSize(b.width, b.height);
this.proxy.setLocation(b.x, b.y);
this.proxy.show();
this.animateTarget = animateTarget || this.animateTarget;
if(!this.el.isVisible()){
this.beforeShow();
- if(this.animateTarget){
+ if(this.animateTarget && Roo.get(this.animateTarget)){
this.animShow();
}else{
this.showEl();
if(this.shim) {
this.shim.hide();
}
- if(this.animateTarget){
+ // sometimes animateTarget seems to get set.. causing problems...
+ // this just double checks..
+ if(this.animateTarget && Roo.get(this.animateTarget)) {
this.animHide(callback);
}else{
this.el.hide();
var config= cfg;
if (typeof(cfg) == 'undefined') {
config = Roo.apply({}, el);
- el = Roo.get( document.documentElement || document.body).createChild();
+ // not sure why we use documentElement here.. - it should always be body.
+ // IE7 borks horribly if we use documentElement.
+ el = Roo.get( Roo.isIE ? (document.body || document.documentElement) : (document.documentElement || document.body) ).createChild();
//config.autoCreate = true;
}
* Fires after the field has been validated with no errors.
* @param {Roo.form.Field} this
*/
- valid : true
+ valid : true,
+ /**
+ * @event keyup
+ * Fires after the key up
+ * @param {Roo.form.Field} this
+ * @param {Roo.EventObject} e The event Object
+ */
+ keyup : true
});
},
this.el.on("keydown" , this.fireKey, this);
this.el.on("focus", this.onFocus, this);
this.el.on("blur", this.onBlur, this);
+ this.el.relayEvent('keyup', this);
// reference to original value for reset
this.originalValue = this.getValue();
*/
valueNotFoundText : undefined,
/**
- * @cfg {bool} blockFocus Prevents all focus calls, so it can work with things like HTML edtor bar
+ * @cfg {Boolean} blockFocus Prevents all focus calls, so it can work with things like HTML edtor bar
*/
blockFocus : false,
/**
- * @cfg {bool} disableClear Disable showing of clear button.
+ * @cfg {Boolean} disableClear Disable showing of clear button.
*/
disableClear : false,
+ /**
+ * @cfg {Boolean} alwaysQuery Disable caching of results, and always send query
+ */
+ alwaysQuery : false,
//private
addicon : false,
dv = !o || typeof(o[this.displayField]) == 'undefined' ? '' : o[this.displayField];
} else {
// this is an error condition!!!
- console.log('no value field set for '+ this.name);
+ Roo.log('no displayField value set for '+ (this.name ? this.name : this.id));
}
if(this.valueField){
q = qe.query;
forceAll = qe.forceAll;
if(forceAll === true || (q.length >= this.minChars)){
- if(this.lastQuery != q){
+ if(this.lastQuery != q || this.alwaysQuery){
this.lastQuery = q;
if(this.mode == 'local'){
this.selectedIndex = -1;
this.list.hide();
Roo.get(document).un('mousedown', this.collapseIf, this);
Roo.get(document).un('mousewheel', this.collapseIf, this);
+ if (!this.editable) {
+ Roo.get(document).un('keydown', this.listKeyPress, this);
+ }
this.fireEvent('collapse', this);
},
this.list.show();
Roo.get(document).on('mousedown', this.collapseIf, this);
Roo.get(document).on('mousewheel', this.collapseIf, this);
+ if (!this.editable) {
+ Roo.get(document).on('keydown', this.listKeyPress, this);
+ }
+
this.fireEvent('expand', this);
},
this.el.focus();
}
}
+ },
+ listKeyPress : function(e)
+ {
+ //Roo.log('listkeypress');
+ // scroll to first matching element based on key pres..
+ if (e.isSpecialKey()) {
+ return false;
+ }
+ var k = String.fromCharCode(e.getKey()).toUpperCase();
+ //Roo.log(k);
+ var match = false;
+ var csel = this.view.getSelectedNodes();
+ var cselitem = false;
+ if (csel.length) {
+ var ix = this.view.indexOf(csel[0]);
+ cselitem = this.store.getAt(ix);
+ if (!cselitem.get(this.displayField) || cselitem.get(this.displayField).substring(0,1).toUpperCase() != k) {
+ cselitem = false;
+ }
+
+ }
+
+ this.store.each(function(v) {
+ if (cselitem) {
+ // start at existing selection.
+ if (cselitem.id == v.id) {
+ cselitem = false;
+ }
+ return;
+ }
+
+ if (v.get(this.displayField) && v.get(this.displayField).substring(0,1).toUpperCase() == k) {
+ match = this.store.indexOf(v);
+ return false;
+ }
+ }, this);
+
+ if (match === false) {
+ return true; // no more action?
+ }
+ // scroll to?
+ this.view.select(match);
+ var sn = Roo.get(this.view.getSelectedNodes()[0])
+ sn.scrollIntoView(sn.dom.parentNode, false);
}
/**
}
this.checked = state;
if(suppressEvent !== true){
- this.fireEvent('checkchange', this, state);
+ this.fireEvent('check', this, state);
}
this.inSetChecked = true;
this.el.dom.value = state ? this.inputValue : this.valueOff;
// clean up silly Windows -- stuff?
return;
}
+ if (node.nodeName == "#comment") {
+ node.parentNode.removeChild(node);
+ // clean up silly Windows -- stuff?
+ return;
+ }
+
if (Roo.form.HtmlEditor.black.indexOf(node.tagName.toLowerCase()) > -1) {
// remove node.
node.parentNode.removeChild(node);
node.removeAttribute(n);
return;
}
+
+
var parts = v.split(/;/);
Roo.each(parts, function(p) {
p = p.replace(/\s+/g,'');
if (a.name == 'style') {
cleanStyle(a.name,a.value);
}
-
+ /// clean up MS crap..
+ if (a.name == 'class') {
+ if (a.value.match(/^Mso/)) {
+ node.className = '';
+ }
+ }
// style cleanup!?
// class cleanup?
'caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th',
'thead', 'tr',
- 'dir', 'menu', 'ol', 'ul', 'dl'
+ 'dir', 'menu', 'ol', 'ul', 'dl',
+ 'embed', 'object'
];
Roo.form.HtmlEditor.black = [
- 'embed', 'object', // eventually enable for flash?
+ // 'embed', 'object', // enable - backend responsiblity to clean thiese
'applet', //
'base', 'basefont', 'bgsound', 'blink', 'body',
'frame', 'frameset', 'head', 'html', 'ilayer',
- 'iframe', 'layer', 'link', 'meta', 'object',
-
+ 'iframe', 'layer', 'link', 'meta', 'object',
'script', 'style' ,'title', 'xml' // clean later..
];
Roo.form.HtmlEditor.clean = [
this.toolbars = {};
for (var i in ty) {
+
this.toolbars[i] = this.buildToolbar(ty[i],i);
}
this.tb = this.toolbars.BODY;
* @cfg {Boolean} fileUpload
* Set to true if this form is a file upload.
*/
+
/**
* @cfg {Object} baseParams
* Parameters to pass with all requests. e.g. baseParams: {id: '123', foo: 'bar'}.
*/
+ /**
+
/**
* @cfg {Number} timeout Timeout for form actions in seconds (default is 30 seconds).
*/
* element by passing it or its id or mask the form itself by passing in true.
* @type Mixed
*/
- waitMsgTarget : undefined,
+ waitMsgTarget : false,
// private
initEl : function(el){
// private
beforeAction : function(action){
var o = action.options;
- if(o.waitMsg){
- if(this.waitMsgTarget === true){
- this.el.mask(o.waitMsg, 'x-mask-loading');
- }else if(this.waitMsgTarget){
- this.waitMsgTarget = Roo.get(this.waitMsgTarget);
- this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
- }else{
- Roo.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle || 'Please Wait...');
- }
+
+
+ if(this.waitMsgTarget === true){
+ this.el.mask(o.waitMsg || "Sending", 'x-mask-loading');
+ }else if(this.waitMsgTarget){
+ this.waitMsgTarget = Roo.get(this.waitMsgTarget);
+ this.waitMsgTarget.mask(o.waitMsg || "Sending", 'x-mask-loading');
+ }else {
+ Roo.MessageBox.wait(o.waitMsg || "Sending", o.waitTitle || this.waitTitle || 'Please Wait...');
}
+
},
// private
afterAction : function(action, success){
this.activeAction = null;
var o = action.options;
- if(o.waitMsg){
- if(this.waitMsgTarget === true){
- this.el.unmask();
- }else if(this.waitMsgTarget){
- this.waitMsgTarget.unmask();
- }else{
- Roo.MessageBox.updateProgress(1);
- Roo.MessageBox.hide();
- }
+
+ if(this.waitMsgTarget === true){
+ this.el.unmask();
+ }else if(this.waitMsgTarget){
+ this.waitMsgTarget.unmask();
+ }else{
+ Roo.MessageBox.updateProgress(1);
+ Roo.MessageBox.hide();
}
+
if(success){
if(o.reset){
this.reset();
}
Roo.callback(o.success, o.scope, [this, action]);
this.fireEvent('actioncomplete', this, action);
+
}else{
Roo.callback(o.failure, o.scope, [this, action]);
+ // show an error message if no failed handler is set..
+ if (!this.hasListener('actionfailed')) {
+ Roo.MessageBox.alert("Error", "Saving Failed, please check your entries");
+ }
+
this.fireEvent('actionfailed', this, action);
}
+
},
/**
}
return Roo.urlDecode(fs);
},
+
+ /**
+ * Returns the fields in this form as an object with key/value pairs.
+ * This differs from getValues as it calls getValue on each child item, rather than using dom data.
+ * @return {Object}
+ */
+ getFieldValues : function()
+ {
+ if (this.childForms) {
+ // copy values from the child forms
+ Roo.each(this.childForms, function (f) {
+ this.setValues(f.getValues());
+ }, this);
+ }
+
+ var ret = {};
+ this.items.each(function(f){
+ if (!f.getName()) {
+ return;
+ }
+ var v = f.getValue();
+ if ((typeof(v) == 'object') && f.getRawValue) {
+ v = f.getRawValue() ; // dates..
+ }
+ ret[f.getName()] = v;
+ });
+
+ return ret;
+ },
/**
* Clears all invalid messages in this form.
rendered : true
});
+ if (this.progressUrl) {
+ // push a hidden field onto the list of fields..
+ this.addxtype( {
+ xns: Roo.form,
+ xtype : 'Hidden',
+ name : 'UPLOAD_IDENTIFIER'
+ });
+ }
+
+
Roo.each(xitems, this.addxtype, this);
* @cfg {Number} monitorPoll The milliseconds to poll valid state, ignored if monitorValid is not true (defaults to 200)
*/
monitorPoll : 200,
-
+
+ /**
+ * @cfg {String} progressUrl - Url to return progress data
+ */
+
+ progressUrl : false,
/**
* Opens a new {@link Roo.form.Column} container in the layout stack. If fields are passed after the config, the
* @param {String/HTMLElement/Element} container The element this component should be rendered into
* @return {Form} this
*/
- render : function(ct){
+ render : function(ct)
+ {
+
+
+
ct = Roo.get(ct);
var o = this.autoCreate || {
tag: 'form',
this.initEl(ct.createChild(o));
this.root.render(this.el);
-
+
+
+
this.items.each(function(f){
f.render('x-form-el-'+f.id);
});
// default connection failure
failure : function(response){
+
this.response = response;
this.failureType = Roo.form.Action.CONNECT_FAILURE;
this.form.afterAction(this, false);
Roo.extend(Roo.form.Action.Submit, Roo.form.Action, {
type : 'submit',
+ haveProgress : false,
+ uploadComplete : false,
+
+ // uploadProgress indicator.
+ uploadProgress : function()
+ {
+ if (!this.form.progressUrl) {
+ return;
+ }
+
+ if (!this.haveProgress) {
+ Roo.MessageBox.progress("Uploading", "Uploading");
+ }
+ if (this.uploadComplete) {
+ Roo.MessageBox.hide();
+ return;
+ }
+
+ this.haveProgress = true;
+
+ var uid = this.form.findField('UPLOAD_IDENTIFIER').getValue();
+
+ var c = new Roo.data.Connection();
+ c.request({
+ url : this.form.progressUrl,
+ params: {
+ id : uid
+ },
+ method: 'GET',
+ success : function(req){
+ //console.log(data);
+ var rdata = false;
+ var edata;
+ try {
+ rdata = Roo.decode(req.responseText)
+ } catch (e) {
+ Roo.log("Invalid data from server..");
+ Roo.log(edata);
+ return;
+ }
+ if (!rdata || !rdata.success) {
+ Roo.log(rdata);
+ return;
+ }
+ var data = rdata.data;
+
+ if (this.uploadComplete) {
+ Roo.MessageBox.hide();
+ return;
+ }
+
+ if (data){
+ Roo.MessageBox.updateProgress(data.bytes_uploaded/data.bytes_total,
+ Math.floor((data.bytes_total - data.bytes_uploaded)/1000) + 'k remaining'
+ );
+ }
+ this.uploadProgress.defer(2000,this);
+ },
+
+ failure: function(data) {
+ Roo.log('progress url failed ');
+ Roo.log(data);
+ },
+ scope : this
+ });
+
+ },
+
+
run : function()
{
// run get Values on the form, so it syncs any secondary forms.
var method = this.getMethod();
var isPost = method == 'POST';
if(o.clientValidation === false || this.form.isValid()){
+
+ if (this.form.progressUrl) {
+ this.form.findField('UPLOAD_IDENTIFIER').setValue(
+ (new Date() * 1) + '' + Math.random());
+
+ }
+
+
Roo.Ajax.request(Roo.apply(this.createCallback(), {
form:this.form.el.dom,
url:this.getUrl(!isPost),
params:isPost ? this.getParams() : null,
isUpload: this.form.fileUpload
}));
+
+ this.uploadProgress();
}else if (o.clientValidation !== false){ // client validation failed
this.failureType = Roo.form.Action.CLIENT_INVALID;
}
},
- success : function(response){
+ success : function(response)
+ {
+ this.uploadComplete= true;
+ if (this.haveProgress) {
+ Roo.MessageBox.hide();
+ }
+
+
var result = this.processResponse(response);
if(result === true || result.success){
this.form.afterAction(this, true);
}
this.form.afterAction(this, false);
},
-
+ failure : function(response)
+ {
+ this.uploadComplete= true;
+ if (this.haveProgress) {
+ Roo.MessageBox.hide();
+ }
+
+
+ this.response = response;
+ this.failureType = Roo.form.Action.CONNECT_FAILURE;
+ this.form.afterAction(this, false);
+ },
+
handleResponse : function(response){
if(this.form.errorReader){
var rs = this.form.errorReader.read(response);
} catch (e) {
ret = {
success: false,
- errorMsg: "Failed to read server message: " + response.responseText,
+ errorMsg: "Failed to read server message: " + (response ? response.responseText : ' - no message'),
errors : []
};
}
type : 'load',
run : function(){
+
Roo.Ajax.request(Roo.apply(
this.createCallback(), {
method:this.getMethod(),
},
success : function(response){
+
var result = this.processResponse(response);
if(result === true || !result.success || !result.data){
this.failureType = Roo.form.Action.LOAD_FAILURE;
* @extends Roo.form.Field
* Embed a grid (or editable grid into a form)
* STATUS ALPHA
+ *
+ * This embeds a grid in a form, the value of the field should be the json encoded array of rows
+ * it needs
+ * xgrid.store = Roo.data.Store
+ * xgrid.store.proxy = Roo.data.MemoryProxy (data = [] )
+ * xgrid.store.reader = Roo.data.JsonReader
+ *
+ *
* @constructor
* Creates a new GridField
* @param {Object} config Configuration options
*/
height : 50,
/**
- * @cfg {Object} xgrid (xtype'd description of grid) Grid or EditorGrid
+ * @cfg {Object} xgrid (xtype'd description of grid) { xtype : 'Grid', dataSource: .... }
+ *
+ *}
*/
xgrid : false,
/**
var style = this.style;
delete this.style;
- Roo.form.DisplayImage.superclass.onRender.call(this, ct, position);
+ Roo.form.GridField.superclass.onRender.call(this, ct, position);
this.wrap = this.el.wrap({cls: ''}); // not sure why ive done thsi...
this.viewEl = this.wrap.createChild({ tag: 'div' });
if (style) {
switch(cfg.xtype)
{
case 'ContentPanel': // ContentPanel (el, cfg)
+ case 'ScrollPanel': // ContentPanel (el, cfg)
if(cfg.autoCreate) {
ret = new Roo[cfg.xtype](cfg); // new panel!!!!!
} else {
});
if(this.autoScroll){
this.resizeEl.setStyle("overflow", "auto");
+ } else {
+ // fix randome scrolling
+ this.el.on('scroll', function() {
+ this.scrollTo('top',0);
+ });
}
content = content || this.content;
if(content){
}
*/
+
Roo.NestedLayoutPanel.superclass.constructor.call(this, layout.getEl(), config);
layout.monitorWindowResize = false; // turn off autosizing
+
};
Roo.extend(Roo.NestedLayoutPanel, Roo.ContentPanel, {
}
/** @private */
this.addEvents({
- // raw events
- /**
- * @event click
- * The raw click event for the entire grid.
- * @param {Roo.EventObject} e
- */
- "click" : true,
- /**
- * @event dblclick
- * The raw dblclick event for the entire grid.
- * @param {Roo.EventObject} e
- */
- "dblclick" : true,
- /**
- * @event contextmenu
- * The raw contextmenu event for the entire grid.
- * @param {Roo.EventObject} e
- */
- "contextmenu" : true,
- /**
- * @event mousedown
- * The raw mousedown event for the entire grid.
- * @param {Roo.EventObject} e
- */
- "mousedown" : true,
- /**
- * @event mouseup
- * The raw mouseup event for the entire grid.
- * @param {Roo.EventObject} e
- */
- "mouseup" : true,
- /**
- * @event mouseover
- * The raw mouseover event for the entire grid.
- * @param {Roo.EventObject} e
- */
- "mouseover" : true,
- /**
- * @event mouseout
- * The raw mouseout event for the entire grid.
- * @param {Roo.EventObject} e
- */
- "mouseout" : true,
- /**
- * @event keypress
- * The raw keypress event for the entire grid.
- * @param {Roo.EventObject} e
- */
- "keypress" : true,
- /**
- * @event keydown
- * The raw keydown event for the entire grid.
- * @param {Roo.EventObject} e
- */
- "keydown" : true,
+ // raw events
+ /**
+ * @event click
+ * The raw click event for the entire grid.
+ * @param {Roo.EventObject} e
+ */
+ "click" : true,
+ /**
+ * @event dblclick
+ * The raw dblclick event for the entire grid.
+ * @param {Roo.EventObject} e
+ */
+ "dblclick" : true,
+ /**
+ * @event contextmenu
+ * The raw contextmenu event for the entire grid.
+ * @param {Roo.EventObject} e
+ */
+ "contextmenu" : true,
+ /**
+ * @event mousedown
+ * The raw mousedown event for the entire grid.
+ * @param {Roo.EventObject} e
+ */
+ "mousedown" : true,
+ /**
+ * @event mouseup
+ * The raw mouseup event for the entire grid.
+ * @param {Roo.EventObject} e
+ */
+ "mouseup" : true,
+ /**
+ * @event mouseover
+ * The raw mouseover event for the entire grid.
+ * @param {Roo.EventObject} e
+ */
+ "mouseover" : true,
+ /**
+ * @event mouseout
+ * The raw mouseout event for the entire grid.
+ * @param {Roo.EventObject} e
+ */
+ "mouseout" : true,
+ /**
+ * @event keypress
+ * The raw keypress event for the entire grid.
+ * @param {Roo.EventObject} e
+ */
+ "keypress" : true,
+ /**
+ * @event keydown
+ * The raw keydown event for the entire grid.
+ * @param {Roo.EventObject} e
+ */
+ "keydown" : true,
- // custom events
+ // custom events
- /**
- * @event cellclick
- * Fires when a cell is clicked
- * @param {Grid} this
- * @param {Number} rowIndex
- * @param {Number} columnIndex
- * @param {Roo.EventObject} e
- */
- "cellclick" : true,
- /**
- * @event celldblclick
- * Fires when a cell is double clicked
- * @param {Grid} this
- * @param {Number} rowIndex
- * @param {Number} columnIndex
- * @param {Roo.EventObject} e
- */
- "celldblclick" : true,
- /**
- * @event rowclick
- * Fires when a row is clicked
- * @param {Grid} this
- * @param {Number} rowIndex
- * @param {Roo.EventObject} e
- */
- "rowclick" : true,
- /**
- * @event rowdblclick
- * Fires when a row is double clicked
- * @param {Grid} this
- * @param {Number} rowIndex
- * @param {Roo.EventObject} e
- */
- "rowdblclick" : true,
- /**
- * @event headerclick
- * Fires when a header is clicked
- * @param {Grid} this
- * @param {Number} columnIndex
- * @param {Roo.EventObject} e
- */
- "headerclick" : true,
- /**
- * @event headerdblclick
- * Fires when a header cell is double clicked
- * @param {Grid} this
- * @param {Number} columnIndex
- * @param {Roo.EventObject} e
- */
- "headerdblclick" : true,
- /**
- * @event rowcontextmenu
- * Fires when a row is right clicked
- * @param {Grid} this
- * @param {Number} rowIndex
- * @param {Roo.EventObject} e
- */
- "rowcontextmenu" : true,
- /**
+ /**
+ * @event cellclick
+ * Fires when a cell is clicked
+ * @param {Grid} this
+ * @param {Number} rowIndex
+ * @param {Number} columnIndex
+ * @param {Roo.EventObject} e
+ */
+ "cellclick" : true,
+ /**
+ * @event celldblclick
+ * Fires when a cell is double clicked
+ * @param {Grid} this
+ * @param {Number} rowIndex
+ * @param {Number} columnIndex
+ * @param {Roo.EventObject} e
+ */
+ "celldblclick" : true,
+ /**
+ * @event rowclick
+ * Fires when a row is clicked
+ * @param {Grid} this
+ * @param {Number} rowIndex
+ * @param {Roo.EventObject} e
+ */
+ "rowclick" : true,
+ /**
+ * @event rowdblclick
+ * Fires when a row is double clicked
+ * @param {Grid} this
+ * @param {Number} rowIndex
+ * @param {Roo.EventObject} e
+ */
+ "rowdblclick" : true,
+ /**
+ * @event headerclick
+ * Fires when a header is clicked
+ * @param {Grid} this
+ * @param {Number} columnIndex
+ * @param {Roo.EventObject} e
+ */
+ "headerclick" : true,
+ /**
+ * @event headerdblclick
+ * Fires when a header cell is double clicked
+ * @param {Grid} this
+ * @param {Number} columnIndex
+ * @param {Roo.EventObject} e
+ */
+ "headerdblclick" : true,
+ /**
+ * @event rowcontextmenu
+ * Fires when a row is right clicked
+ * @param {Grid} this
+ * @param {Number} rowIndex
+ * @param {Roo.EventObject} e
+ */
+ "rowcontextmenu" : true,
+ /**
* @event cellcontextmenu
* Fires when a cell is right clicked
* @param {Grid} this
* @param {Roo.EventObject} e
*/
"cellcontextmenu" : true,
- /**
- * @event headercontextmenu
- * Fires when a header is right clicked
- * @param {Grid} this
- * @param {Number} columnIndex
- * @param {Roo.EventObject} e
- */
- "headercontextmenu" : true,
- /**
- * @event bodyscroll
- * Fires when the body element is scrolled
- * @param {Number} scrollLeft
- * @param {Number} scrollTop
- */
- "bodyscroll" : true,
- /**
- * @event columnresize
- * Fires when the user resizes a column
- * @param {Number} columnIndex
- * @param {Number} newSize
- */
- "columnresize" : true,
- /**
- * @event columnmove
- * Fires when the user moves a column
- * @param {Number} oldIndex
- * @param {Number} newIndex
- */
- "columnmove" : true,
- /**
- * @event startdrag
- * Fires when row(s) start being dragged
- * @param {Grid} this
- * @param {Roo.GridDD} dd The drag drop object
- * @param {event} e The raw browser event
- */
- "startdrag" : true,
- /**
- * @event enddrag
- * Fires when a drag operation is complete
- * @param {Grid} this
- * @param {Roo.GridDD} dd The drag drop object
- * @param {event} e The raw browser event
- */
- "enddrag" : true,
- /**
- * @event dragdrop
- * Fires when dragged row(s) are dropped on a valid DD target
- * @param {Grid} this
- * @param {Roo.GridDD} dd The drag drop object
- * @param {String} targetId The target drag drop object
- * @param {event} e The raw browser event
- */
- "dragdrop" : true,
- /**
- * @event dragover
- * Fires while row(s) are being dragged. "targetId" is the id of the Yahoo.util.DD object the selected rows are being dragged over.
- * @param {Grid} this
- * @param {Roo.GridDD} dd The drag drop object
- * @param {String} targetId The target drag drop object
- * @param {event} e The raw browser event
- */
- "dragover" : true,
- /**
- * @event dragenter
- * Fires when the dragged row(s) first cross another DD target while being dragged
- * @param {Grid} this
- * @param {Roo.GridDD} dd The drag drop object
- * @param {String} targetId The target drag drop object
- * @param {event} e The raw browser event
- */
- "dragenter" : true,
- /**
- * @event dragout
- * Fires when the dragged row(s) leave another DD target while being dragged
- * @param {Grid} this
- * @param {Roo.GridDD} dd The drag drop object
- * @param {String} targetId The target drag drop object
- * @param {event} e The raw browser event
- */
- "dragout" : true,
+ /**
+ * @event headercontextmenu
+ * Fires when a header is right clicked
+ * @param {Grid} this
+ * @param {Number} columnIndex
+ * @param {Roo.EventObject} e
+ */
+ "headercontextmenu" : true,
+ /**
+ * @event bodyscroll
+ * Fires when the body element is scrolled
+ * @param {Number} scrollLeft
+ * @param {Number} scrollTop
+ */
+ "bodyscroll" : true,
+ /**
+ * @event columnresize
+ * Fires when the user resizes a column
+ * @param {Number} columnIndex
+ * @param {Number} newSize
+ */
+ "columnresize" : true,
+ /**
+ * @event columnmove
+ * Fires when the user moves a column
+ * @param {Number} oldIndex
+ * @param {Number} newIndex
+ */
+ "columnmove" : true,
+ /**
+ * @event startdrag
+ * Fires when row(s) start being dragged
+ * @param {Grid} this
+ * @param {Roo.GridDD} dd The drag drop object
+ * @param {event} e The raw browser event
+ */
+ "startdrag" : true,
+ /**
+ * @event enddrag
+ * Fires when a drag operation is complete
+ * @param {Grid} this
+ * @param {Roo.GridDD} dd The drag drop object
+ * @param {event} e The raw browser event
+ */
+ "enddrag" : true,
+ /**
+ * @event dragdrop
+ * Fires when dragged row(s) are dropped on a valid DD target
+ * @param {Grid} this
+ * @param {Roo.GridDD} dd The drag drop object
+ * @param {String} targetId The target drag drop object
+ * @param {event} e The raw browser event
+ */
+ "dragdrop" : true,
+ /**
+ * @event dragover
+ * Fires while row(s) are being dragged. "targetId" is the id of the Yahoo.util.DD object the selected rows are being dragged over.
+ * @param {Grid} this
+ * @param {Roo.GridDD} dd The drag drop object
+ * @param {String} targetId The target drag drop object
+ * @param {event} e The raw browser event
+ */
+ "dragover" : true,
+ /**
+ * @event dragenter
+ * Fires when the dragged row(s) first cross another DD target while being dragged
+ * @param {Grid} this
+ * @param {Roo.GridDD} dd The drag drop object
+ * @param {String} targetId The target drag drop object
+ * @param {event} e The raw browser event
+ */
+ "dragenter" : true,
+ /**
+ * @event dragout
+ * Fires when the dragged row(s) leave another DD target while being dragged
+ * @param {Grid} this
+ * @param {Roo.GridDD} dd The drag drop object
+ * @param {String} targetId The target drag drop object
+ * @param {event} e The raw browser event
+ */
+ "dragout" : true,
+ /**
+ * @event rowclass
+ * Fires when a row is rendered, so you can change add a style to it.
+ * @param {GridView} gridview The grid view
+ * @param {Object} rowcfg contains record, rowIndex and rowClass - set rowClass to add a style.
+ */
+ 'rowclass' : true,
+
/**
* @event render
* Fires when the grid is rendered
* @param {Grid} grid
*/
- render : true
+ 'render' : true
});
Roo.grid.Grid.superclass.constructor.call(this);
* @cfg {Object} loadMask An {@link Roo.LoadMask} config or true to mask the grid while loading. Default is false.
*/
loadMask : false,
-
+ /**
+ * @cfg {Roo.dd.DropTarget} dragTarget An {@link Roo.dd.DragTarget} config
+ */
+ dropTarget: false,
// private
rendered : false,
this.footer.container = this.getView().getFooterPanel(true);
this.footer = Roo.factory(this.footer, Roo);
}
+ if (this.dropTarget && this.dropTarget.xtype) {
+ delete this.dropTarget.xtype;
+ this.dropTarget = new Ext.dd.DropTarget(this.getView().mainBody, this.dropTarget);
+ }
+
+
this.rendered = true;
this.fireEvent('render', this);
return this;
var ts = this.templates, ct = ts.cell, rt = ts.row;
// buffers
var buf = "", lbuf = "", cb, lcb, c, p = {}, rp = {}, r, rowIndex;
+
+ var hasListener = this.grid.hasListener('rowclass');
+ var rowcfg = {};
for(var j = 0, len = rs.length; j < len; j++){
r = rs[j]; cb = ""; lcb = ""; rowIndex = (j+startRow);
for(var i = 0; i < colCount; i++){
}
var alt = [];
if(stripe && ((rowIndex+1) % 2 == 0)){
- alt[0] = "x-grid-row-alt";
+ alt.push("x-grid-row-alt")
}
if(r.dirty){
- alt[1] = " x-grid-dirty-row";
+ alt.push( " x-grid-dirty-row");
}
rp.cells = lcb;
if(this.getRowClass){
- alt[2] = this.getRowClass(r, rowIndex);
+ alt.push(this.getRowClass(r, rowIndex));
+ }
+ if (hasListener) {
+ rowcfg = {
+
+ record: r,
+ rowIndex : rowIndex,
+ rowClass : ''
+ }
+ this.grid.fireEvent('rowclass', this, rowcfg);
+ alt.push(rowcfg.rowClass);
}
rp.alt = alt.join(" ");
lbuf+= rt.apply(rp);
var ts = this.templates, ct = ts.cell, rt = ts.row;
// buffers
var buf = [], lbuf = [], cb, lcb, c, p = {}, rp = {}, r, rowIndex;
+ var hasListener = this.grid.hasListener('rowclass');
+ var rowcfg = {};
for(var j = 0, len = rs.length; j < len; j++){
r = rs[j]; cb = []; lcb = []; rowIndex = (j+startRow);
for(var i = 0; i < colCount; i++){
}
var alt = [];
if(stripe && ((rowIndex+1) % 2 == 0)){
- alt[0] = "x-grid-row-alt";
+ alt.push( "x-grid-row-alt");
}
if(r.dirty){
- alt[1] = " x-grid-dirty-row";
+ alt.push(" x-grid-dirty-row");
}
rp.cells = lcb;
if(this.getRowClass){
- alt[2] = this.getRowClass(r, rowIndex);
+ alt.push( this.getRowClass(r, rowIndex));
+ }
+ if (hasListener) {
+ rowcfg = {
+
+ record: r,
+ rowIndex : rowIndex,
+ rowClass : ''
+ }
+ this.grid.fireEvent('rowclass', this, rowcfg);
+ alt.push(rowcfg.rowClass);
}
rp.alt = alt.join(" ");
rp.cells = lcb.join("");
this.grid.getGridEl().dom.innerHTML = html;
this.initElements();
+
+ // a kludge to fix the random scolling effect in webkit
+ this.el.on("scroll", function() {
+ this.el.dom.scrollTop=0; // hopefully not recursive..
+ },this);
this.scroller.on("scroll", this.handleScroll, this);
this.lockedBody.on("mousewheel", this.handleWheel, this);
if(this.fireEvent("validateedit", e) !== false && !e.cancel){
r.set(field, e.value);
+ // if we are dealing with a combo box..
+ // then we also set the 'name' colum to be the displayField
+ if (ed.field.displayField && ed.field.name) {
+ r.set(ed.field.name, ed.field.el.dom.value);
+ }
+
delete e.cancel; //?? why!!!
this.fireEvent("afteredit", e);
}
} else {
- this.fireEvent("afteredit", e); // always fir it!
+ this.fireEvent("afteredit", e); // always fire it!
}
this.view.focusCell(ed.row, ed.col);
},
this.activeEditor = ed;
var v = r.data[field];
ed.startEdit(this.view.getCell(row, col), v);
+ // combo's with 'displayField and name set
+ if (ed.field.displayField && ed.field.name) {
+ ed.field.el.dom.value = r.data[ed.field.name];
+ }
+
+
}).defer(50, this);
}
}