Ext.define('Ext.form.Basic', {
extend: 'Ext.util.Observable',
alternateClassName: 'Ext.form.BasicForm',
requires: ['Ext.util.MixedCollection', 'Ext.form.action.Load', 'Ext.form.action.Submit',
'Ext.window.MessageBox', 'Ext.data.Errors', 'Ext.util.DelayedTask'],
constructor: function(owner, config) {
var me = this,
onItemAddOrRemove = me.onItemAddOrRemove,
api,
fn;
me.owner = owner;
me.mon(owner, {
add: onItemAddOrRemove,
remove: onItemAddOrRemove,
scope: me
});
Ext.apply(me, config);
if (Ext.isString(me.paramOrder)) {
me.paramOrder = me.paramOrder.split(/[\s,|]/);
}
if (me.api) {
api = me.api = Ext.apply({}, me.api);
for (fn in api) {
if (api.hasOwnProperty(fn)) {
api[fn] = Ext.direct.Manager.parseMethod(api[fn]);
}
}
}
me.checkValidityTask = new Ext.util.DelayedTask(me.checkValidity, me);
me.addEvents(
'beforeaction',
'actionfailed',
'actioncomplete',
'validitychange',
'dirtychange'
);
me.callParent();
},
initialize : function() {
var me = this;
me.initialized = true;
me.onValidityChange(!me.hasInvalidField());
},
timeout: 30,
paramsAsHash: false,
waitTitle: 'Please Wait...',
trackResetOnLoad: false,
wasDirty: false,
destroy: function() {
this.clearListeners();
this.checkValidityTask.cancel();
},
onItemAddOrRemove: function(parent, child) {
var me = this,
isAdding = !!child.ownerCt,
isContainer = child.isContainer;
function handleField(field) {
me[isAdding ? 'mon' : 'mun'](field, {
validitychange: me.checkValidity,
dirtychange: me.checkDirty,
scope: me,
buffer: 100
});
delete me._fields;
}
if (child.isFormField) {
handleField(child);
} else if (isContainer) {
if (child.isDestroyed || child.destroying) {
delete me._fields;
} else {
Ext.Array.forEach(child.query('[isFormField]'), handleField);
}
}
delete this._boundItems;
if (me.initialized) {
me.checkValidityTask.delay(10);
}
},
getFields: function() {
var fields = this._fields;
if (!fields) {
fields = this._fields = new Ext.util.MixedCollection();
fields.addAll(this.owner.query('[isFormField]'));
}
return fields;
},
getBoundItems: function() {
var boundItems = this._boundItems;
if (!boundItems || boundItems.getCount() === 0) {
boundItems = this._boundItems = new Ext.util.MixedCollection();
boundItems.addAll(this.owner.query('[formBind]'));
}
return boundItems;
},
hasInvalidField: function() {
return !!this.getFields().findBy(function(field) {
var preventMark = field.preventMark,
isValid;
field.preventMark = true;
isValid = field.isValid();
field.preventMark = preventMark;
return !isValid;
});
},
isValid: function() {
var me = this,
invalid;
Ext.suspendLayouts();
invalid = me.getFields().filterBy(function(field) {
return !field.validate();
});
Ext.resumeLayouts(true);
return invalid.length < 1;
},
checkValidity: function() {
var me = this,
valid = !me.hasInvalidField();
if (valid !== me.wasValid) {
me.onValidityChange(valid);
me.fireEvent('validitychange', me, valid);
me.wasValid = valid;
}
},
onValidityChange: function(valid) {
var boundItems = this.getBoundItems(),
items, i, iLen, cmp;
if (boundItems) {
items = boundItems.items;
iLen = items.length;
for (i = 0; i < iLen; i++) {
cmp = items[i];
if (cmp.disabled === valid) {
cmp.setDisabled(!valid);
}
}
}
},
isDirty: function() {
return !!this.getFields().findBy(function(f) {
return f.isDirty();
});
},
checkDirty: function() {
var dirty = this.isDirty();
if (dirty !== this.wasDirty) {
this.fireEvent('dirtychange', this, dirty);
this.wasDirty = dirty;
}
},
hasUpload: function() {
return !!this.getFields().findBy(function(f) {
return f.isFileUpload();
});
},
doAction: function(action, options) {
if (Ext.isString(action)) {
action = Ext.ClassManager.instantiateByAlias('formaction.' + action, Ext.apply({}, options, {form: this}));
}
if (this.fireEvent('beforeaction', this, action) !== false) {
this.beforeAction(action);
Ext.defer(action.run, 100, action);
}
return this;
},
submit: function(options) {
options = options || {};
var me = this,
action;
if (options.standardSubmit || me.standardSubmit) {
action = 'standardsubmit';
} else {
action = me.api ? 'directsubmit' : 'submit';
}
return me.doAction(action, options);
},
load: function(options) {
return this.doAction(this.api ? 'directload' : 'load', options);
},
updateRecord: function(record) {
record = record || this._record;
if (!record) {
Ext.Error.raise("A record is required.");
}
var fields = record.fields.items,
values = this.getFieldValues(),
obj = {},
i = 0,
len = fields.length,
name;
for (; i < len; ++i) {
name = fields[i].name;
if (values.hasOwnProperty(name)) {
obj[name] = values[name];
}
}
record.beginEdit();
record.set(obj);
record.endEdit();
return this;
},
loadRecord: function(record) {
this._record = record;
return this.setValues(record.data);
},
getRecord: function() {
return this._record;
},
beforeAction: function(action) {
var waitMsg = action.waitMsg,
maskCls = Ext.baseCSSPrefix + 'mask-loading',
fields = this.getFields().items,
f,
fLen = fields.length,
field, waitMsgTarget;
for (f = 0; f < fLen; f++) {
field = fields[f];
if (field.isFormField && field.syncValue) {
field.syncValue();
}
}
if (waitMsg) {
waitMsgTarget = this.waitMsgTarget;
if (waitMsgTarget === true) {
this.owner.el.mask(waitMsg, maskCls);
} else if (waitMsgTarget) {
waitMsgTarget = this.waitMsgTarget = Ext.get(waitMsgTarget);
waitMsgTarget.mask(waitMsg, maskCls);
} else {
Ext.MessageBox.wait(waitMsg, action.waitTitle || this.waitTitle);
}
}
},
afterAction: function(action, success) {
if (action.waitMsg) {
var messageBox = Ext.MessageBox,
waitMsgTarget = this.waitMsgTarget;
if (waitMsgTarget === true) {
this.owner.el.unmask();
} else if (waitMsgTarget) {
waitMsgTarget.unmask();
} else {
messageBox.suspendEvents();
messageBox.hide();
messageBox.resumeEvents();
}
}
if (success) {
if (action.reset) {
this.reset();
}
Ext.callback(action.success, action.scope || action, [this, action]);
this.fireEvent('actioncomplete', this, action);
} else {
Ext.callback(action.failure, action.scope || action, [this, action]);
this.fireEvent('actionfailed', this, action);
}
},
findField: function(id) {
return this.getFields().findBy(function(f) {
return f.id === id || f.getName() === id;
});
},
markInvalid: function(errors) {
var me = this,
e, eLen, error, value,
key;
function mark(fieldId, msg) {
var field = me.findField(fieldId);
if (field) {
field.markInvalid(msg);
}
}
if (Ext.isArray(errors)) {
eLen = errors.length;
for (e = 0; e < eLen; e++) {
error = errors[e];
mark(error.id, error.msg);
}
} else if (errors instanceof Ext.data.Errors) {
eLen = errors.items.length;
for (e = 0; e < eLen; e++) {
error = errors.items[e];
mark(error.field, error.message);
}
} else {
for (key in errors) {
if (errors.hasOwnProperty(key)) {
value = errors[key];
mark(key, value, errors);
}
}
}
return this;
},
setValues: function(values) {
var me = this,
v, vLen, val, field;
function setVal(fieldId, val) {
var field = me.findField(fieldId);
if (field) {
field.setValue(val);
if (me.trackResetOnLoad) {
field.resetOriginalValue();
}
}
}
if (Ext.isArray(values)) {
vLen = values.length;
for (v = 0; v < vLen; v++) {
val = values[v];
setVal(val.id, val.value);
}
} else {
Ext.iterate(values, setVal);
}
return this;
},
getValues: function(asString, dirtyOnly, includeEmptyText, useDataValues) {
var values = {},
fields = this.getFields().items,
f,
fLen = fields.length,
isArray = Ext.isArray,
field, data, val, bucket, name;
for (f = 0; f < fLen; f++) {
field = fields[f];
if (!dirtyOnly || field.isDirty()) {
data = field[useDataValues ? 'getModelData' : 'getSubmitData'](includeEmptyText);
if (Ext.isObject(data)) {
for (name in data) {
if (data.hasOwnProperty(name)) {
val = data[name];
if (includeEmptyText && val === '') {
val = field.emptyText || '';
}
if (values.hasOwnProperty(name)) {
bucket = values[name];
if (!isArray(bucket)) {
bucket = values[name] = [bucket];
}
if (isArray(val)) {
values[name] = values[name] = bucket.concat(val);
} else {
bucket.push(val);
}
} else {
values[name] = val;
}
}
}
}
}
}
if (asString) {
values = Ext.Object.toQueryString(values);
}
return values;
},
getFieldValues: function(dirtyOnly) {
return this.getValues(false, dirtyOnly, false, true);
},
clearInvalid: function() {
Ext.suspendLayouts();
var me = this,
fields = me.getFields().items,
f,
fLen = fields.length;
for (f = 0; f < fLen; f++) {
fields[f].clearInvalid();
}
Ext.resumeLayouts(true);
return me;
},
reset: function() {
Ext.suspendLayouts();
var me = this,
fields = me.getFields().items,
f,
fLen = fields.length;
for (f = 0; f < fLen; f++) {
fields[f].reset();
}
Ext.resumeLayouts(true);
return me;
},
applyToFields: function(obj) {
var fields = this.getFields().items,
f,
fLen = fields.length;
for (f = 0; f < fLen; f++) {
Ext.apply(fields[f], obj);
}
return this;
},
applyIfToFields: function(obj) {
var fields = this.getFields().items,
f,
fLen = fields.length;
for (f = 0; f < fLen; f++) {
Ext.applyIf(fields[f], obj);
}
return this;
}
});