<!DOCTYPE html>
|
<html>
|
<head>
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<title>The source code</title>
|
<link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
|
<script type="text/javascript" src="../resources/prettify/prettify.js"></script>
|
<style type="text/css">
|
.highlight { display: block; background-color: #ddd; }
|
</style>
|
<script type="text/javascript">
|
function highlight() {
|
document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
|
}
|
</script>
|
</head>
|
<body onload="prettyPrint(); highlight();">
|
<pre class="prettyprint lang-js"><span id='Ext-form-Basic'>/**
|
</span> * Provides input field management, validation, submission, and form loading services for the collection
|
* of {@link Ext.form.field.Field Field} instances within a {@link Ext.container.Container}. It is recommended
|
* that you use a {@link Ext.form.Panel} as the form container, as that has logic to automatically
|
* hook up an instance of {@link Ext.form.Basic} (plus other conveniences related to field configuration.)
|
*
|
* ## Form Actions
|
*
|
* The Basic class delegates the handling of form loads and submits to instances of {@link Ext.form.action.Action}.
|
* See the various Action implementations for specific details of each one's functionality, as well as the
|
* documentation for {@link #doAction} which details the configuration options that can be specified in
|
* each action call.
|
*
|
* The default submit Action is {@link Ext.form.action.Submit}, which uses an Ajax request to submit the
|
* form's values to a configured URL. To enable normal browser submission of an Ext form, use the
|
* {@link #standardSubmit} config option.
|
*
|
* ## File uploads
|
*
|
* File uploads are not performed using normal 'Ajax' techniques; see the description for
|
* {@link #hasUpload} for details. If you're using file uploads you should read the method description.
|
*
|
* ## Example usage:
|
*
|
* @example
|
* Ext.create('Ext.form.Panel', {
|
* title: 'Basic Form',
|
* renderTo: Ext.getBody(),
|
* bodyPadding: 5,
|
* width: 350,
|
*
|
* // Any configuration items here will be automatically passed along to
|
* // the Ext.form.Basic instance when it gets created.
|
*
|
* // The form will submit an AJAX request to this URL when submitted
|
* url: 'save-form.php',
|
*
|
* items: [{
|
* xtype: 'textfield',
|
* fieldLabel: 'Field',
|
* name: 'theField'
|
* }],
|
*
|
* buttons: [{
|
* text: 'Submit',
|
* handler: function() {
|
* // The getForm() method returns the Ext.form.Basic instance:
|
* var form = this.up('form').getForm();
|
* if (form.isValid()) {
|
* // Submit the Ajax request and handle the response
|
* form.submit({
|
* success: function(form, action) {
|
* Ext.Msg.alert('Success', action.result.message);
|
* },
|
* failure: function(form, action) {
|
* Ext.Msg.alert('Failed', action.result ? action.result.message : 'No response');
|
* }
|
* });
|
* }
|
* }
|
* }]
|
* });
|
*
|
* @docauthor Jason Johnston <jason@sencha.com>
|
*/
|
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'],
|
|
<span id='Ext-form-Basic-method-constructor'> /**
|
</span> * Creates new form.
|
* @param {Ext.container.Container} owner The component that is the container for the form, usually a {@link Ext.form.Panel}
|
* @param {Object} config Configuration options. These are normally specified in the config to the
|
* {@link Ext.form.Panel} constructor, which passes them along to the BasicForm automatically.
|
*/
|
constructor: function(owner, config) {
|
var me = this,
|
reader;
|
|
<span id='Ext-form-Basic-property-owner'> /**
|
</span> * @property {Ext.container.Container} owner
|
* The container component to which this BasicForm is attached.
|
*/
|
me.owner = owner;
|
|
me.checkValidityTask = new Ext.util.DelayedTask(me.checkValidity, me);
|
me.checkDirtyTask = new Ext.util.DelayedTask(me.checkDirty, me);
|
|
// We use the monitor here as opposed to event bubbling. The problem with bubbling is it doesn't
|
// let us react to items being added/remove at different places in the hierarchy which may have an
|
// impact on the dirty/valid state.
|
me.monitor = new Ext.container.Monitor({
|
selector: '[isFormField]',
|
scope: me,
|
addHandler: me.onFieldAdd,
|
removeHandler: me.onFieldRemove
|
});
|
me.monitor.bind(owner);
|
|
Ext.apply(me, config);
|
|
// Normalize the paramOrder to an Array
|
if (Ext.isString(me.paramOrder)) {
|
me.paramOrder = me.paramOrder.split(/[\s,|]/);
|
}
|
|
reader = me.reader;
|
if (reader && !reader.isReader) {
|
if (typeof reader === 'string') {
|
reader = {
|
type: reader
|
};
|
}
|
me.reader = Ext.createByAlias('reader.' + reader.type, reader);
|
}
|
|
reader = me.errorReader;
|
if (reader && !reader.isReader) {
|
if (typeof reader === 'string') {
|
reader = {
|
type: reader
|
};
|
}
|
me.errorReader = Ext.createByAlias('reader.' + reader.type, reader);
|
}
|
|
me.addEvents(
|
<span id='Ext-form-Basic-event-beforeaction'> /**
|
</span> * @event beforeaction
|
* Fires before any action is performed. Return false to cancel the action.
|
* @param {Ext.form.Basic} this
|
* @param {Ext.form.action.Action} action The {@link Ext.form.action.Action} to be performed
|
*/
|
'beforeaction',
|
<span id='Ext-form-Basic-event-actionfailed'> /**
|
</span> * @event actionfailed
|
* Fires when an action fails.
|
* @param {Ext.form.Basic} this
|
* @param {Ext.form.action.Action} action The {@link Ext.form.action.Action} that failed
|
*/
|
'actionfailed',
|
<span id='Ext-form-Basic-event-actioncomplete'> /**
|
</span> * @event actioncomplete
|
* Fires when an action is completed.
|
* @param {Ext.form.Basic} this
|
* @param {Ext.form.action.Action} action The {@link Ext.form.action.Action} that completed
|
*/
|
'actioncomplete',
|
<span id='Ext-form-Basic-event-validitychange'> /**
|
</span> * @event validitychange
|
* Fires when the validity of the entire form changes.
|
* @param {Ext.form.Basic} this
|
* @param {Boolean} valid `true` if the form is now valid, `false` if it is now invalid.
|
*/
|
'validitychange',
|
<span id='Ext-form-Basic-event-dirtychange'> /**
|
</span> * @event dirtychange
|
* Fires when the dirty state of the entire form changes.
|
* @param {Ext.form.Basic} this
|
* @param {Boolean} dirty `true` if the form is now dirty, `false` if it is no longer dirty.
|
*/
|
'dirtychange'
|
);
|
me.callParent();
|
},
|
|
<span id='Ext-form-Basic-method-initialize'> /**
|
</span> * Do any post layout initialization
|
* @private
|
*/
|
initialize : function() {
|
this.initialized = true;
|
this.onValidityChange(!this.hasInvalidField());
|
},
|
|
|
<span id='Ext-form-Basic-cfg-method'> /**
|
</span> * @cfg {String} method
|
* The request method to use (GET or POST) for form actions if one isn't supplied in the action options.
|
*/
|
|
<span id='Ext-form-Basic-cfg-reader'> /**
|
</span> * @cfg {Object/Ext.data.reader.Reader} reader
|
* An Ext.data.reader.Reader (e.g. {@link Ext.data.reader.Xml}) instance or
|
* configuration to be used to read data when executing 'load' actions. This
|
* is optional as there is built-in support for processing JSON responses.
|
*/
|
|
<span id='Ext-form-Basic-cfg-errorReader'> /**
|
</span> * @cfg {Object/Ext.data.reader.Reader} errorReader
|
* An Ext.data.reader.Reader (e.g. {@link Ext.data.reader.Xml}) instance or
|
* configuration to be used to read field error messages returned from 'submit' actions.
|
* This is optional as there is built-in support for processing JSON responses.
|
*
|
* The Records which provide messages for the invalid Fields must use the
|
* Field name (or id) as the Record ID, and must contain a field called 'msg'
|
* which contains the error message.
|
*
|
* The errorReader does not have to be a full-blown implementation of a
|
* Reader. It simply needs to implement a `read(xhr)` function
|
* which returns an Array of Records in an object with the following
|
* structure:
|
*
|
* {
|
* records: recordArray
|
* }
|
*/
|
|
<span id='Ext-form-Basic-cfg-url'> /**
|
</span> * @cfg {String} url
|
* The URL to use for form actions if one isn't supplied in the
|
* {@link #doAction doAction} options.
|
*/
|
|
<span id='Ext-form-Basic-cfg-baseParams'> /**
|
</span> * @cfg {Object} baseParams
|
* Parameters to pass with all requests. e.g. baseParams: `{id: '123', foo: 'bar'}`.
|
*
|
* Parameters are encoded as standard HTTP parameters using {@link Ext.Object#toQueryString}.
|
*/
|
|
<span id='Ext-form-Basic-cfg-timeout'> /**
|
</span> * @cfg {Number} timeout
|
* Timeout for form actions in seconds.
|
*/
|
timeout: 30,
|
|
<span id='Ext-form-Basic-cfg-api'> /**
|
</span> * @cfg {Object} api
|
* If specified, load and submit actions will be handled with {@link Ext.form.action.DirectLoad DirectLoad}
|
* and {@link Ext.form.action.DirectSubmit DirectSubmit}. Methods which have been imported by
|
* {@link Ext.direct.Manager} can be specified here to load and submit forms. API methods may also be
|
* specified as strings. See {@link Ext.data.proxy.Direct#directFn}. Such as the following:
|
*
|
* api: {
|
* load: App.ss.MyProfile.load,
|
* submit: App.ss.MyProfile.submit
|
* }
|
*
|
* Load actions can use {@link #paramOrder} or {@link #paramsAsHash} to customize how the load method
|
* is invoked. Submit actions will always use a standard form submit. The `formHandler` configuration
|
* (see Ext.direct.RemotingProvider#action) must be set on the associated server-side method which has
|
* been imported by {@link Ext.direct.Manager}.
|
*/
|
|
<span id='Ext-form-Basic-cfg-paramOrder'> /**
|
</span> * @cfg {String/String[]} paramOrder
|
* A list of params to be executed server side. Only used for the {@link #api} `load`
|
* configuration.
|
*
|
* Specify the params in the order in which they must be executed on the
|
* server-side as either (1) an Array of String values, or (2) a String of params
|
* delimited by either whitespace, comma, or pipe. For example,
|
* any of the following would be acceptable:
|
*
|
* paramOrder: ['param1','param2','param3']
|
* paramOrder: 'param1 param2 param3'
|
* paramOrder: 'param1,param2,param3'
|
* paramOrder: 'param1|param2|param'
|
*/
|
|
<span id='Ext-form-Basic-cfg-paramsAsHash'> /**
|
</span> * @cfg {Boolean} paramsAsHash
|
* Only used for the {@link #api} `load` configuration. If true, parameters will be sent as a
|
* single hash collection of named arguments. Providing a {@link #paramOrder} nullifies this
|
* configuration.
|
*/
|
paramsAsHash: false,
|
|
//<locale>
|
<span id='Ext-form-Basic-cfg-waitTitle'> /**
|
</span> * @cfg {String} waitTitle
|
* The default title to show for the waiting message box
|
*/
|
waitTitle: 'Please Wait...',
|
//</locale>
|
|
<span id='Ext-form-Basic-cfg-trackResetOnLoad'> /**
|
</span> * @cfg {Boolean} trackResetOnLoad
|
* If set to true, {@link #reset}() resets to the last loaded or {@link #setValues}() data instead of
|
* when the form was first created.
|
*/
|
trackResetOnLoad: false,
|
|
<span id='Ext-form-Basic-cfg-standardSubmit'> /**
|
</span> * @cfg {Boolean} standardSubmit
|
* If set to true, a standard HTML form submit is used instead of a XHR (Ajax) style form submission.
|
* All of the field values, plus any additional params configured via {@link #baseParams}
|
* and/or the `options` to {@link #submit}, will be included in the values submitted in the form.
|
*/
|
|
<span id='Ext-form-Basic-cfg-jsonSubmit'> /**
|
</span> * @cfg {Boolean} jsonSubmit
|
* If set to true, the field values are sent as JSON in the request body.
|
* All of the field values, plus any additional params configured via {@link #baseParams}
|
* and/or the `options` to {@link #submit}, will be included in the values POSTed in the body of the request.
|
*/
|
|
<span id='Ext-form-Basic-cfg-waitMsgTarget'> /**
|
</span> * @cfg {String/HTMLElement/Ext.Element} waitMsgTarget
|
* By default wait messages are displayed with Ext.MessageBox.wait. You can target a specific
|
* element by passing it or its id or mask the form itself by passing in true.
|
*/
|
|
|
<span id='Ext-form-Basic-property-wasDirty'> // Private
|
</span> wasDirty: false,
|
|
|
<span id='Ext-form-Basic-method-destroy'> /**
|
</span> * Destroys this object.
|
*/
|
destroy: function() {
|
var me = this,
|
mon = me.monitor;
|
|
if (mon) {
|
mon.unbind();
|
me.monitor = null;
|
}
|
me.clearListeners();
|
me.checkValidityTask.cancel();
|
me.checkDirtyTask.cancel();
|
},
|
|
<span id='Ext-form-Basic-method-onFieldAdd'> onFieldAdd: function(field){
|
</span> var me = this;
|
|
me.mon(field, 'validitychange', me.checkValidityDelay, me);
|
me.mon(field, 'dirtychange', me.checkDirtyDelay, me);
|
if (me.initialized) {
|
me.checkValidityDelay();
|
}
|
},
|
|
<span id='Ext-form-Basic-method-onFieldRemove'> onFieldRemove: function(field){
|
</span> var me = this;
|
|
me.mun(field, 'validitychange', me.checkValidityDelay, me);
|
me.mun(field, 'dirtychange', me.checkDirtyDelay, me);
|
if (me.initialized) {
|
me.checkValidityDelay();
|
}
|
},
|
|
<span id='Ext-form-Basic-method-getFields'> /**
|
</span> * Return all the {@link Ext.form.field.Field} components in the owner container.
|
* @return {Ext.util.MixedCollection} Collection of the Field objects
|
*/
|
getFields: function() {
|
return this.monitor.getItems();
|
},
|
|
<span id='Ext-form-Basic-method-getBoundItems'> /**
|
</span> * @private
|
* Finds and returns the set of all items bound to fields inside this form
|
* @return {Ext.util.MixedCollection} The set of all bound form field items
|
*/
|
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;
|
},
|
|
<span id='Ext-form-Basic-method-hasInvalidField'> /**
|
</span> * Returns true if the form contains any invalid fields. No fields will be marked as invalid
|
* as a result of calling this; to trigger marking of fields use {@link #isValid} instead.
|
*/
|
hasInvalidField: function() {
|
return !!this.getFields().findBy(function(field) {
|
var preventMark = field.preventMark,
|
isValid;
|
field.preventMark = true;
|
isValid = field.isValid();
|
field.preventMark = preventMark;
|
return !isValid;
|
});
|
},
|
|
<span id='Ext-form-Basic-method-isValid'> /**
|
</span> * Returns true if client-side validation on the form is successful. Any invalid fields will be
|
* marked as invalid. If you only want to determine overall form validity without marking anything,
|
* use {@link #hasInvalidField} instead.
|
* @return {Boolean}
|
*/
|
isValid: function() {
|
var me = this,
|
invalid;
|
Ext.suspendLayouts();
|
invalid = me.getFields().filterBy(function(field) {
|
return !field.validate();
|
});
|
Ext.resumeLayouts(true);
|
return invalid.length < 1;
|
},
|
|
<span id='Ext-form-Basic-method-checkValidity'> /**
|
</span> * Check whether the validity of the entire form has changed since it was last checked, and
|
* if so fire the {@link #validitychange validitychange} event. This is automatically invoked
|
* when an individual field's validity changes.
|
*/
|
checkValidity: function() {
|
var me = this,
|
valid = !me.hasInvalidField();
|
if (valid !== me.wasValid) {
|
me.onValidityChange(valid);
|
me.fireEvent('validitychange', me, valid);
|
me.wasValid = valid;
|
}
|
},
|
|
<span id='Ext-form-Basic-method-checkValidityDelay'> checkValidityDelay: function(){
|
</span> this.checkValidityTask.delay(10);
|
},
|
|
<span id='Ext-form-Basic-method-onValidityChange'> /**
|
</span> * @private
|
* Handle changes in the form's validity. If there are any sub components with
|
* `formBind=true` then they are enabled/disabled based on the new validity.
|
* @param {Boolean} 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);
|
}
|
}
|
}
|
},
|
|
<span id='Ext-form-Basic-method-isDirty'> /**
|
</span> * Returns `true` if any fields in this form have changed from their original values.
|
*
|
* Note that if this BasicForm was configured with {@link Ext.form.Basic#trackResetOnLoad
|
* trackResetOnLoad} then the Fields' *original values* are updated when the values are
|
* loaded by {@link Ext.form.Basic#setValues setValues} or {@link #loadRecord}.
|
*
|
* @return {Boolean}
|
*/
|
isDirty: function() {
|
return !!this.getFields().findBy(function(f) {
|
return f.isDirty();
|
});
|
},
|
|
<span id='Ext-form-Basic-method-checkDirtyDelay'> checkDirtyDelay: function(){
|
</span> this.checkDirtyTask.delay(10);
|
},
|
|
<span id='Ext-form-Basic-method-checkDirty'> /**
|
</span> * Check whether the dirty state of the entire form has changed since it was last checked, and
|
* if so fire the {@link #dirtychange dirtychange} event. This is automatically invoked
|
* when an individual field's `dirty` state changes.
|
*/
|
checkDirty: function() {
|
var dirty = this.isDirty();
|
if (dirty !== this.wasDirty) {
|
this.fireEvent('dirtychange', this, dirty);
|
this.wasDirty = dirty;
|
}
|
},
|
|
<span id='Ext-form-Basic-method-hasUpload'> /**
|
</span> * Returns `true` if the form contains a file upload field. This is used to determine the method for submitting the
|
* form: File uploads are not performed using normal 'Ajax' techniques, that is they are **not** performed using
|
* XMLHttpRequests. Instead a hidden `<form>` element containing all the fields is created temporarily and submitted
|
* with its [target][1] set to refer to a dynamically generated, hidden `<iframe>` which is inserted into the document
|
* but removed after the return data has been gathered.
|
*
|
* The server response is parsed by the browser to create the document for the IFRAME. If the server is using JSON
|
* to send the return object, then the [Content-Type][2] header must be set to "text/html" in order to tell the
|
* browser to insert the text unchanged into the document body.
|
*
|
* Characters which are significant to an HTML parser must be sent as HTML entities, so encode `"<"` as `"&lt;"`,
|
* `"&"` as `"&amp;"` etc.
|
*
|
* The response text is retrieved from the document, and a fake XMLHttpRequest object is created containing a
|
* responseText property in order to conform to the requirements of event handlers and callbacks.
|
*
|
* Be aware that file upload packets are sent with the content type [multipart/form][3] and some server technologies
|
* (notably JEE) may require some custom processing in order to retrieve parameter names and parameter values from
|
* the packet content.
|
*
|
* [1]: http://www.w3.org/TR/REC-html40/present/frames.html#adef-target
|
* [2]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.17
|
* [3]: http://www.faqs.org/rfcs/rfc2388.html
|
*
|
* @return {Boolean}
|
*/
|
hasUpload: function() {
|
return !!this.getFields().findBy(function(f) {
|
return f.isFileUpload();
|
});
|
},
|
|
<span id='Ext-form-Basic-method-doAction'> /**
|
</span> * Performs a predefined action (an implementation of {@link Ext.form.action.Action}) to perform application-
|
* specific processing.
|
*
|
* @param {String/Ext.form.action.Action} action The name of the predefined action type, or instance of {@link
|
* Ext.form.action.Action} to perform.
|
*
|
* @param {Object} [options] The options to pass to the {@link Ext.form.action.Action} that will get created,
|
* if the action argument is a String.
|
*
|
* All of the config options listed below are supported by both the {@link Ext.form.action.Submit submit} and
|
* {@link Ext.form.action.Load load} actions unless otherwise noted (custom actions could also accept other
|
* config options):
|
*
|
* @param {String} options.url
|
* The url for the action (defaults to the form's {@link #url}.)
|
*
|
* @param {String} options.method
|
* The form method to use (defaults to the form's method, or POST if not defined)
|
*
|
* @param {String/Object} options.params
|
* The params to pass (defaults to the form's baseParams, or none if not defined)
|
*
|
* Parameters are encoded as standard HTTP parameters using {@link Ext#urlEncode Ext.Object.toQueryString}.
|
*
|
* @param {Object} options.headers
|
* Request headers to set for the action.
|
*
|
* @param {Function} options.success
|
* The callback that will be invoked after a successful response (see top of {@link Ext.form.action.Submit submit}
|
* and {@link Ext.form.action.Load load} for a description of what constitutes a successful response).
|
* @param {Ext.form.Basic} options.success.form The form that requested the action.
|
* @param {Ext.form.action.Action} options.success.action The Action object which performed the operation.
|
* The action object contains these properties of interest:
|
*
|
* - {@link Ext.form.action.Action#response response}
|
* - {@link Ext.form.action.Action#result result} - interrogate for custom postprocessing
|
* - {@link Ext.form.action.Action#type type}
|
*
|
* @param {Function} options.failure
|
* The callback that will be invoked after a failed transaction attempt.
|
* @param {Ext.form.Basic} options.failure.form The form that requested the action.
|
* @param {Ext.form.action.Action} options.failure.action The Action object which performed the operation.
|
* The action object contains these properties of interest:
|
*
|
* - {@link Ext.form.action.Action#failureType failureType}
|
* - {@link Ext.form.action.Action#response response}
|
* - {@link Ext.form.action.Action#result result} - interrogate for custom postprocessing
|
* - {@link Ext.form.action.Action#type type}
|
*
|
* @param {Object} options.scope
|
* The scope in which to call the callback functions (The this reference for the callback functions).
|
*
|
* @param {Boolean} options.clientValidation
|
* Submit Action only. Determines whether a Form's fields are validated in a final call to {@link
|
* Ext.form.Basic#isValid isValid} prior to submission. Set to false to prevent this. If undefined, pre-submission
|
* field validation is performed.
|
*
|
* @return {Ext.form.Basic} this
|
*/
|
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;
|
},
|
|
<span id='Ext-form-Basic-method-submit'> /**
|
</span> * Shortcut to {@link #doAction do} a {@link Ext.form.action.Submit submit action}. This will use the
|
* {@link Ext.form.action.Submit AJAX submit action} by default. If the {@link #standardSubmit} config
|
* is enabled it will use a standard form element to submit, or if the {@link #api} config is present
|
* it will use the {@link Ext.form.action.DirectLoad Ext.direct.Direct submit action}.
|
*
|
* The following code:
|
*
|
* myFormPanel.getForm().submit({
|
* clientValidation: true,
|
* url: 'updateConsignment.php',
|
* params: {
|
* newStatus: 'delivered'
|
* },
|
* success: function(form, action) {
|
* Ext.Msg.alert('Success', action.result.msg);
|
* },
|
* failure: function(form, action) {
|
* switch (action.failureType) {
|
* case Ext.form.action.Action.CLIENT_INVALID:
|
* Ext.Msg.alert('Failure', 'Form fields may not be submitted with invalid values');
|
* break;
|
* case Ext.form.action.Action.CONNECT_FAILURE:
|
* Ext.Msg.alert('Failure', 'Ajax communication failed');
|
* break;
|
* case Ext.form.action.Action.SERVER_INVALID:
|
* Ext.Msg.alert('Failure', action.result.msg);
|
* }
|
* }
|
* });
|
*
|
* would process the following server response for a successful submission:
|
*
|
* {
|
* "success":true, // note this is Boolean, not string
|
* "msg":"Consignment updated"
|
* }
|
*
|
* and the following server response for a failed submission:
|
*
|
* {
|
* "success":false, // note this is Boolean, not string
|
* "msg":"You do not have permission to perform this operation"
|
* }
|
*
|
* @param {Object} options The options to pass to the action (see {@link #doAction} for details).
|
* @return {Ext.form.Basic} 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);
|
},
|
|
<span id='Ext-form-Basic-method-load'> /**
|
</span> * Shortcut to {@link #doAction do} a {@link Ext.form.action.Load load action}.
|
* @param {Object} options The options to pass to the action (see {@link #doAction} for details)
|
* @return {Ext.form.Basic} this
|
*/
|
load: function(options) {
|
return this.doAction(this.api ? 'directload' : 'load', options);
|
},
|
|
<span id='Ext-form-Basic-method-updateRecord'> /**
|
</span> * Persists the values in this form into the passed {@link Ext.data.Model} object in a beginEdit/endEdit block.
|
* If the record is not specified, it will attempt to update (if it exists) the record provided to loadRecord.
|
* @param {Ext.data.Model} [record] The record to edit
|
* @return {Ext.form.Basic} this
|
*/
|
updateRecord: function(record) {
|
record = record || this._record;
|
if (!record) {
|
//<debug>
|
Ext.Error.raise("A record is required.");
|
//</debug>
|
return this;
|
}
|
|
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;
|
},
|
|
<span id='Ext-form-Basic-method-loadRecord'> /**
|
</span> * Loads an {@link Ext.data.Model} into this form by calling {@link #setValues} with the
|
* {@link Ext.data.Model#raw record data}.
|
* See also {@link #trackResetOnLoad}.
|
* @param {Ext.data.Model} record The record to load
|
* @return {Ext.form.Basic} this
|
*/
|
loadRecord: function(record) {
|
this._record = record;
|
return this.setValues(record.getData());
|
},
|
|
<span id='Ext-form-Basic-method-getRecord'> /**
|
</span> * Returns the last Ext.data.Model instance that was loaded via {@link #loadRecord}
|
* @return {Ext.data.Model} The record
|
*/
|
getRecord: function() {
|
return this._record;
|
},
|
|
<span id='Ext-form-Basic-method-beforeAction'> /**
|
</span> * @private
|
* Called before an action is performed via {@link #doAction}.
|
* @param {Ext.form.action.Action} action The Action instance that was invoked
|
*/
|
beforeAction: function(action) {
|
var me = this,
|
waitMsg = action.waitMsg,
|
maskCls = Ext.baseCSSPrefix + 'mask-loading',
|
fields = me.getFields().items,
|
f,
|
fLen = fields.length,
|
field, waitMsgTarget;
|
|
// Call HtmlEditor's syncValue before actions
|
for (f = 0; f < fLen; f++) {
|
field = fields[f];
|
|
if (field.isFormField && field.syncValue) {
|
field.syncValue();
|
}
|
}
|
|
if (waitMsg) {
|
waitMsgTarget = me.waitMsgTarget;
|
if (waitMsgTarget === true) {
|
me.owner.el.mask(waitMsg, maskCls);
|
} else if (waitMsgTarget) {
|
waitMsgTarget = me.waitMsgTarget = Ext.get(waitMsgTarget);
|
waitMsgTarget.mask(waitMsg, maskCls);
|
} else {
|
me.floatingAncestor = me.owner.up('[floating]');
|
|
// https://sencha.jira.com/browse/EXTJSIV-6397
|
// When the "wait" MessageBox is hidden, the ZIndexManager activates the previous
|
// topmost floating item which would be any Window housing this form.
|
// That kicks off a delayed focus call on that Window.
|
// So if any form post submit processing displayed a MessageBox, that gets
|
// stomped on.
|
// The solution is to not move focus at all during this process.
|
if (me.floatingAncestor) {
|
me.savePreventFocusOnActivate = me.floatingAncestor.preventFocusOnActivate;
|
me.floatingAncestor.preventFocusOnActivate = true;
|
}
|
Ext.MessageBox.wait(waitMsg, action.waitTitle || me.waitTitle);
|
}
|
}
|
},
|
|
<span id='Ext-form-Basic-method-afterAction'> /**
|
</span> * @private
|
* Called after an action is performed via {@link #doAction}.
|
* @param {Ext.form.action.Action} action The Action instance that was invoked
|
* @param {Boolean} success True if the action completed successfully, false, otherwise.
|
*/
|
afterAction: function(action, success) {
|
var me = this;
|
if (action.waitMsg) {
|
var messageBox = Ext.MessageBox,
|
waitMsgTarget = me.waitMsgTarget;
|
if (waitMsgTarget === true) {
|
me.owner.el.unmask();
|
} else if (waitMsgTarget) {
|
waitMsgTarget.unmask();
|
} else {
|
messageBox.hide();
|
}
|
}
|
// Restore setting of any floating ancestor which was manipulated in beforeAction
|
if (me.floatingAncestor) {
|
me.floatingAncestor.preventFocusOnActivate = me.savePreventFocusOnActivate;
|
}
|
if (success) {
|
if (action.reset) {
|
me.reset();
|
}
|
Ext.callback(action.success, action.scope || action, [me, action]);
|
me.fireEvent('actioncomplete', me, action);
|
} else {
|
Ext.callback(action.failure, action.scope || action, [me, action]);
|
me.fireEvent('actionfailed', me, action);
|
}
|
},
|
|
|
<span id='Ext-form-Basic-method-findField'> /**
|
</span> * Find a specific {@link Ext.form.field.Field} in this form by id or name.
|
* @param {String} id The value to search for (specify either a {@link Ext.Component#id id} or
|
* {@link Ext.form.field.Field#getName name or hiddenName}).
|
* @return {Ext.form.field.Field} The first matching field, or `null` if none was found.
|
*/
|
findField: function(id) {
|
return this.getFields().findBy(function(f) {
|
return f.id === id || f.getName() === id;
|
});
|
},
|
|
|
<span id='Ext-form-Basic-method-markInvalid'> /**
|
</span> * Mark fields in this form invalid in bulk.
|
* @param {Object/Object[]/Ext.data.Errors} errors
|
* Either an array in the form `[{id:'fieldId', msg:'The message'}, ...]`,
|
* an object hash of `{id: msg, id2: msg2}`, or a {@link Ext.data.Errors} object.
|
* @return {Ext.form.Basic} this
|
*/
|
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;
|
},
|
|
<span id='Ext-form-Basic-method-setValues'> /**
|
</span> * Set values for fields in this form in bulk.
|
*
|
* @param {Object/Object[]} values Either an array in the form:
|
*
|
* [{id:'clientName', value:'Fred. Olsen Lines'},
|
* {id:'portOfLoading', value:'FXT'},
|
* {id:'portOfDischarge', value:'OSL'} ]
|
*
|
* or an object hash of the form:
|
*
|
* {
|
* clientName: 'Fred. Olsen Lines',
|
* portOfLoading: 'FXT',
|
* portOfDischarge: 'OSL'
|
* }
|
*
|
* @return {Ext.form.Basic} 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();
|
}
|
}
|
}
|
|
// Suspend here because setting the value on a field could trigger
|
// a layout, for example if an error gets set, or it's a display field
|
Ext.suspendLayouts();
|
if (Ext.isArray(values)) {
|
// array of objects
|
vLen = values.length;
|
|
for (v = 0; v < vLen; v++) {
|
val = values[v];
|
|
setVal(val.id, val.value);
|
}
|
} else {
|
// object hash
|
Ext.iterate(values, setVal);
|
}
|
Ext.resumeLayouts(true);
|
return this;
|
},
|
|
<span id='Ext-form-Basic-method-getValues'> /**
|
</span> * Retrieves the fields in the form as a set of key/value pairs, using their
|
* {@link Ext.form.field.Field#getSubmitData getSubmitData()} method to collect the values.
|
* If multiple fields return values under the same name those values will be combined into an Array.
|
* This is similar to {@link Ext.form.Basic#getFieldValues getFieldValues} except that this method
|
* collects only String values for submission, while getFieldValues collects type-specific data
|
* values (e.g. Date objects for date fields.)
|
*
|
* @param {Boolean} [asString=false] If true, will return the key/value collection as a single
|
* URL-encoded param string.
|
* @param {Boolean} [dirtyOnly=false] If true, only fields that are dirty will be included in the result.
|
* @param {Boolean} [includeEmptyText=false] If true, the configured emptyText of empty fields will be used.
|
* @param {Boolean} [useDataValues=false] If true, the {@link Ext.form.field.Field#getModelData getModelData}
|
* method is used to retrieve values from fields, otherwise the {@link Ext.form.field.Field#getSubmitData getSubmitData}
|
* method is used.
|
* @return {String/Object}
|
*/
|
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] = bucket.concat(val);
|
} else {
|
bucket.push(val);
|
}
|
} else {
|
values[name] = val;
|
}
|
}
|
}
|
}
|
}
|
}
|
|
if (asString) {
|
values = Ext.Object.toQueryString(values);
|
}
|
return values;
|
},
|
|
<span id='Ext-form-Basic-method-getFieldValues'> /**
|
</span> * Retrieves the fields in the form as a set of key/value pairs, using their
|
* {@link Ext.form.field.Field#getModelData getModelData()} method to collect the values.
|
* If multiple fields return values under the same name those values will be combined into an Array.
|
* This is similar to {@link #getValues} except that this method collects type-specific data values
|
* (e.g. Date objects for date fields) while getValues returns only String values for submission.
|
*
|
* @param {Boolean} [dirtyOnly=false] If true, only fields that are dirty will be included in the result.
|
* @return {Object}
|
*/
|
getFieldValues: function(dirtyOnly) {
|
return this.getValues(false, dirtyOnly, false, true);
|
},
|
|
<span id='Ext-form-Basic-method-clearInvalid'> /**
|
</span> * Clears all invalid field messages in this form.
|
* @return {Ext.form.Basic} this
|
*/
|
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;
|
},
|
|
<span id='Ext-form-Basic-method-reset'> /**
|
</span> * Resets all fields in this form. By default, any record bound by {@link #loadRecord}
|
* will be retained.
|
* @param {Boolean} [resetRecord=false] True to unbind any record set
|
* by {@link #loadRecord}
|
* @return {Ext.form.Basic} this
|
*/
|
reset: function(resetRecord) {
|
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);
|
|
if (resetRecord === true) {
|
delete me._record;
|
}
|
return me;
|
},
|
|
<span id='Ext-form-Basic-method-applyToFields'> /**
|
</span> * Calls {@link Ext#apply Ext.apply} for all fields in this form with the passed object.
|
* @param {Object} obj The object to be applied
|
* @return {Ext.form.Basic} this
|
*/
|
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;
|
},
|
|
<span id='Ext-form-Basic-method-applyIfToFields'> /**
|
</span> * Calls {@link Ext#applyIf Ext.applyIf} for all field in this form with the passed object.
|
* @param {Object} obj The object to be applied
|
* @return {Ext.form.Basic} 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;
|
}
|
});
|
</pre>
|
</body>
|
</html>
|