/*!
- * Ext JS Library 3.3.0
- * Copyright(c) 2006-2010 Ext JS, Inc.
- * licensing@extjs.com
- * http://www.extjs.com/license
+ * Ext JS Library 3.3.1
+ * Copyright(c) 2006-2010 Sencha Inc.
+ * licensing@sencha.com
+ * http://www.sencha.com/license
*/
(function(){
Ext.fly(bd, '_internal').addClass(cls);
return true;
};
-
- /*
- * Assert Ext.isReady here. If Ext is loaded after the document is ready, none of the native
- * DOM onReady events will fire, because they have already passed.
- */
- Ext.isReady = initExtCss();
- if (!Ext.isReady) {
+ if (!initExtCss()) {
Ext.onReady(initExtCss);
}
})();
return new Ext.EventObjectImpl();
}();
+/**
+ * @class Ext.Loader
+ * @singleton
+ * Simple class to help load JavaScript files on demand
+ */
+Ext.Loader = Ext.apply({}, {
+ /**
+ * Loads a given set of .js files. Calls the callback function when all files have been loaded
+ * Set preserveOrder to true to ensure non-parallel loading of files if load order is important
+ * @param {Array} fileList Array of all files to load
+ * @param {Function} callback Callback to call after all files have been loaded
+ * @param {Object} scope The scope to call the callback in
+ * @param {Boolean} preserveOrder True to make files load in serial, one after the other (defaults to false)
+ */
+ load: function(fileList, callback, scope, preserveOrder) {
+ var scope = scope || this,
+ head = document.getElementsByTagName("head")[0],
+ fragment = document.createDocumentFragment(),
+ numFiles = fileList.length,
+ loadedFiles = 0,
+ me = this;
+
+ /**
+ * Loads a particular file from the fileList by index. This is used when preserving order
+ */
+ var loadFileIndex = function(index) {
+ head.appendChild(
+ me.buildScriptTag(fileList[index], onFileLoaded)
+ );
+ };
+
+ /**
+ * Callback function which is called after each file has been loaded. This calls the callback
+ * passed to load once the final file in the fileList has been loaded
+ */
+ var onFileLoaded = function() {
+ loadedFiles ++;
+
+ //if this was the last file, call the callback, otherwise load the next file
+ if (numFiles == loadedFiles && typeof callback == 'function') {
+ callback.call(scope);
+ } else {
+ if (preserveOrder === true) {
+ loadFileIndex(loadedFiles);
+ }
+ }
+ };
+
+ if (preserveOrder === true) {
+ loadFileIndex.call(this, 0);
+ } else {
+ //load each file (most browsers will do this in parallel)
+ Ext.each(fileList, function(file, index) {
+ fragment.appendChild(
+ this.buildScriptTag(file, onFileLoaded)
+ );
+ }, this);
+
+ head.appendChild(fragment);
+ }
+ },
+
+ /**
+ * @private
+ * Creates and returns a script tag, but does not place it into the document. If a callback function
+ * is passed, this is called when the script has been loaded
+ * @param {String} filename The name of the file to create a script tag for
+ * @param {Function} callback Optional callback, which is called when the script has been loaded
+ * @return {Element} The new script ta
+ */
+ buildScriptTag: function(filename, callback) {
+ var script = document.createElement('script');
+ script.type = "text/javascript";
+ script.src = filename;
+
+ //IE has a different way of handling <script> loads, so we need to check for it here
+ if (script.readyState) {
+ script.onreadystatechange = function() {
+ if (script.readyState == "loaded" || script.readyState == "complete") {
+ script.onreadystatechange = null;
+ callback();
+ }
+ };
+ } else {
+ script.onload = callback;
+ }
+
+ return script;
+ }
+});
/**
* @class Ext
*/
calc = [],
regex = [],
special = false,
- ch = "";
+ ch = "",
+ i = 0,
+ obj,
+ last;
- for (var i = 0; i < format.length; ++i) {
+ for (; i < format.length; ++i) {
ch = format.charAt(i);
if (!special && ch == "\\") {
special = true;
special = false;
regex.push(String.escape(ch));
} else {
- var obj = $f(ch, currentGroup);
+ obj = $f(ch, currentGroup);
currentGroup += obj.g;
regex.push(obj.s);
if (obj.g && obj.c) {
- calc.push(obj.c);
+ if (obj.calcLast) {
+ last = obj.c;
+ } else {
+ calc.push(obj.c);
+ }
}
}
}
+
+ if (last) {
+ calc.push(last);
+ }
Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i');
Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
* even though it doesn't exactly match the spec. It gives much more flexibility
* in being able to specify case insensitive regexes.
*/
- a: {
- g:1,
- c:"if (/(am)/i.test(results[{0}])) {\n"
- + "if (!h || h == 12) { h = 0; }\n"
- + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
- s:"(am|pm|AM|PM)"
+ a: function(){
+ return $f("A");
},
A: {
+ // We need to calculate the hour before we apply AM/PM when parsing
+ calcLast: true,
g:1,
c:"if (/(am)/i.test(results[{0}])) {\n"
+ "if (!h || h == 12) { h = 0; }\n"
c = Ext.ComponentMgr.get(c);
Ext.apply(c, d);
}else if(!c.events){
- Ext.applyIf(c, d);
+ Ext.applyIf(c.isAction ? c.initialConfig : c, d);
}else{
Ext.apply(c, d);
}
if(this.resizeTask && this.resizeTask.cancel){
this.resizeTask.cancel();
}
+ if(this.container) {
+ this.container.un(this.container.resizeEvent, this.onResize, this);
+ }
if(!Ext.isEmpty(this.targetCls)){
var target = this.container.getLayoutTarget();
if(target){
* to add to the cache. See {@link #recordType}.
*/
add : function(records) {
- var i, record, index;
+ var i, len, record, index;
records = [].concat(records);
if (records.length < 1) {
* @param {Ext.data.Record[]} records An Array of Ext.data.Record objects to add to the cache.
*/
insert : function(index, records) {
- var i, record;
+ var i, len, record;
records = [].concat(records);
for (i = 0, len = records.length; i < len; i++) {
// private
// Called as a callback by the Reader during a load operation.
loadRecords : function(o, options, success){
- var i;
+ var i, len;
if (this.isDestroyed === true) {
return;
createAccessor : function(){
var q = Ext.DomQuery;
return function(key) {
+ if (Ext.isFunction(key)) {
+ return key;
+ }
switch(key) {
case this.meta.totalProperty:
return function(root, def){
*/
groupOnSort:false,
+ /**
+ * @cfg {String} groupDir
+ * The direction to sort the groups. Defaults to <tt>'ASC'</tt>.
+ */
groupDir : 'ASC',
/**
*/
initComponent : function(){
+ if(this.menu){
+ this.menu = Ext.menu.MenuMgr.get(this.menu);
+ this.menu.ownerCt = this;
+ }
+
Ext.Button.superclass.initComponent.call(this);
this.addEvents(
*/
'menutriggerout'
);
- if(this.menu){
- this.menu = Ext.menu.MenuMgr.get(this.menu);
+
+ if (this.menu){
+ this.menu.ownerCt = undefined;
}
if(Ext.isString(this.toggleGroup)){
this.enableToggle = true;
* @static
* @type String
*/
-Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.0/build/charts/assets/charts.swf';
+Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.2/build/charts/assets/charts.swf';
/**
* @class Ext.chart.PieChart
},
// private
- assertValue : function(){
+ assertValue : function(){
var val = this.getRawValue(),
- rec = this.findRecord(this.displayField, val);
+ rec;
+ if(this.valueField && Ext.isDefined(this.value)){
+ rec = this.findRecord(this.valueField, this.value);
+ }
+ if(!rec || rec.get(this.displayField) != val){
+ rec = this.findRecord(this.displayField, val);
+ }
if(!rec && this.forceSelection){
if(val.length > 0 && val != this.emptyText){
this.el.dom.value = Ext.value(this.lastSelectionText, '');
this.clearValue();
}
}else{
- if(rec){
+ if(rec && this.valueField){
// onSelect may have already set the value and by doing so
// set the display field properly. Let's not wipe out the
// valueField here by just sending the displayField.
- if (val == rec.get(this.displayField) && this.value == rec.get(this.valueField)){
+ if (this.value == val){
return;
}
val = rec.get(this.valueField || this.displayField);
* {tag: 'input', type: 'checkbox', autocomplete: 'off'})
*/
defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'},
- /**
- * @cfg {String} boxLabel The text that appears beside the checkbox
- */
/**
* @cfg {String} inputValue The value that should go into the generated input element's value attribute
*/
for (var i=0, j = items.length; i < j; i++) {
item = items[i];
+
+ if (!Ext.isEmpty(item.ref)){
+ item.ref = '../' + item.ref;
+ }
labels.push(item.fieldLabel);
layout : 'hbox',
items : this.items,
cls : 'x-form-composite',
- defaultMargins: '0 3 0 0'
+ defaultMargins: '0 3 0 0',
+ ownerCt: this
});
+ this.innerCt.ownerCt = undefined;
var fields = this.innerCt.findBy(function(c) {
return c.isFormField;
*/
updateRecord : function(record){
record.beginEdit();
- var fs = record.fields;
+ var fs = record.fields,
+ field,
+ value;
fs.each(function(f){
- var field = this.findField(f.name);
+ field = this.findField(f.name);
if(field){
- var value = field.getValue();
- if ( value.getGroupValue ) {
+ value = field.getValue();
+ if (typeof value != undefined && value.getGroupValue) {
value = value.getGroupValue();
} else if ( field.eachItem ) {
value = [];
store = this.store,
s,
c,
- oldIndex;
+ colIndex;
if(cs){
for(var i = 0, len = cs.length; i < len; i++){
s = cs[i];
c = cm.getColumnById(s.id);
if(c){
- cm.setState(s.id, {
+ colIndex = cm.getIndexById(s.id);
+ cm.setState(colIndex, {
hidden: s.hidden,
- width: s.width
+ width: s.width,
+ sortable: s.sortable
});
- oldIndex = cm.getIndexById(s.id);
- if(oldIndex != i){
- cm.moveColumn(oldIndex, i);
+ if(colIndex != i){
+ cm.moveColumn(colIndex, i);
}
}
}
if(c.hidden){
o.columns[i].hidden = true;
}
+ if(c.sortable){
+ o.columns[i].sortable = true;
+ }
}
if(store){
ss = store.getSortState();
/**
* @cfg {Boolean} forceFit
- * Defaults to <tt>false</tt>. Specify <tt>true</tt> to have the column widths re-proportioned
- * at <b>all times</b>. The {@link Ext.grid.Column#width initially configured width}</tt> of each
+ * <p>Defaults to <tt>false</tt>. Specify <tt>true</tt> to have the column widths re-proportioned
+ * at <b>all times</b>.</p>
+ * <p>The {@link Ext.grid.Column#width initially configured width}</tt> of each
* column will be adjusted to fit the grid width and prevent horizontal scrolling. If columns are
* later resized (manually or programmatically), the other columns in the grid <b>will</b> be resized
- * to fit the grid width. See <tt>{@link #autoFill}</tt> also.
+ * to fit the grid width.</p>
+ * <p>Columns which are configured with <code>fixed: true</code> are omitted from being resized.</p>
+ * <p>See <tt>{@link #autoFill}</tt>.</p>
*/
forceFit : false,
Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
}
if (!isUpdate) {
- this.fireEvent('rowsinserted', this, firstRow, lastRow);
this.processRows(firstRow);
+ this.fireEvent('rowsinserted', this, firstRow, lastRow);
} else if (firstRow === 0 || firstRow >= last) {
//ensure first/last row is kept after an update.
Ext.fly(this.getRow(firstRow)).addClass(firstRow === 0 ? this.firstRowCls : this.lastRowCls);
s = this.getSelections(),
i = 0,
len = s.length,
- index;
+ index, r;
this.silent = true;
this.clearSelections(true);
r = newCell[0];
c = newCell[1];
- if(last.row != r){
- this.selectRow(r); // *** highlight newly-selected cell and update selection
- }
+ this.onEditorSelect(r, last.row);
if(g.isEditor && g.editing){ // *** handle tabbing while editorgrid is in edit mode
ae = g.activeEditor;
}
},
+ onEditorSelect: function(row, lastRow){
+ if(lastRow != row){
+ this.selectRow(row); // *** highlight newly-selected cell and update selection
+ }
+ },
+
destroy : function(){
Ext.destroy(this.rowNav);
this.rowNav = null;
Ext.grid.RowSelectionModel.superclass.destroy.call(this);
}
-});/**
+});
+/**
* @class Ext.grid.Column
* <p>This class encapsulates column configuration data to be used in the initialization of a
* {@link Ext.grid.ColumnModel ColumnModel}.</p>
*/
/**
* @cfg {Function} getClass A function which returns the CSS class to apply to the icon image.
- * The function is passed the following parameters:<ul>
+ * The function is passed the following parameters:<div class="mdetail-params"><ul>
* <li><b>v</b> : Object<p class="sub-desc">The value of the column's configured field (if any).</p></li>
* <li><b>metadata</b> : Object<p class="sub-desc">An object in which you may set the following attributes:<ul>
* <li><b>css</b> : String<p class="sub-desc">A CSS class name to add to the cell's TD element.</p></li>
* <li><b>rowIndex</b> : Number<p class="sub-desc">The row index..</p></li>
* <li><b>colIndex</b> : Number<p class="sub-desc">The column index.</p></li>
* <li><b>store</b> : Ext.data.Store<p class="sub-desc">The Store which is providing the data Model.</p></li>
- * </ul>
+ * </ul></div>
*/
/**
* @cfg {Array} items An Array which may contain multiple icon definitions, each element of which may contain:
// private
renderer : function(v, p, record){
return '<div class="x-grid3-row-checker"> </div>';
+ },
+
+ onEditorSelect: function(row, lastRow){
+ if(lastRow != row && !this.checkOnly){
+ this.selectRow(row); // *** highlight newly-selected cell and update selection
+ }
}
});/**
* @class Ext.grid.CellSelectionModel
// private
onGroupByClick : function(){
+ var grid = this.grid;
this.enableGrouping = true;
- this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
- this.grid.fireEvent('groupchange', this, this.grid.store.getGroupState());
+ grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
+ grid.fireEvent('groupchange', grid, grid.store.getGroupState());
this.beforeMenuShow(); // Make sure the checkboxes get properly set when changing groups
this.refresh();
},