index.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. import { createNamespace } from '../utils';
  2. import { sortChildren } from '../utils/vnodes';
  3. var _createNamespace = createNamespace('form'),
  4. createComponent = _createNamespace[0],
  5. bem = _createNamespace[1];
  6. export default createComponent({
  7. props: {
  8. colon: Boolean,
  9. disabled: Boolean,
  10. readonly: Boolean,
  11. labelWidth: [Number, String],
  12. labelAlign: String,
  13. inputAlign: String,
  14. scrollToError: Boolean,
  15. validateFirst: Boolean,
  16. errorMessageAlign: String,
  17. submitOnEnter: {
  18. type: Boolean,
  19. default: true
  20. },
  21. validateTrigger: {
  22. type: String,
  23. default: 'onBlur'
  24. },
  25. showError: {
  26. type: Boolean,
  27. default: true
  28. },
  29. showErrorMessage: {
  30. type: Boolean,
  31. default: true
  32. }
  33. },
  34. provide: function provide() {
  35. return {
  36. vanForm: this
  37. };
  38. },
  39. data: function data() {
  40. return {
  41. fields: []
  42. };
  43. },
  44. methods: {
  45. getFieldsByNames: function getFieldsByNames(names) {
  46. if (names) {
  47. return this.fields.filter(function (field) {
  48. return names.indexOf(field.name) !== -1;
  49. });
  50. }
  51. return this.fields;
  52. },
  53. validateSeq: function validateSeq(names) {
  54. var _this = this;
  55. return new Promise(function (resolve, reject) {
  56. var errors = [];
  57. var fields = _this.getFieldsByNames(names);
  58. fields.reduce(function (promise, field) {
  59. return promise.then(function () {
  60. if (!errors.length) {
  61. return field.validate().then(function (error) {
  62. if (error) {
  63. errors.push(error);
  64. }
  65. });
  66. }
  67. });
  68. }, Promise.resolve()).then(function () {
  69. if (errors.length) {
  70. reject(errors);
  71. } else {
  72. resolve();
  73. }
  74. });
  75. });
  76. },
  77. validateFields: function validateFields(names) {
  78. var _this2 = this;
  79. return new Promise(function (resolve, reject) {
  80. var fields = _this2.getFieldsByNames(names);
  81. Promise.all(fields.map(function (item) {
  82. return item.validate();
  83. })).then(function (errors) {
  84. errors = errors.filter(function (item) {
  85. return item;
  86. });
  87. if (errors.length) {
  88. reject(errors);
  89. } else {
  90. resolve();
  91. }
  92. });
  93. });
  94. },
  95. // @exposed-api
  96. validate: function validate(name) {
  97. if (name && !Array.isArray(name)) {
  98. return this.validateField(name);
  99. }
  100. return this.validateFirst ? this.validateSeq(name) : this.validateFields(name);
  101. },
  102. validateField: function validateField(name) {
  103. var matched = this.fields.filter(function (item) {
  104. return item.name === name;
  105. });
  106. if (matched.length) {
  107. return new Promise(function (resolve, reject) {
  108. matched[0].validate().then(function (error) {
  109. if (error) {
  110. reject(error);
  111. } else {
  112. resolve();
  113. }
  114. });
  115. });
  116. }
  117. return Promise.reject();
  118. },
  119. // @exposed-api
  120. resetValidation: function resetValidation(name) {
  121. if (name && !Array.isArray(name)) {
  122. name = [name];
  123. }
  124. var fields = this.getFieldsByNames(name);
  125. fields.forEach(function (item) {
  126. item.resetValidation();
  127. });
  128. },
  129. // @exposed-api
  130. scrollToField: function scrollToField(name, options) {
  131. this.fields.some(function (item) {
  132. if (item.name === name) {
  133. item.$el.scrollIntoView(options);
  134. return true;
  135. }
  136. return false;
  137. });
  138. },
  139. addField: function addField(field) {
  140. this.fields.push(field);
  141. sortChildren(this.fields, this);
  142. },
  143. removeField: function removeField(field) {
  144. this.fields = this.fields.filter(function (item) {
  145. return item !== field;
  146. });
  147. },
  148. getValues: function getValues() {
  149. return this.fields.reduce(function (form, field) {
  150. form[field.name] = field.formValue;
  151. return form;
  152. }, {});
  153. },
  154. onSubmit: function onSubmit(event) {
  155. event.preventDefault();
  156. this.submit();
  157. },
  158. // @exposed-api
  159. submit: function submit() {
  160. var _this3 = this;
  161. var values = this.getValues();
  162. this.validate().then(function () {
  163. _this3.$emit('submit', values);
  164. }).catch(function (errors) {
  165. _this3.$emit('failed', {
  166. values: values,
  167. errors: errors
  168. });
  169. if (_this3.scrollToError) {
  170. _this3.scrollToField(errors[0].name);
  171. }
  172. });
  173. }
  174. },
  175. render: function render() {
  176. var h = arguments[0];
  177. return h("form", {
  178. "class": bem(),
  179. "on": {
  180. "submit": this.onSubmit
  181. }
  182. }, [this.slots()]);
  183. }
  184. });