Form.js 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. let $eColumns = {};
  2. export default class Form {
  3. /**
  4. * 表单提交
  5. *
  6. * @param options
  7. * @constructor
  8. */
  9. constructor(options) {
  10. let _this = this;
  11. _this.options = $.extend({
  12. // 表单的 jquery 对象
  13. form: null,
  14. errorClass: 'has-error',
  15. groupSelector: '.form-group',
  16. template: '<label class="control-label" for="inputError"><i class="fa fa-times-circle-o"></i> _message_</label><br/>',
  17. disableRedirect: false, //
  18. columnSelectors: {}, //
  19. disableRemoveError: false,
  20. before: function () {},
  21. after: function () {},
  22. }, options);
  23. }
  24. _execute() {
  25. var originalVals = {},
  26. cls = opts.errorClass,
  27. groupSlt = opts.groupSelector,
  28. tpl = opts.template,
  29. $form = opts.$form,
  30. tabSelector = '.tab-pane',
  31. get_tab_id = function ($c) {
  32. return $c.parents(tabSelector).attr('id');
  33. },
  34. get_tab_title_error = function ($c) {
  35. var id = get_tab_id($c);
  36. if (!id) return $('<none></none>');
  37. return $("[href='#" + id + "'] .text-red");
  38. };
  39. var self = this;
  40. // 移除错误信息
  41. remove_field_error();
  42. $form.ajaxSubmit({
  43. beforeSubmit: function (d, f, o) {
  44. if (opts.before(d, f, o, self) === false) {
  45. return false;
  46. }
  47. if (fire(LA._form_.before, d, f, o, self) === false) {
  48. return false;
  49. }
  50. LA.NP.start();
  51. },
  52. success: function (d) {
  53. LA.NP.done();
  54. if (opts.after(true, d, self) === false) {
  55. return;
  56. }
  57. if (fire(LA._form_.success, d, self) === false) {
  58. return;
  59. }
  60. if (!d.status) {
  61. LA.error(d.message || 'Save failed!');
  62. return;
  63. }
  64. LA.success(d.message || 'Save succeeded!');
  65. if (opts.disableRedirect || d.redirect === false) return;
  66. if (d.redirect) {
  67. return LA.reload(d.redirect);
  68. }
  69. history.back(-1);
  70. },
  71. error: function (v) {
  72. LA.NP.done();
  73. if (opts.after(false, v, self) === false) {
  74. return;
  75. }
  76. if (fire(LA._form_.error, v, self) === false) {
  77. return;
  78. }
  79. try {
  80. var error = JSON.parse(v.responseText), i;
  81. if (v.status != 422 || !error || !LA.isset(error, 'errors')) {
  82. return LA.error(v.status + ' ' + v.statusText);
  83. }
  84. error = error.errors;
  85. for (i in error) {
  86. // 显示错误信息
  87. $eColumns[i] = show_field_error($form, i, error[i]);
  88. }
  89. } catch (e) {
  90. return LA.error(v.status + ' ' + v.statusText);
  91. }
  92. }
  93. });
  94. // 触发钩子事件
  95. function fire(evs) {
  96. var i, j, r, args = arguments, p = [];
  97. delete args[0];
  98. args = args || [];
  99. for (j in args) {
  100. p.push(args[j]);
  101. }
  102. for (i in evs) {
  103. r = evs[i].apply(evs[i], p);
  104. if (r === false) return r; // 返回 false 会代码阻止继续执行
  105. }
  106. }
  107. // 删除错误有字段的错误信息
  108. function remove_field_error() {
  109. var i, p, t;
  110. for (i in $eColumns) {
  111. p = $eColumns[i].parents(groupSlt);
  112. p.removeClass(cls);
  113. p.find('error').html('');
  114. t = get_tab_title_error($eColumns[i]);
  115. if (!t.hasClass('hide')) {
  116. t.addClass('hide');
  117. }
  118. }
  119. // 重置
  120. $eColumns = {};
  121. }
  122. // 显示错误信息
  123. function show_field_error($form, column, errors) {
  124. var $c = get_field_obj($form, column);
  125. get_tab_title_error($c).removeClass('hide');
  126. // 保存字段原始数据
  127. originalVals[column] = get_val($c);
  128. if (!$c) {
  129. if (LA.len(errors) && errors.length) {
  130. LA.error(errors.join(" \n "));
  131. }
  132. return;
  133. }
  134. var p = $c.closest(groupSlt), j;
  135. p.addClass(cls);
  136. for (j in errors) {
  137. p.find('error').eq(0).append(tpl.replace('_message_', errors[j]));
  138. }
  139. if (!opts.disableRemoveError) {
  140. remove_error_when_val_changed($c, column);
  141. }
  142. return $c;
  143. }
  144. // 获取字段对象
  145. function get_field_obj($form, column) {
  146. if (column.indexOf('.') != -1) {
  147. column = column.split('.');
  148. var first = column.shift(), i, sub = '';
  149. for (i in column) {
  150. sub += '[' + column[i] + ']';
  151. }
  152. column = first + sub;
  153. }
  154. var $c = $form.find('[name="' + column + '"]');
  155. if (!$c.length) $c = $form.find('[name="' + column + '[]"]');
  156. if (!$c.length) {
  157. $c = $form.find('[name="' + column.replace(/start$/, '') + '"]');
  158. }
  159. if (!$c.length) {
  160. $c = $form.find('[name="' + column.replace(/end$/, '') + '"]');
  161. }
  162. if (!$c.length) {
  163. $c = $form.find('[name="' + column.replace(/start\]$/, ']') + '"]');
  164. }
  165. if (!$c.length) {
  166. $c = $form.find('[name="' + column.replace(/end\]$/, ']') + '"]');
  167. }
  168. return $c;
  169. }
  170. // 获取字段值
  171. function get_val($c) {
  172. var vals = [],
  173. t = $c.attr('type'),
  174. cked = t === 'checkbox' || t === 'radio',
  175. i;
  176. for (i = 0; i < $c.length; i++) {
  177. if (cked) {
  178. vals.push($($c[i]).prop('checked'));
  179. continue;
  180. }
  181. vals.push($($c[i]).val());
  182. }
  183. return vals;
  184. }
  185. // 当字段值变化时移除错误信息
  186. function remove_error_when_val_changed($c, column) {
  187. var p = $c.parents(groupSlt);
  188. $c.one('change', rm);
  189. $c.off('blur', rm).on('blur', function () {
  190. if (val_changed()) rm();
  191. });
  192. // 表单值发生变化就移除错误信息
  193. function autorm() {
  194. setTimeout(function () {
  195. if (!$c.length) return;
  196. if (val_changed()) return rm();
  197. autorm();
  198. }, 500);
  199. }
  200. autorm();
  201. // 判断值是否改变
  202. function val_changed() {
  203. return !LA.arr.equal(originalVals[column], get_val($c));
  204. }
  205. function rm() {
  206. p.removeClass(cls);
  207. p.find('error').html('');
  208. // tab页下没有错误信息了,隐藏title的错误图标
  209. var id = get_tab_id($c), t;
  210. if (id && !$('#'+id).find('.'+cls).length) {
  211. t = get_tab_title_error($c);
  212. if (!t.hasClass('hide')) {
  213. t.addClass('hide');
  214. }
  215. }
  216. delete $eColumns[column];
  217. }
  218. }
  219. }
  220. }