@form-create/element-ui 2.6.3 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/core/api.js CHANGED
@@ -11,7 +11,7 @@ function tidyBtnProp(btn, def) {
11
11
  }
12
12
 
13
13
  export default function extendApi(api, h) {
14
- extend(api, {
14
+ return {
15
15
  formEl() {
16
16
  return h.$manager.form();
17
17
  },
@@ -32,21 +32,19 @@ export default function extendApi(api, h) {
32
32
  callback && callback(true);
33
33
  }).catch((e) => {
34
34
  reject(e);
35
- callback && callback(false, e);
35
+ callback && callback(e);
36
36
  h.vm.$emit('validate-fail', e, {api});
37
37
  })
38
38
  });
39
39
  },
40
- validateField: (field, callback) => {
40
+ validateField(field, callback) {
41
41
  return new Promise((resolve, reject) => {
42
42
  const ctx = h.getFieldCtx(field);
43
43
  if (!ctx) return;
44
44
  const sub = h.subForm[ctx.id];
45
45
  const all = [h.$manager.validateField(ctx.id)];
46
46
  toArray(sub).forEach(v => {
47
- all.push(v.validate().catch(() => {
48
- return Promise.reject('子表单验证未通过');
49
- }));
47
+ all.push(v.validate());
50
48
  })
51
49
  Promise.all(all).then(() => {
52
50
  resolve(null);
@@ -116,21 +114,18 @@ export default function extendApi(api, h) {
116
114
  api.refreshOptions();
117
115
  },
118
116
  submit(successFn, failFn) {
119
- api.validate((valid) => {
120
- if (valid) {
117
+ return new Promise((resolve, reject) => {
118
+ api.validate().then(() => {
121
119
  let formData = api.formData();
122
- if (is.Function(successFn))
123
- invoke(() => successFn(formData, this));
124
- else {
125
- is.Function(h.options.onSubmit) && invoke(() => h.options.onSubmit(formData, this));
126
- h.vm.$emit('submit', formData, this);
127
- }
128
- } else {
129
- is.Function(failFn) && invoke(() => failFn(this, ...arguments));
130
- }
131
- }).catch(e=>{});
120
+ is.Function(successFn) && invoke(() => successFn(formData, api));
121
+ is.Function(h.options.onSubmit) && invoke(() => h.options.onSubmit(formData, api));
122
+ h.vm.$emit('submit', formData, api);
123
+ resolve(formData);
124
+ }).catch((...args) => {
125
+ is.Function(failFn) && invoke(() => failFn(api, ...args));
126
+ reject(...args)
127
+ })
128
+ });
132
129
  },
133
- });
134
-
135
- return api;
130
+ };
136
131
  }
package/src/core/index.js CHANGED
@@ -6,6 +6,7 @@ import FormCreateFactory from '@form-create/core/src/index';
6
6
  import makers from './maker';
7
7
  import '../style/index.css';
8
8
  import extendApi from './api';
9
+ import required from './provider';
9
10
 
10
11
  function install(FormCreate) {
11
12
  FormCreate.componentAlias(alias);
@@ -14,6 +15,8 @@ function install(FormCreate) {
14
15
  FormCreate.component(component.name, component);
15
16
  });
16
17
 
18
+ FormCreate.register(required);
19
+
17
20
  parsers.forEach((parser) => {
18
21
  FormCreate.parser(parser);
19
22
  });
@@ -8,12 +8,6 @@ function isTooltip(info) {
8
8
  return info.type === 'tooltip';
9
9
  }
10
10
 
11
- const upperCaseReg = /[A-Z]/;
12
-
13
- export function isAttr(name, value) {
14
- return (!upperCaseReg.test(name) && (is.String(value) || is.Number(value)))
15
- }
16
-
17
11
  function tidy(props, name) {
18
12
  if (!hasProperty(props, name)) return;
19
13
  if (is.String(props[name])) {
@@ -31,30 +25,37 @@ function tidyBool(opt, name) {
31
25
  }
32
26
  }
33
27
 
28
+ function tidyRule(rule) {
29
+ const _rule = {...rule};
30
+ delete _rule.children;
31
+ return _rule;
32
+ }
33
+
34
34
  export default {
35
35
  validate() {
36
36
  const form = this.form();
37
37
  if (form) {
38
38
  return form.validate();
39
+ } else {
40
+ return new Promise(v => v());
39
41
  }
40
- return new Promise(v => v());
41
42
  },
42
43
  validateField(field) {
43
- const form = this.form();
44
- if (form) {
45
- return new Promise((resolve, reject) => {
46
- form.validateField(field, e => {
47
- e ? reject(e) : resolve(null);
44
+ return new Promise((resolve, reject) => {
45
+ const form = this.form();
46
+ if (form) {
47
+ form.validateField(field, (res, err) => {
48
+ err ? reject(err) : resolve(res);
48
49
  });
49
- })
50
- }
51
- return new Promise(v => v());
50
+ } else {
51
+ resolve();
52
+ }
53
+ });
52
54
  },
53
55
  clearValidateState(ctx) {
54
56
  const fItem = this.vm.$refs[ctx.wrapRef];
55
57
  if (fItem) {
56
- fItem.validateMessage = '';
57
- fItem.validateState = '';
58
+ fItem.clearValidate();
58
59
  }
59
60
  },
60
61
  tidyOptions(options) {
@@ -69,18 +70,7 @@ export default {
69
70
  return prop;
70
71
  },
71
72
  mergeProp(ctx) {
72
- let props = ctx.prop.props;
73
- ctx.prop = mergeProps([{
74
- attrs: Object.keys(props).reduce((initial, val) => {
75
- if (isAttr(val, props[val]))
76
- initial[val] = props[val];
77
- return initial;
78
- }, {}),
79
- info: this.options.info || {},
80
- wrap: this.options.wrap || {},
81
- col: this.options.col || {},
82
- title: this.options.title || {},
83
- }, ctx.prop], {
73
+ const def = {
84
74
  info: {
85
75
  trigger: 'hover',
86
76
  placement: 'top-start',
@@ -89,7 +79,10 @@ export default {
89
79
  title: {},
90
80
  col: {span: 24},
91
81
  wrap: {},
92
- }, {normal: ['title', 'info', 'col', 'wrap']});
82
+ };
83
+ ['info', 'wrap', 'col', 'title'].forEach(name => {
84
+ ctx.prop[name] = mergeProps([this.options[name] || {}, ctx.prop[name] || {}], def[name]);
85
+ });
93
86
  },
94
87
  getDefaultOptions() {
95
88
  return getConfig();
@@ -103,7 +96,7 @@ export default {
103
96
  e.preventDefault();
104
97
  }
105
98
  },
106
- class: [form.className, form.class, 'form-create'],
99
+ class: [form.className, form.class, 'form-create', this.$handle.preview ? 'is-preview' : ''],
107
100
  style: form.style,
108
101
  type: 'form',
109
102
  };
@@ -113,35 +106,35 @@ export default {
113
106
  extend(this.rule, {key, ref});
114
107
  extend(this.rule.props, {
115
108
  model: $handle.formData,
116
- // rules: $handle.validate(),
117
109
  });
118
110
  },
119
111
  render(children) {
120
- if (children.length) {
121
- children.push(this.makeFormBtn());
112
+ if (children.slotLen() && !this.$handle.preview) {
113
+ children.setSlot(undefined, () => this.makeFormBtn());
122
114
  }
123
- return this.$r(this.rule, isFalse(this.options.row.show) ? children : [this.makeRow(children)]);
115
+ return this.$r(this.rule, isFalse(this.options.row.show) ? children.getSlots() : [this.makeRow(children)]);
124
116
  },
125
117
  makeWrap(ctx, children) {
126
118
  const rule = ctx.prop;
127
119
  const uni = `${this.key}${ctx.key}`;
128
120
  const col = rule.col;
129
- const isTitle = this.isTitle(rule);
121
+ const isTitle = this.isTitle(rule) && rule.wrap.title !== false;
130
122
  const labelWidth = (!col.labelWidth && !isTitle) ? 0 : col.labelWidth;
131
123
  const {inline, col: _col} = this.rule.props;
124
+ delete rule.wrap.title;
132
125
  const item = isFalse(rule.wrap.show) ? children : this.$r(mergeProps([rule.wrap, {
133
126
  props: {
134
127
  labelWidth: labelWidth === void 0 ? labelWidth : toString(labelWidth),
135
128
  label: isTitle ? rule.title.title : undefined,
136
- ...(rule.wrap || {}),
129
+ ...tidyRule(rule.wrap || {}),
137
130
  prop: ctx.id,
138
131
  rules: ctx.injectValidate(),
139
132
  },
140
- class: rule.className,
133
+ class: this.$render.mergeClass(rule.className, 'fc-form-item'),
141
134
  key: `${uni}fi`,
142
135
  ref: ctx.wrapRef,
143
136
  type: 'formItem',
144
- }]), [children, isTitle ? this.makeInfo(rule, uni, ctx) : null]);
137
+ }]), {default: () => children, ...(isTitle ? {label: () => this.makeInfo(rule, uni, ctx)} : {})});
145
138
  return (inline === true || isFalse(_col) || isFalse(col.show)) ? item : this.makeCol(rule, uni, [item]);
146
139
  },
147
140
  isTitle(rule) {
@@ -150,23 +143,34 @@ export default {
150
143
  return !((!title.title && !title.native) || isFalse(title.show))
151
144
  },
152
145
  makeInfo(rule, uni, ctx) {
153
- const titleProp = rule.title;
154
- const infoProp = rule.info;
146
+ const titleProp = {...rule.title};
147
+ const infoProp = {...rule.info};
155
148
  const isTip = isTooltip(infoProp);
156
149
  const form = this.options.form;
157
150
  const titleSlot = this.getSlot('title');
158
- const children = [titleSlot ? titleSlot({title: titleProp.title || '', rule: ctx.rule, options: this.options}) : ((titleProp.title || '') + (form.labelSuffix || form['label-suffix'] || ''))];
151
+ const children = [titleSlot ? titleSlot({
152
+ title: ctx.refRule.__$title.value,
153
+ rule: ctx.rule,
154
+ options: this.options
155
+ }) : ((ctx.refRule.__$title.value) + (form.labelSuffix || form['label-suffix'] || ''))];
159
156
 
160
157
  if (!isFalse(infoProp.show) && (infoProp.info || infoProp.native) && !isFalse(infoProp.icon)) {
161
158
  const prop = {
162
159
  type: infoProp.type || 'popover',
163
- props: {...infoProp},
164
- key: `${uni}pop`,
165
- slot: 'label'
160
+ slot: 'label',
161
+ props: tidyRule(infoProp),
162
+ key: `${uni}pop`
166
163
  };
164
+
165
+ delete prop.props.icon;
166
+ delete prop.props.show;
167
+ delete prop.props.info;
168
+ delete prop.props.align;
169
+ delete prop.props.native;
170
+
167
171
  const field = 'content';
168
172
  if (infoProp.info && !hasProperty(prop.props, field)) {
169
- prop.props[field] = infoProp.info;
173
+ prop.props[field] = ctx.refRule.__$info.value;
170
174
  }
171
175
  children[infoProp.align !== 'left' ? 'unshift' : 'push'](this.$r(mergeProps([infoProp, prop]), [
172
176
  this.$r({
@@ -177,17 +181,24 @@ export default {
177
181
  })
178
182
  ]));
179
183
  }
180
- return this.$r(mergeProps([titleProp, {
181
- props: titleProp,
182
- slot: titleProp.slot || 'label',
184
+ const _prop = mergeProps([titleProp, {
185
+ props: tidyRule(titleProp),
183
186
  key: `${uni}tit`,
187
+ class: 'fc-form-title',
188
+ slot: titleProp.slot || 'label',
184
189
  type: titleProp.type || 'span',
185
- }]), children);
190
+ }]);
191
+
192
+ delete _prop.props.show;
193
+ delete _prop.props.title;
194
+ delete _prop.props.native;
195
+
196
+ return this.$r(_prop, children);
186
197
  },
187
198
  makeCol(rule, uni, children) {
188
199
  const col = rule.col;
189
200
  return this.$r({
190
- class: col.class,
201
+ class: this.$render.mergeClass(col.class, 'fc-form-col'),
191
202
  type: 'col',
192
203
  props: col || {span: 24},
193
204
  key: `${uni}col`
@@ -198,7 +209,7 @@ export default {
198
209
  return this.$r({
199
210
  type: 'row',
200
211
  props: row,
201
- class: row.class,
212
+ class: this.$render.mergeClass(row.class, 'fc-form-row'),
202
213
  key: `${this.key}row`
203
214
  }, children)
204
215
  },
@@ -215,6 +226,7 @@ export default {
215
226
  }
216
227
  const item = this.$r({
217
228
  type: 'formItem',
229
+ class: 'fc-form-item',
218
230
  key: `${this.key}fb`
219
231
  }, vn);
220
232
 
@@ -222,43 +234,57 @@ export default {
222
234
  ? item
223
235
  : this.$r({
224
236
  type: 'col',
237
+ class: 'fc-form-col fc-form-footer',
225
238
  props: {span: 24},
226
239
  key: `${this.key}fc`
227
240
  }, [item]);
228
241
  },
242
+
229
243
  makeResetBtn() {
230
- const resetBtn = this.options.resetBtn;
244
+ const resetBtn = {...this.options.resetBtn};
245
+ const innerText = resetBtn.innerText;
246
+ delete resetBtn.innerText;
247
+ delete resetBtn.click;
248
+ delete resetBtn.col;
249
+ delete resetBtn.show;
231
250
  return this.$r({
232
251
  type: 'button',
233
252
  props: resetBtn,
253
+ class: 'fc-reset-btn',
234
254
  style: {width: resetBtn.width},
235
255
  on: {
236
256
  click: () => {
237
257
  const fApi = this.$handle.api;
238
- resetBtn.click
239
- ? resetBtn.click(fApi)
258
+ this.options.resetBtn.click
259
+ ? this.options.resetBtn.click(fApi)
240
260
  : fApi.resetFields();
241
261
  }
242
262
  },
243
263
  key: `${this.key}b2`,
244
- }, [resetBtn.innerText]);
264
+ }, [innerText]);
245
265
  },
246
266
  makeSubmitBtn() {
247
- const submitBtn = this.options.submitBtn;
248
-
267
+ const submitBtn = {...this.options.submitBtn};
268
+ const innerText = submitBtn.innerText;
269
+ delete submitBtn.innerText;
270
+ delete submitBtn.click;
271
+ delete submitBtn.col;
272
+ delete submitBtn.show;
249
273
  return this.$r({
250
274
  type: 'button',
251
275
  props: submitBtn,
276
+ class: 'fc-submit-btn',
252
277
  style: {width: submitBtn.width},
253
278
  on: {
254
279
  click: () => {
255
280
  const fApi = this.$handle.api;
256
- submitBtn.click
257
- ? submitBtn.click(fApi)
258
- : fApi.submit();
281
+ this.options.submitBtn.click
282
+ ? this.options.submitBtn.click(fApi)
283
+ : fApi.submit().catch(() => {
284
+ });
259
285
  }
260
286
  },
261
287
  key: `${this.key}b1`,
262
- }, [submitBtn.innerText]);
288
+ }, [innerText]);
263
289
  }
264
290
  }
@@ -0,0 +1,52 @@
1
+ import is from '@form-create/utils/lib/type';
2
+
3
+ const required = {
4
+ name: 'required',
5
+ load(inject, rule, api) {
6
+ const val = parseVal(inject.getValue());
7
+ if (val.required === false) {
8
+ inject.clearProp();
9
+ api.clearValidateState([rule.field]);
10
+ } else {
11
+ const validate = {
12
+ required: true,
13
+ validator(_, v, call) {
14
+ is.empty(v) ? call(validate.message) : call();
15
+ },
16
+ ...val,
17
+ };
18
+ if (!validate.message) {
19
+ validate.message = rule.__fc__.refRule.__$title.value + (api.getLocale() === 'en' ? ' is required' : '不能为空');
20
+ } else {
21
+ const match = validate.message.match(/^\{\{\s*\$t\.(.+)\s*\}\}$/);
22
+ if (match) {
23
+ validate.message = api.t(match[1], {title: rule.__fc__.refRule.__$title.value});
24
+ }
25
+ }
26
+ inject.getProp().validate = [validate];
27
+ }
28
+ api.sync(rule);
29
+ },
30
+ watch(...args) {
31
+ required.load(...args);
32
+ }
33
+ }
34
+
35
+ function parseVal(val) {
36
+ if (is.Boolean(val)) {
37
+ return {required: val}
38
+ } else if (is.String(val)) {
39
+ return {message: val};
40
+ } else if (is.Undef(val)) {
41
+ return {required: false};
42
+ } else if (is.Function(val)) {
43
+ return {validator: val};
44
+ } else if (!is.Object(val)) {
45
+ return {};
46
+ } else {
47
+ return val;
48
+ }
49
+ }
50
+
51
+
52
+ export default required
@@ -2,6 +2,62 @@
2
2
  margin-bottom: 22px;
3
3
  }
4
4
 
5
- .form-create .form-create .el-form-item .el-form-item {
6
- margin-bottom: 0px;
5
+ .form-create {
6
+ width: 100%;
7
+ }
8
+
9
+ .fc-form-row {
10
+ box-sizing: border-box;
11
+ display: flex;
12
+ flex-wrap: wrap;
13
+ position: relative;
14
+ }
15
+
16
+ .form-create.is-preview .fc-clock, .form-create .fc-none, .form-create.is-preview .el-form-item.is-required > .el-form-item__label-wrap > .el-form-item__label:before, .form-create.is-preview .el-form-item.is-required > .el-form-item__label:before {
17
+ display: none !important;
18
+ }
19
+
20
+ .fc-wrap-right > .el-form-item__label {
21
+ display: flex;
22
+ justify-content: flex-end;
23
+ }
24
+
25
+ .fc-wrap-left > .el-form-item__label {
26
+ display: flex;
27
+ justify-content: flex-start;
28
+ }
29
+
30
+ .fc-wrap-top.el-form-item {
31
+ display: block;
32
+ }
33
+
34
+ .fc-wrap-top.el-form-item > .el-form-item__label {
35
+ display: block;
36
+ height: auto;
37
+ line-height: 22px;
38
+ margin-bottom: 8px;
39
+ text-align: left;
40
+ }
41
+
42
+ .fc-wrap-top.el-form-item > .el-form-item__content {
43
+ margin-left: 0 !important;
44
+ }
45
+
46
+ .el-form--large .fc-wrap-top.el-form-item > .el-form-item__label {
47
+ line-height: 22px;
48
+ margin-bottom: 12px;
49
+ }
50
+
51
+ .el-form--default .fc-wrap-top.el-form-item > .el-form-item__label {
52
+ line-height: 22px;
53
+ margin-bottom: 8px;
54
+ }
55
+
56
+ .el-form--small .fc-wrap-top.el-form-item > .el-form-item__label {
57
+ line-height: 20px;
58
+ margin-bottom: 4px;
59
+ }
60
+
61
+ .fc-form-footer {
62
+ margin-top: 12px;
7
63
  }
package/types/config.d.ts CHANGED
@@ -103,7 +103,7 @@ export interface ApiAttrs {
103
103
 
104
104
  wrapEl(id: string): undefined | ElFormItem;
105
105
 
106
- submit(success: (formData: FormData, api: Api) => void, fail: (api: Api) => void): void;
106
+ submit(success: (formData: FormData, $f: Api) => void, fail: ($f: Api) => void): Promise<any>;
107
107
 
108
108
  clearValidateState(fields?: string | string[], clearSub?: Boolean): void;
109
109