66d385f41152b19c8f15a933ceec29675db1d198.svn-base 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  1. /*
  2. * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com
  3. *
  4. * http://extjs.com/license
  5. */
  6. /**
  7. * @class Ext.form.Action The subclasses of this class provide actions to
  8. * perform upon {@link Ext.form.BasicForm Form}s. <br>
  9. * <br>
  10. * Instances of this class are only created by a
  11. * {@link Ext.form.BasicForm Form} when the Form needs to perform an
  12. * action such as submit or load. The Configuration options listed for
  13. * this class are set through the Form's action methods:
  14. * {@link Ext.form.BasicForm#submit submit},
  15. * {@link Ext.form.BasicForm#load load} and
  16. * {@link Ext.form.BasicForm#doAction doAction}. <br>
  17. * <br>
  18. * The instance of Action which performed the action is passed to the
  19. * success and failure callbacks of the Form's action methods ({@link Ext.form.BasicForm#submit submit},
  20. * {@link Ext.form.BasicForm#load load} and
  21. * {@link Ext.form.BasicForm#doAction doAction}), and to the
  22. * {@link Ext.form.BasicForm#actioncomplete actioncomplete} and
  23. * {@link Ext.form.BasicForm#actionfailed actionfailed} event handlers.
  24. */
  25. Ext.form.Action = function(form, options) {
  26. this.form = form;
  27. this.options = options || {};
  28. };
  29. /**
  30. * Failure type returned when client side validation of the Form fails thus
  31. * aborting a submit action.
  32. *
  33. * @type {String}
  34. * @static
  35. */
  36. Ext.form.Action.CLIENT_INVALID = 'client';
  37. /**
  38. * Failure type returned when server side validation of the Form fails
  39. * indicating that field-specific error messages have been returned in the
  40. * response's <tt style="font-weight:bold">errors</tt> property.
  41. *
  42. * @type {String}
  43. * @static
  44. */
  45. Ext.form.Action.SERVER_INVALID = 'server';
  46. /**
  47. * Failure type returned when a communication error happens when attempting to
  48. * send a request to the remote server.
  49. *
  50. * @type {String}
  51. * @static
  52. */
  53. Ext.form.Action.CONNECT_FAILURE = 'connect';
  54. /**
  55. * Failure type returned when no field values are returned in the response's
  56. * <tt style="font-weight:bold">data</tt> property.
  57. *
  58. * @type {String}
  59. * @static
  60. */
  61. Ext.form.Action.LOAD_FAILURE = 'load';
  62. Ext.form.Action.prototype = {
  63. /**
  64. * @cfg {String} url The URL that the Action is to invoke.
  65. */
  66. /**
  67. * @cfg {String} method The HTTP method to use to access the requested URL.
  68. * Defaults to the {@link Ext.form.BasicForm}'s method, or if that is
  69. * not specified, the underlying DOM form's method.
  70. */
  71. /**
  72. * @cfg {Mixed} params Extra parameter values to pass. These are added to
  73. * the Form's {@link Ext.form.BasicForm#baseParams} and passed to the
  74. * specified URL along with the Form's input fields.
  75. */
  76. /**
  77. * @cfg {Function} success The function to call when a valid success return
  78. * packet is recieved. The function is passed the following parameters:
  79. * <ul class="mdetail-params">
  80. * <li><b>form</b> : Ext.form.BasicForm<div class="sub-desc">The
  81. * form that requested the action</div></li>
  82. * <li><b>action</b> : Ext.form.Action<div class="sub-desc">The
  83. * Action class. The {@link #result} property of this object may be
  84. * examined to perform custom postprocessing.</div></li>
  85. * </ul>
  86. */
  87. /**
  88. * @cfg {Function} failure The function to call when a failure packet was
  89. * recieved, or when an error ocurred in the Ajax communication. The
  90. * function is passed the following parameters:
  91. * <ul class="mdetail-params">
  92. * <li><b>form</b> : Ext.form.BasicForm<div class="sub-desc">The
  93. * form that requested the action</div></li>
  94. * <li><b>action</b> : Ext.form.Action<div class="sub-desc">The
  95. * Action class. If an Ajax error ocurred, the failure type will be in
  96. * {@link #failureType}. The {@link #result} property of this object
  97. * may be examined to perform custom postprocessing.</div></li>
  98. * </ul>
  99. */
  100. /**
  101. * @cfg {Object} scope The scope in which to call the callback functions
  102. * (The <tt>this</tt> reference for the callback functions).
  103. */
  104. /**
  105. * @cfg {String} waitMsg The message to be displayed by a call to
  106. * {@link Ext.MessageBox#wait} during the time the action is being
  107. * processed.
  108. */
  109. /**
  110. * @cfg {String} waitTitle The title to be displayed by a call to
  111. * {@link Ext.MessageBox#wait} during the time the action is being
  112. * processed.
  113. */
  114. /**
  115. * The type of action this Action instance performs. Currently only "submit"
  116. * and "load" are supported.
  117. *
  118. * @type {String}
  119. */
  120. type : 'default',
  121. /**
  122. * The type of failure detected. See
  123. * {@link #Ext.form.Action-Action.CLIENT_INVALID CLIENT_INVALID},
  124. * {@link #Ext.form.Action-Action.SERVER_INVALID SERVER_INVALID},
  125. * {@link #Ext.form.Action-Action.CONNECT_FAILURE CONNECT_FAILURE},
  126. * {@link #Ext.form.Action-Action.LOAD_FAILURE LOAD_FAILURE}
  127. *
  128. * @property failureType
  129. * @type {String}
  130. */
  131. /**
  132. * The XMLHttpRequest object used to perform the action.
  133. *
  134. * @property response
  135. * @type {Object}
  136. */
  137. /**
  138. * The decoded response object containing a boolean
  139. * <tt style="font-weight:bold">success</tt> property and other,
  140. * action-specific properties.
  141. *
  142. * @property result
  143. * @type {Object}
  144. */
  145. // interface method
  146. run : function(options) {
  147. },
  148. // interface method
  149. success : function(response) {
  150. },
  151. // interface method
  152. handleResponse : function(response) {
  153. },
  154. // default connection failure
  155. failure : function(response) {
  156. this.response = response;
  157. this.failureType = Ext.form.Action.CONNECT_FAILURE;
  158. this.form.afterAction(this, false);
  159. },
  160. // private
  161. processResponse : function(response) {
  162. this.response = response;
  163. if (!response.responseText) {
  164. return true;
  165. }
  166. this.result = this.handleResponse(response);
  167. return this.result;
  168. },
  169. // utility functions used internally
  170. getUrl : function(appendParams) {
  171. var url = this.options.url || this.form.url || this.form.el.dom.action;
  172. if (appendParams) {
  173. var p = this.getParams();
  174. if (p) {
  175. url += (url.indexOf('?') != -1 ? '&' : '?') + p;
  176. }
  177. }
  178. return url;
  179. },
  180. // private
  181. getMethod : function() {
  182. return (this.options.method || this.form.method
  183. || this.form.el.dom.method || 'POST').toUpperCase();
  184. },
  185. // private
  186. getParams : function() {
  187. var bp = this.form.baseParams;
  188. var p = this.options.params;
  189. if (p) {
  190. if (typeof p == "object") {
  191. p = Ext.urlEncode(Ext.applyIf(p, bp));
  192. } else if (typeof p == 'string' && bp) {
  193. p += '&' + Ext.urlEncode(bp);
  194. }
  195. } else if (bp) {
  196. p = Ext.urlEncode(bp);
  197. }
  198. return p;
  199. },
  200. // private
  201. createCallback : function(opts) {
  202. var opts = opts || {};
  203. return {
  204. success : this.success,
  205. failure : this.failure,
  206. scope : this,
  207. timeout : (opts.timeout * 1000) || (this.form.timeout * 1000),
  208. upload : this.form.fileUpload ? this.success : undefined
  209. };
  210. }
  211. };
  212. /**
  213. * @class Ext.form.Action.Submit
  214. * @extends Ext.form.Action A class which handles submission of data from
  215. * {@link Ext.form.BasicForm Form}s and processes the returned
  216. * response. <br>
  217. * <br>
  218. * Instances of this class are only created by a
  219. * {@link Ext.form.BasicForm Form} when submitting. <br>
  220. * <br>
  221. * A response packet must contain a boolean
  222. * <tt style="font-weight:bold">success</tt> property, and,
  223. * optionally an <tt style="font-weight:bold">errors</tt> property.
  224. * The <tt style="font-weight:bold">errors</tt> property contains
  225. * error messages for invalid fields. <br>
  226. * <br>
  227. * By default, response packets are assumed to be JSON, so a typical
  228. * response packet may look like this: <br>
  229. * <br>
  230. *
  231. * <pre><code>
  232. * {
  233. * success: false,
  234. * errors: {
  235. * clientCode: &quot;Client not found&quot;,
  236. * portOfLoading: &quot;This field must not be null&quot;
  237. * }
  238. * }
  239. * </code></pre>
  240. *
  241. * <br>
  242. * <br>
  243. * Other data may be placed into the response for processing the the
  244. * {@link Ext.form.BasicForm}'s callback or event handler methods. The
  245. * object decoded from this JSON is available in the {@link #result}
  246. * property.
  247. */
  248. Ext.form.Action.Submit = function(form, options) {
  249. Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
  250. };
  251. Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
  252. /**
  253. * @cfg {boolean} clientValidation Determines whether a Form's
  254. * fields are validated in a final call to
  255. * {@link Ext.form.BasicForm#isValid isValid} prior to
  256. * submission. Pass <tt>false</tt> in the Form's submit
  257. * options to prevent this. If not defined, pre-submission
  258. * field validation is performed.
  259. */
  260. type : 'submit',
  261. // private
  262. run : function() {
  263. var o = this.options;
  264. var method = this.getMethod();
  265. var isPost = method == 'POST';
  266. if (o.clientValidation === false || this.form.isValid()) {
  267. Ext.Ajax.request(Ext.apply(this.createCallback(o), {
  268. form : this.form.el.dom,
  269. url : this.getUrl(!isPost),
  270. method : method,
  271. params : isPost ? this.getParams() : null,
  272. isUpload : this.form.fileUpload
  273. }));
  274. } else if (o.clientValidation !== false) { // client validation
  275. // failed
  276. this.failureType = Ext.form.Action.CLIENT_INVALID;
  277. this.form.afterAction(this, false);
  278. }
  279. },
  280. // private
  281. success : function(response) {
  282. var result = this.processResponse(response);
  283. if (result === true || result.success) {
  284. this.form.afterAction(this, true);
  285. return;
  286. }
  287. if (result.errors) {
  288. this.form.markInvalid(result.errors);
  289. this.failureType = Ext.form.Action.SERVER_INVALID;
  290. }
  291. this.form.afterAction(this, false);
  292. },
  293. // private
  294. handleResponse : function(response) {
  295. if (this.form.errorReader) {
  296. var rs = this.form.errorReader.read(response);
  297. var errors = [];
  298. if (rs.records) {
  299. for (var i = 0, len = rs.records.length; i < len; i++) {
  300. var r = rs.records[i];
  301. errors[i] = r.data;
  302. }
  303. }
  304. if (errors.length < 1) {
  305. errors = null;
  306. }
  307. return {
  308. success : rs.success,
  309. errors : errors
  310. };
  311. }
  312. return Ext.decode(response.responseText);
  313. }
  314. });
  315. /**
  316. * @class Ext.form.Action.Load
  317. * @extends Ext.form.Action A class which handles loading of data from a server
  318. * into the Fields of an {@link Ext.form.BasicForm}. <br>
  319. * <br>
  320. * Instances of this class are only created by a
  321. * {@link Ext.form.BasicForm Form} when submitting. <br>
  322. * <br>
  323. * A response packet <b>must</b> contain a boolean
  324. * <tt style="font-weight:bold">success</tt> property, and a
  325. * <tt style="font-weight:bold">data</tt> property. The
  326. * <tt style="font-weight:bold">data</tt> property contains the
  327. * values of Fields to load. The individual value object for each Field
  328. * is passed to the Field's {@link Ext.form.Field#setValue setValue}
  329. * method. <br>
  330. * <br>
  331. * By default, response packets are assumed to be JSON, so a typical
  332. * response packet may look like this: <br>
  333. * <br>
  334. *
  335. * <pre><code>
  336. * {
  337. * success: true,
  338. * data: {
  339. * clientName: &quot;Fred. Olsen Lines&quot;,
  340. * portOfLoading: &quot;FXT&quot;,
  341. * portOfDischarge: &quot;OSL&quot;
  342. * }
  343. * }
  344. * </code></pre>
  345. *
  346. * <br>
  347. * <br>
  348. * Other data may be placed into the response for processing the the
  349. * {@link Ext.form.BasicForm Form}'s callback or event handler
  350. * methods. The object decoded from this JSON is available in the
  351. * {@link #result} property.
  352. */
  353. Ext.form.Action.Load = function(form, options) {
  354. Ext.form.Action.Load.superclass.constructor.call(this, form, options);
  355. this.reader = this.form.reader;
  356. };
  357. Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
  358. // private
  359. type : 'load',
  360. // private
  361. run : function() {
  362. Ext.Ajax.request(Ext.apply(this.createCallback(this.options), {
  363. method : this.getMethod(),
  364. url : this.getUrl(false),
  365. params : this.getParams()
  366. }));
  367. },
  368. // private
  369. success : function(response) {
  370. var result = this.processResponse(response);
  371. if (result === true || !result.success || !result.data) {
  372. this.failureType = Ext.form.Action.LOAD_FAILURE;
  373. this.form.afterAction(this, false);
  374. return;
  375. }
  376. this.form.clearInvalid();
  377. this.form.setValues(result.data);
  378. this.form.afterAction(this, true);
  379. },
  380. // private
  381. handleResponse : function(response) {
  382. if (this.form.reader) {
  383. var rs = this.form.reader.read(response);
  384. var data = rs.records && rs.records[0]
  385. ? rs.records[0].data
  386. : null;
  387. return {
  388. success : rs.success,
  389. data : data
  390. };
  391. }
  392. return Ext.decode(response.responseText);
  393. }
  394. });
  395. Ext.form.Action.ACTION_TYPES = {
  396. 'load' : Ext.form.Action.Load,
  397. 'submit' : Ext.form.Action.Submit
  398. };