free-fe-core-modules 0.0.4 → 0.0.5

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.
@@ -65,7 +65,7 @@
65
65
  :key="index"
66
66
  :Field="field"
67
67
  :values="fieldsData"
68
- :ref="`input_field_validator_${index}`"
68
+ ref="fieldsToValid"
69
69
  @input="onInputFieldInput(field)"
70
70
  ></free-field>
71
71
  </div>
@@ -101,6 +101,7 @@
101
101
 
102
102
  <script>
103
103
  import { defineComponent } from 'vue';
104
+ import { useFormValidator } from '../../composible/useFormValidator';
104
105
  import FreeField from '../../free-field/composible/fieldWrapper';
105
106
  import EIcon from '../Basic/EIcon.vue';
106
107
 
@@ -153,6 +154,14 @@ export default defineComponent({
153
154
  FreeField,
154
155
  EIcon,
155
156
  },
157
+ setup(props, { expose }) {
158
+ const { validate } = useFormValidator('fieldsToValid');
159
+ expose({
160
+ validate,
161
+ })
162
+
163
+ return {};
164
+ },
156
165
  data() {
157
166
  return {
158
167
  timeLeft: 0,
@@ -0,0 +1,56 @@
1
+ import { unref, getCurrentInstance, computed } from "vue";
2
+
3
+ export function useFormValidator(...list) {
4
+ const { proxy:vm } = getCurrentInstance();
5
+
6
+ return {
7
+ validate: computed(() => {
8
+ return (...args) => {
9
+ if (vm.shouldHide) return true;
10
+
11
+ // could have customized validate function in component
12
+ if (vm.selfValidate && typeof vm.selfValidate === 'function') {
13
+ return vm.selfValidate();
14
+ }
15
+
16
+ const refsList = [];
17
+ for(let i = 0; i < list.length; i += 1) {
18
+ if (typeof list[i] === 'string') {
19
+ list[i] = vm.$refs[list[i]];
20
+ } else if (typeof list[i] === 'function') {
21
+ list[i] = list[i]();
22
+ }
23
+
24
+ if (Array.isArray(list[i])) {
25
+ refsList.push(...list[i])
26
+ } else {
27
+ refsList.push(list[i])
28
+ }
29
+ }
30
+
31
+ if (refsList.length <= 0) return true;
32
+
33
+ let hasErr = false;
34
+ for (let i = 0; i < refsList.length; i += 1) {
35
+ let refi = unref(refsList[i]);
36
+
37
+
38
+ const validFun = unref(refi.validate || refi.methods?.validate || refi.component?.exposed?.validate|| refi.component?.ctx?.validate);
39
+ const shouldHide = unref(refi.shouldHide || refi.component?.ctx?.shouldHide);
40
+
41
+ if (typeof validFun === 'function' && shouldHide !== true) {
42
+ hasErr = !validFun() || hasErr;
43
+
44
+ if (hasErr) {
45
+ console.error('got error', args)
46
+ break;
47
+ }
48
+ }
49
+ }
50
+
51
+ return !hasErr;
52
+ };
53
+ }),
54
+ }
55
+ };
56
+
@@ -1,6 +1,6 @@
1
1
  import { defineComponent, h, ref, getCurrentInstance } from 'vue';
2
- import { useFreeField, freeFieldProps } from '../composible/useFreeField';
3
2
  import { QCheckbox } from 'quasar';
3
+ import { useFreeField, freeFieldProps } from '../composible/useFreeField';
4
4
 
5
5
  export default defineComponent({
6
6
  name: 'InputFieldAgreementCheck',
@@ -21,7 +21,7 @@ export default defineComponent({
21
21
  ...freeFieldProps,
22
22
  },
23
23
  emits: ['input'],
24
- setup(props, { emit }){
24
+ setup(props, { emit, expose }){
25
25
  if (!props.Field) return {};
26
26
 
27
27
  const { proxy:vm } = getCurrentInstance();
@@ -106,6 +106,10 @@ export default defineComponent({
106
106
  return isValid;
107
107
  };
108
108
 
109
+ defineExpose({
110
+ validate,
111
+ })
112
+
109
113
  const checkboxNode = () => h(QCheckbox, {
110
114
  disable: props.Field?.ReadOnly,
111
115
  label: props.Field?.showLabel ? '' : props.Field?.Label,
@@ -1,7 +1,8 @@
1
1
  import { ref, defineComponent, getCurrentInstance, h, computed } from 'vue';
2
- import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
3
2
  import { QInput, QIcon, QPopupProxy, QDate } from 'quasar';
3
+ import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
4
4
  import freeFieldLabel from '../composible/freeFieldLabel';
5
+ import { useFormValidator} from '../../composible/useFormValidator';
5
6
 
6
7
  export default defineComponent({
7
8
  name: 'InputFieldDate',
@@ -40,7 +41,7 @@ export default defineComponent({
40
41
  methods: {
41
42
  ...useFreeFieldMethods,
42
43
  },
43
- setup(props, { emit, slots }){
44
+ setup(props, { emit, slots, expose }){
44
45
  if (!props.Field) return {};
45
46
 
46
47
  const { proxy: vm } = getCurrentInstance();
@@ -80,7 +81,7 @@ export default defineComponent({
80
81
 
81
82
  const showPopup = ref(false);
82
83
 
83
- const DateNode = () => h(QInput, {
84
+ const DateNode = computed(() => h(QInput, {
84
85
  hideBottomSpace: true,
85
86
  readonly: props.Field?.ReadOnly,
86
87
 
@@ -121,12 +122,19 @@ export default defineComponent({
121
122
  class: 'cursor-pointer',
122
123
  name: 'event'
123
124
  }),
124
- });
125
+ }));
126
+
127
+ const {
128
+ validate,
129
+ } = useFormValidator(DateNode);
130
+ expose({
131
+ validate,
132
+ })
125
133
 
126
134
  return () => h('div', {
127
135
  class: 'simple-field input-field-date row items-center no-wrap',
128
136
  }, [
129
- props.Field.ReadOnly ? readonlyNode() : DateNode(),
137
+ props.Field.ReadOnly ? readonlyNode() : DateNode.value,
130
138
  slots.warning && slots.warning(),
131
139
  ]);
132
140
  },
@@ -1,7 +1,8 @@
1
1
  import { ref, defineComponent, getCurrentInstance, h, computed, watch, watchEffect } from 'vue';
2
- import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
3
2
  import { QInput, QIcon, QPopupProxy, QDate } from 'quasar';
3
+ import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
4
4
  import freeFieldLabel from '../composible/freeFieldLabel';
5
+ import { useFormValidator} from '../../composible/useFormValidator';
5
6
 
6
7
  export default defineComponent({
7
8
  name: 'InputFieldDateRange',
@@ -40,7 +41,7 @@ export default defineComponent({
40
41
  methods: {
41
42
  ...useFreeFieldMethods,
42
43
  },
43
- setup(props, { emit, slots }){
44
+ setup(props, { emit, slots, expose }){
44
45
  if (!props.Field) return {};
45
46
 
46
47
  const { proxy: vm } = getCurrentInstance();
@@ -119,7 +120,7 @@ export default defineComponent({
119
120
  const showMaxPopup = ref(false);
120
121
 
121
122
 
122
- const minDateNode = () => h(QInput, {
123
+ const minDateNode = computed(() => h(QInput, {
123
124
  hideBottomSpace: true,
124
125
  readonly: props.Field?.ReadOnly,
125
126
 
@@ -162,9 +163,9 @@ export default defineComponent({
162
163
  class: 'cursor-pointer',
163
164
  name: 'event'
164
165
  }),
165
- });
166
+ }));
166
167
 
167
- const maxDateNode = () => h(QInput, {
168
+ const maxDateNode = computed(() => h(QInput, {
168
169
  hideBottomSpace: true,
169
170
  readonly: props.Field?.ReadOnly,
170
171
 
@@ -206,7 +207,12 @@ export default defineComponent({
206
207
  class: 'cursor-pointer',
207
208
  name: 'event'
208
209
  }),
209
- });
210
+ }));
211
+
212
+ const { validate } = useFormValidator(minDateNode, maxDateNode);
213
+ expose({
214
+ validate,
215
+ })
210
216
 
211
217
  return () => h('div', {
212
218
  class: 'simple-field input-field-date row items-center no-wrap',
@@ -214,11 +220,11 @@ export default defineComponent({
214
220
  props.Field.ReadOnly ? readonlyNode() : h('div', {
215
221
  class: 'row items-center no-wrap'
216
222
  }, [
217
- minDateNode(),
223
+ minDateNode.value,
218
224
  h('span', {
219
225
  class: 'input-field-range-separator'
220
226
  },props.Field.Separator || '~'),
221
- maxDateNode(),
227
+ maxDateNode.value,
222
228
  ]),
223
229
  slots.warning && slots.warning(),
224
230
  ]);
@@ -1,8 +1,9 @@
1
1
  import { ref, defineComponent, getCurrentInstance, h, computed, watchEffect } from 'vue';
2
- import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
3
2
  import { QTable, QTh, QTd, QTr, QIcon } from 'quasar';
3
+ import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
4
4
  import freeFieldLabel from '../composible/freeFieldLabel';
5
5
  import FreeField from '../composible/fieldWrapper';
6
+ import { useFormValidator} from '../../composible/useFormValidator';
6
7
 
7
8
  export default defineComponent({
8
9
  name: 'InputFieldDynamicList',
@@ -424,10 +425,16 @@ export default defineComponent({
424
425
  }
425
426
  };
426
427
 
428
+ const fieldsToValidate = ref([]);
429
+ const {
430
+ validate
431
+ } = useFormValidator(fieldsToValidate);
432
+
427
433
  expose({
428
434
  selected,
429
435
  addRow,
430
436
  deleteRow,
437
+ validate,
431
438
  })
432
439
 
433
440
  watchEffect(() => {
@@ -456,6 +463,22 @@ export default defineComponent({
456
463
  );
457
464
 
458
465
  const bodyCell = (slotProps) => {
466
+ fieldsToValidate.value = slotProps.col?.List?.length > 1 ? slotProps.col.List.map((col) =>
467
+ h(FreeField, {
468
+ Field: columnField(col, true, slotProps.col),
469
+ values: slotProps.row,
470
+ style: "margin: 4px auto",
471
+ onInput: cellChanged,
472
+ })
473
+ ) : [
474
+ h(FreeField, {
475
+ Field: columnField(slotProps.col),
476
+ values: slotProps.row,
477
+ borderless: true,
478
+ onInput: cellChanged,
479
+ }),
480
+ ];
481
+
459
482
  if (slotProps.col.name === "listActions") {
460
483
  return h(QTd, null, {
461
484
  default: () =>
@@ -480,38 +503,15 @@ export default defineComponent({
480
503
  rowspan: slotProps.value ? slotProps.value.rowspan || "1" : "1",
481
504
  class: "items-center justify-center",
482
505
  },
483
- {
484
- default: () =>
485
- slotProps.col.List?.length > 1
486
- ? h(
487
- "span",
488
- {
489
- class: "full-height full-width abcClass",
490
- },
491
- slotProps.col.List.map((col) =>
492
- h(FreeField, {
493
- Field: columnField(col, true, slotProps.col),
494
- values: slotProps.row,
495
- style: "margin: 4px auto",
496
- onInput: cellChanged,
497
- })
498
- )
499
- )
500
- : h(
501
- "span",
502
- {
503
- class: "full-height full-width defClass",
504
- },
505
- [
506
- h(FreeField, {
507
- Field: columnField(slotProps.col),
508
- values: slotProps.row,
509
- borderless: true,
510
- onInput: cellChanged,
511
- }),
512
- ]
513
- ),
514
- }
506
+ [
507
+ h(
508
+ "span",
509
+ {
510
+ class: "full-height full-width",
511
+ },
512
+ fieldsToValidate.value,
513
+ )
514
+ ]
515
515
  );
516
516
  }
517
517
  };
@@ -45,8 +45,7 @@
45
45
  :Field="columnField(col, true, props.col)"
46
46
  :values="props.row"
47
47
  @input="cellChanged()"
48
- :ref="`input_field_validator_${
49
- columnField(col, true, props.col).Name}-${index}-${props.row.auto__index}`"
48
+ ref="fieldsToValid"
50
49
  ></free-field>
51
50
  </span>
52
51
  <span v-else class="full-width full-height">
@@ -55,8 +54,7 @@
55
54
  :values="props.row"
56
55
  @input="cellChanged()"
57
56
  borderless
58
- :ref="`input_field_validator_${
59
- columnField(props.col, false).Name}-${props.row.auto__index}`"
57
+ ref="fieldToValid"
60
58
  ></free-field>
61
59
  </span>
62
60
  </q-td>
@@ -74,6 +72,7 @@
74
72
  <script>
75
73
  import { defineComponent, watchEffect, ref, computed } from 'vue';
76
74
  import { useFreeField, freeFieldProps } from '../composible/useFreeField';
75
+ import { useFormValidator} from '../../composible/useFormValidator';
77
76
 
78
77
  export default defineComponent({
79
78
  name: 'InputFieldFixedList',
@@ -205,7 +204,7 @@ export default defineComponent({
205
204
  props: {
206
205
  ...freeFieldProps,
207
206
  },
208
- setup(props, { emit }) {
207
+ setup(props, { emit, expose }) {
209
208
  if (!props.Field) return {};
210
209
 
211
210
  const { fieldData, setFieldData } = useFreeField(props);
@@ -341,6 +340,11 @@ export default defineComponent({
341
340
  setFieldData(tableData.value, emit);
342
341
  };
343
342
 
343
+ const { validate } = useFormValidator('fieldsToValid', 'fieldToValid')
344
+ expose({
345
+ validate,
346
+ })
347
+
344
348
  return {
345
349
  fieldData,
346
350
  tableData,
@@ -87,6 +87,7 @@
87
87
  <script>
88
88
  import { defineComponent } from 'vue';
89
89
  import { useFreeField, freeFieldProps } from '../composible/useFreeField';
90
+ import { useFormValidator} from '../../composible/useFormValidator';
90
91
 
91
92
  export default defineComponent({
92
93
  name: 'InputFieldLabels',
@@ -114,9 +115,14 @@ export default defineComponent({
114
115
  newLabel: '',
115
116
  };
116
117
  },
117
- setup(props) {
118
+ setup(props, { expose }) {
118
119
  const { fieldData, setFieldData } = useFreeField(props);
119
120
 
121
+ const { validate } = useFormValidator('input_field_validator_label');
122
+ expose({
123
+ validate,
124
+ });
125
+
120
126
  return {
121
127
  fieldData,
122
128
  setFieldData,
@@ -54,7 +54,7 @@
54
54
  :Field="{...f, ReadOnly: Field.ReadOnly || f.ReadOnly}"
55
55
  :values="fieldData.value"
56
56
  @input="cellChanged(f)"
57
- :ref="`input_field_validator_${index}`"
57
+ ref="fieldsToValid"
58
58
  ></free-field>
59
59
  </span>
60
60
  <span
@@ -66,7 +66,7 @@
66
66
  :values="fieldData.value"
67
67
  @input="cellChanged(r[rk].List[0])"
68
68
  borderless
69
- :ref="`input_field_validator_extra_${index}`"
69
+ ref="fieldToValid"
70
70
  ></free-field>
71
71
  </span>
72
72
  </q-td>
@@ -91,6 +91,7 @@
91
91
  <script>
92
92
  import { computed, defineComponent } from 'vue';
93
93
  import { useFreeField, freeFieldProps } from '../composible/useFreeField';
94
+ import { useFormValidator} from '../../composible/useFormValidator';
94
95
 
95
96
  export default defineComponent({
96
97
  name: 'InputFieldMixedTable',
@@ -271,7 +272,7 @@ export default defineComponent({
271
272
  props: {
272
273
  ...freeFieldProps,
273
274
  },
274
- setup(props, { emit }) {
275
+ setup(props, { emit, expose }) {
275
276
  if (!props.Field) return () => null;
276
277
 
277
278
  const { fieldData, setFieldData } = useFreeField(props);
@@ -342,6 +343,11 @@ export default defineComponent({
342
343
  return summaryText;
343
344
  });
344
345
 
346
+ const { validate } = useFormValidator('fieldsToValid', 'fieldToValid');
347
+ expose({
348
+ validate,
349
+ });
350
+
345
351
  return {
346
352
  fieldData,
347
353
  setFieldData,
@@ -1,8 +1,9 @@
1
- import { defineComponent, h, watch } from 'vue';
2
- import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
1
+ import { defineComponent, h, watch, computed } from 'vue';
3
2
  import { QInput } from 'quasar';
3
+ import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
4
4
  import ReadonlyContent from '../composible/readonlyContent';
5
5
  import freeFieldLabel from '../composible/freeFieldLabel';
6
+ import { useFormValidator} from '../../composible/useFormValidator';
6
7
 
7
8
  export default defineComponent({
8
9
  name: 'InputFieldNumber',
@@ -95,7 +96,7 @@ export default defineComponent({
95
96
  methods: {
96
97
  ...useFreeFieldMethods,
97
98
  },
98
- setup(props, { emit, slots }){
99
+ setup(props, { emit, slots , expose }){
99
100
  if (!props.Field) return {};
100
101
 
101
102
  const { fieldData, setFieldData } = useFreeField(props);
@@ -134,7 +135,7 @@ export default defineComponent({
134
135
  class: 'postfix',
135
136
  }, props.Field.Options?.Postfix));
136
137
 
137
- const inputNode = () => h(QInput, {
138
+ const inputNode = computed(() => h(QInput, {
138
139
  type: 'number',
139
140
  maxlength: props.Field.Options?.MaxLength,
140
141
  autocomplete: 'off',
@@ -155,12 +156,17 @@ export default defineComponent({
155
156
  before,
156
157
  prepend,
157
158
  append,
158
- });
159
+ }));
160
+
161
+ const { validate } = useFormValidator(inputNode);
162
+ expose({
163
+ validate,
164
+ })
159
165
 
160
166
  return () => h('div', {
161
167
  class: 'simple-field input-field-number row items-center no-wrap',
162
168
  }, [
163
- props.Field.ReadOnly ? readonlyNode() : inputNode(),
169
+ props.Field.ReadOnly ? readonlyNode() : inputNode.value,
164
170
  slots.warning && slots.warning(),
165
171
  ]);
166
172
  },
@@ -1,7 +1,8 @@
1
- import { defineComponent, h, ref } from 'vue';
2
- import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
1
+ import { defineComponent, h, ref, computed } from 'vue';
3
2
  import { QInput, QIcon } from 'quasar';
3
+ import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
4
4
  import freeFieldLabel from '../composible/freeFieldLabel';
5
+ import { useFormValidator} from '../../composible/useFormValidator';
5
6
 
6
7
  export default defineComponent({
7
8
  name: 'InputFieldPassword',
@@ -31,7 +32,7 @@ export default defineComponent({
31
32
  methods: {
32
33
  ...useFreeFieldMethods,
33
34
  },
34
- setup(props, { emit, slots }){
35
+ setup(props, { emit, slots, expose }){
35
36
  if (!props.Field) return {};
36
37
 
37
38
  const { fieldData, setFieldData } = useFreeField(props);
@@ -49,7 +50,7 @@ export default defineComponent({
49
50
  },
50
51
  });
51
52
 
52
- const inputNode = () => h(QInput, {
53
+ const inputNode = () => computed(h(QInput, {
53
54
  type: isPwd.value ? 'password' : 'text',
54
55
  maxlength: props.Field.Options?.MaxLength,
55
56
  autocomplete: props.Field.Options?.autocomplete ? '' : 'new-password',
@@ -69,12 +70,17 @@ export default defineComponent({
69
70
  }, {
70
71
  before,
71
72
  append,
72
- });
73
+ }));
74
+
75
+ const { validate } = useFormValidator(inputNode);
76
+ expose({
77
+ validate,
78
+ })
73
79
 
74
80
  return () => h('div', {
75
81
  class: 'simple-field input-field-password row items-center no-wrap',
76
82
  }, [
77
- inputNode(),
83
+ inputNode.value,
78
84
  slots.warning && slots.warning(),
79
85
  ]);
80
86
  },
@@ -127,7 +127,7 @@
127
127
  readonly
128
128
  :class="`${Field && Field.Multiple
129
129
  ? '' : 'simple-field'} ${searchDisplay ? 'has-data' : 'empty'}`"
130
- :ref="`input_field_validator_${Field.Name || Field.Label}`"
130
+ ref="fieldToValid"
131
131
  @click="searchKey = '';searchData = {}; showSearch = true"
132
132
  >
133
133
  <template v-slot:prepend>
@@ -175,6 +175,7 @@
175
175
  <script>
176
176
  import { defineComponent } from 'vue';
177
177
  import { useFreeField, freeFieldProps } from '../composible/useFreeField';
178
+ import { useFormValidator} from '../../composible/useFormValidator';
178
179
 
179
180
  export default defineComponent({
180
181
  name: 'InputFieldSearch',
@@ -286,11 +287,16 @@ export default defineComponent({
286
287
  ],
287
288
  Description: '',
288
289
  },
289
- setup(props) {
290
+ setup(props, { expose }) {
290
291
  if (!props.Field) return {};
291
292
 
292
293
  const { fieldData, setFieldData } = useFreeField(props);
293
294
 
295
+ const { validate } = useFormValidator('fieldToValid');
296
+ expose({
297
+ validate,
298
+ })
299
+
294
300
  return {
295
301
  fieldData,
296
302
  setFieldData,
@@ -55,7 +55,7 @@
55
55
  emit-value
56
56
  :multiple="Field.Multiple"
57
57
  :readonly="Field.ReadOnly"
58
- :ref="`input_field_validator_${Field.Name || Field.Label}`"
58
+ ref="fieldToValid"
59
59
  :use-input="Field && Field.UseInput"
60
60
  :use-chip="Field && Field.UseChip"
61
61
  >
@@ -156,6 +156,7 @@
156
156
  <script>
157
157
  import { ref, computed, defineComponent, getCurrentInstance, watch, watchEffect } from 'vue';
158
158
  import { useFreeField, freeFieldProps } from '../composible/useFreeField';
159
+ import { useFormValidator} from '../../composible/useFormValidator';
159
160
 
160
161
  export default defineComponent({
161
162
  name: 'InputFieldSelect',
@@ -304,8 +305,10 @@ export default defineComponent({
304
305
  return true;
305
306
  };
306
307
 
308
+ const { validate } = useFormValidator('fieldToValid');
307
309
  expose ({
308
310
  selfValidate,
311
+ validate,
309
312
  })
310
313
 
311
314
  const checkChanged = (v) => {
@@ -34,7 +34,7 @@
34
34
  :label="valuesList[index] ? '' : option.Placeholder"
35
35
  emit-value
36
36
  @input="selectionChanged(index)"
37
- :ref="`input_field_validator_${index}`"
37
+ ref="fieldsToValid"
38
38
  ></q-select>
39
39
  </span>
40
40
  <span v-if="Field && Field.ReadOnly">
@@ -56,6 +56,7 @@
56
56
  <script>
57
57
  import { defineComponent, ref, watch, getCurrentInstance, } from 'vue';
58
58
  import { useFreeField, freeFieldProps } from '../composible/useFreeField';
59
+ import { useFormValidator} from '../../composible/useFormValidator';
59
60
 
60
61
  export default defineComponent({
61
62
  name: 'InputFieldSelectChain',
@@ -113,7 +114,7 @@ export default defineComponent({
113
114
  ],
114
115
  Description: '',
115
116
  },
116
- setup(props, { emit }) {
117
+ setup(props, { emit, expose }) {
117
118
  if (!props.Field) return () => null;
118
119
 
119
120
  const { proxy:vm } = getCurrentInstance();
@@ -202,6 +203,11 @@ export default defineComponent({
202
203
  initOptions();
203
204
  });
204
205
 
206
+ const { validate } = useFormValidator('fieldsToValid');
207
+ expose ({
208
+ validate,
209
+ })
210
+
205
211
  return {
206
212
  fieldData,
207
213
  setFieldData,
@@ -1,8 +1,9 @@
1
- import { defineComponent, h } from 'vue';
1
+ import { defineComponent, h, computed } from 'vue';
2
2
  import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
3
3
  import { QInput } from 'quasar';
4
4
  import ReadonlyContent from '../composible/readonlyContent';
5
5
  import freeFieldLabel from '../composible/freeFieldLabel';
6
+ import { useFormValidator} from '../../composible/useFormValidator';
6
7
 
7
8
  export default defineComponent({
8
9
  name: 'InputFieldString',
@@ -51,7 +52,7 @@ export default defineComponent({
51
52
  methods: {
52
53
  ...useFreeFieldMethods,
53
54
  },
54
- setup(props, { emit, slots }){
55
+ setup(props, { emit, slots, expose }){
55
56
  if (!props.Field) return {};
56
57
 
57
58
  const { fieldData, setFieldData } = useFreeField(props);
@@ -73,7 +74,7 @@ export default defineComponent({
73
74
  class: 'postfix',
74
75
  }, props.Field.Options?.Postfix));
75
76
 
76
- const inputNode = () => h(QInput, {
77
+ const inputNode = computed(() => h(QInput, {
77
78
  maxlength: props.Field.Options?.MaxLength,
78
79
  autocomplete: 'off',
79
80
  // bottomSlots: true,
@@ -93,12 +94,17 @@ export default defineComponent({
93
94
  before,
94
95
  prepend,
95
96
  append,
96
- });
97
+ }));
98
+
99
+ const { validate } = useFormValidator(inputNode);
100
+ expose({
101
+ validate,
102
+ })
97
103
 
98
104
  return () => h('div', {
99
105
  class: 'simple-field input-field-string row items-center no-wrap',
100
106
  }, [
101
- props.Field.ReadOnly ? readonlyNode() : inputNode(),
107
+ props.Field.ReadOnly ? readonlyNode() : inputNode.value,
102
108
  slots.warning && slots.warning(),
103
109
  ]);
104
110
  },
@@ -1,8 +1,9 @@
1
- import { defineComponent, h, ref, watchEffect } from 'vue';
2
- import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
1
+ import { defineComponent, h, ref, watchEffect, computed } from 'vue';
3
2
  import { QInput } from 'quasar';
3
+ import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
4
4
  import ReadonlyContent from '../composible/readonlyContent';
5
5
  import freeFieldLabel from '../composible/freeFieldLabel';
6
+ import { useFormValidator} from '../../composible/useFormValidator';
6
7
 
7
8
  export default defineComponent({
8
9
  name: 'InputFieldText',
@@ -26,7 +27,7 @@ export default defineComponent({
26
27
  methods: {
27
28
  ...useFreeFieldMethods,
28
29
  },
29
- setup(props, { emit, slots }){
30
+ setup(props, { emit, slots, expose }){
30
31
  if (!props.Field) return {};
31
32
 
32
33
  const { fieldData, setFieldData } = useFreeField(props);
@@ -48,7 +49,7 @@ export default defineComponent({
48
49
  Field: props.Field,
49
50
  });
50
51
 
51
- const inputNode = () => h(QInput, {
52
+ const inputNode = computed(() => h(QInput, {
52
53
  type: 'textarea',
53
54
  maxlength: props.Field.Options?.MaxLength,
54
55
  hideBottomSpace: true,
@@ -66,7 +67,12 @@ export default defineComponent({
66
67
  },
67
68
  }, {
68
69
  before,
69
- });
70
+ }));
71
+
72
+ const { validate } = useFormValidator(inputNode);
73
+ expose ({
74
+ validate,
75
+ })
70
76
 
71
77
  return () => h('div', {
72
78
  class: 'input-field-text',
@@ -74,7 +80,7 @@ export default defineComponent({
74
80
  slots.warning && h('div', {
75
81
  class: props.Field.Label ? 'warning-with-label' : 'warning-without-label',
76
82
  }, slots.warning()),
77
- props.Field.ReadOnly ? readonlyNode() : inputNode(),
83
+ props.Field.ReadOnly ? readonlyNode() : inputNode.value,
78
84
  ]);
79
85
  },
80
86
  });
@@ -14,7 +14,7 @@
14
14
  <q-input v-else v-model="fieldData.value" hide-bottom-space
15
15
  :readonly="Field.ReadOnly"
16
16
  @input="$emit('input')"
17
- :ref="`input_field_validator_${Field.Name || Field.Label}`">
17
+ ref="fieldToValid">
18
18
  <template v-slot:before v-if="Field.Label !== void 0">
19
19
  <span
20
20
  :class="`field-label ${(Field.Label && Field.Label.trim().length)
@@ -56,6 +56,7 @@
56
56
  <script>
57
57
  import { computed, defineComponent, getCurrentInstance } from 'vue';
58
58
  import { useFreeField, freeFieldProps } from '../composible/useFreeField';
59
+ import { useFormValidator} from '../../composible/useFormValidator';
59
60
 
60
61
  export default defineComponent({
61
62
  name: 'InputFieldTime',
@@ -91,7 +92,7 @@ export default defineComponent({
91
92
  ...freeFieldProps,
92
93
  },
93
94
  emits:['input'],
94
- setup(props, { emit }) {
95
+ setup(props, { emit, expose }) {
95
96
  if (!props.Field) return () => null;
96
97
 
97
98
  const { proxy:vm } = getCurrentInstance();
@@ -158,6 +159,11 @@ export default defineComponent({
158
159
  };
159
160
  });
160
161
 
162
+ const { validate } = useFormValidator('fieldToValid');
163
+ expose ({
164
+ validate,
165
+ })
166
+
161
167
  return {
162
168
  fieldData,
163
169
  locale,
@@ -27,7 +27,7 @@
27
27
  v-model="min"
28
28
  hide-bottom-space
29
29
  :readonly="Field.ReadOnly"
30
- :ref="`input_field_validator_first`"
30
+ ref="input_field_validator_first"
31
31
  >
32
32
  <q-popup-proxy
33
33
  v-if="!Field.ReadOnly"
@@ -62,7 +62,7 @@
62
62
  v-model="max"
63
63
  hide-bottom-space
64
64
  :readonly="Field.ReadOnly"
65
- :ref="`input_field_validator_second`"
65
+ ref="input_field_validator_second"
66
66
  >
67
67
  <q-popup-proxy
68
68
  v-if="!Field.ReadOnly"
@@ -98,6 +98,7 @@
98
98
  <script>
99
99
  import { defineComponent, ref, getCurrentInstance } from 'vue';
100
100
  import { useFreeField, freeFieldProps } from '../composible/useFreeField';
101
+ import { useFormValidator} from '../../composible/useFormValidator';
101
102
 
102
103
  export default defineComponent({
103
104
  name: 'InputFieldTimeRange',
@@ -155,7 +156,7 @@ export default defineComponent({
155
156
  ],
156
157
  Description: '',
157
158
  },
158
- setup(props, { emit }) {
159
+ setup(props, { emit, expose }) {
159
160
  if (!props.Field) return () => null;
160
161
 
161
162
  const { proxy:vm } = getCurrentInstance();
@@ -342,6 +343,11 @@ export default defineComponent({
342
343
  };
343
344
  });
344
345
 
346
+ const { validate } = useFormValidator('input_field_validator_first', 'input_field_validator_second');
347
+ expose ({
348
+ validate,
349
+ })
350
+
345
351
  return {
346
352
  fieldData,
347
353
  locale,
@@ -1,7 +1,8 @@
1
- import { ref, defineComponent, getCurrentInstance, h, computed } from 'vue';
2
- import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
1
+ import { defineComponent, h, computed } from 'vue';
3
2
  import { QSelect } from 'quasar';
3
+ import { useFreeField, freeFieldProps, useFreeFieldMethods } from '../composible/useFreeField';
4
4
  import freeFieldLabel from '../composible/freeFieldLabel';
5
+ import { useFormValidator} from '../../composible/useFormValidator';
5
6
 
6
7
  export default defineComponent({
7
8
  name: 'InputFieldYear',
@@ -74,7 +75,7 @@ export default defineComponent({
74
75
  methods: {
75
76
  ...useFreeFieldMethods,
76
77
  },
77
- setup(props, { emit, slots }){
78
+ setup(props, { emit, slots, expose }){
78
79
  if (!props.Field) return {};
79
80
 
80
81
  const { fieldData, setFieldData } = useFreeField(props);
@@ -107,7 +108,7 @@ export default defineComponent({
107
108
  return options;
108
109
  });
109
110
 
110
- const selectNode = () => h(QSelect, {
111
+ const selectNode = computed(() => h(QSelect, {
111
112
  hideBottomSpace: true,
112
113
  readonly: props.Field?.ReadOnly,
113
114
  'map-options': true,
@@ -125,12 +126,17 @@ export default defineComponent({
125
126
  },
126
127
  }, {
127
128
  before,
128
- });
129
+ }));
130
+
131
+ const { validate } = useFormValidator(selectNode);
132
+ expose ({
133
+ validate,
134
+ })
129
135
 
130
136
  return () => h('div', {
131
137
  class: 'simple-field input-field-year row items-center no-wrap',
132
138
  }, [
133
- selectNode(),
139
+ selectNode.value,
134
140
  slots.warning && slots.warning(),
135
141
  ]);
136
142
  },
@@ -19,7 +19,7 @@
19
19
  :options="minYearOptions"
20
20
  :readonly="Field.ReadOnly"
21
21
  @input="rangeChanged"
22
- :ref="`input_field_validator_first`"
22
+ ref="input_field_validator_first"
23
23
  >
24
24
  <template v-slot:before v-if="Field.Label !== void 0">
25
25
  <span
@@ -39,7 +39,7 @@
39
39
  :options="maxYearOptions"
40
40
  :readonly="Field.ReadOnly"
41
41
  @input="rangeChanged"
42
- :ref="`input_field_validator_second`"
42
+ ref="input_field_validator_second"
43
43
  />
44
44
  </span>
45
45
 
@@ -48,8 +48,9 @@
48
48
  </template>
49
49
 
50
50
  <script>
51
- import { defineComponent, ref, getCurrentInstance } from 'vue';
51
+ import { defineComponent, ref } from 'vue';
52
52
  import { useFreeField, freeFieldProps } from '../composible/useFreeField';
53
+ import { useFormValidator} from '../../composible/useFormValidator';
53
54
 
54
55
  export default defineComponent({
55
56
  name: 'InputFieldYearRange',
@@ -85,11 +86,9 @@ export default defineComponent({
85
86
  ...freeFieldProps,
86
87
  },
87
88
  emits:['input'],
88
- setup(props, { emit }) {
89
+ setup(props, { emit, expose }) {
89
90
  if (!props.Field) return () => null;
90
91
 
91
- const { proxy:vm } = getCurrentInstance();
92
-
93
92
  const { fieldData, setFieldData } = useFreeField(props);
94
93
 
95
94
  const min = ref('');
@@ -163,6 +162,10 @@ export default defineComponent({
163
162
  return options;
164
163
  });
165
164
 
165
+ const { validate } = useFormValidator('input_field_validator_first', 'input_field_validator_second');
166
+ expose ({
167
+ validate,
168
+ })
166
169
 
167
170
  return {
168
171
  fieldData,
@@ -3,7 +3,7 @@ import {
3
3
  getCurrentInstance,
4
4
  h,
5
5
  ref,
6
- reactive,
6
+ shallowRef,
7
7
  watchEffect,
8
8
  computed,
9
9
  onMounted,
@@ -11,6 +11,8 @@ import {
11
11
  isRef,
12
12
  } from "vue";
13
13
  import { freeFieldProps } from "./useFreeField";
14
+ import { useFormValidator } from '../../composible/useFormValidator';
15
+
14
16
 
15
17
  export default defineComponent({
16
18
  name: "FreeFieldWrapper",
@@ -111,7 +113,7 @@ export default defineComponent({
111
113
  return props.Field.Hidden;
112
114
  });
113
115
 
114
- let realComponent = reactive({});
116
+ let realComponent = shallowRef(null);
115
117
 
116
118
  watchEffect(() => {
117
119
  const fComponents = vm.ctx.FieldComponents || {};
@@ -131,7 +133,7 @@ export default defineComponent({
131
133
  }
132
134
  }
133
135
 
134
- realComponent = field;
136
+ realComponent.value = field;
135
137
  });
136
138
 
137
139
  if (props.Field && props.Field.Info && props.Field.Info.KeepChanged) {
@@ -153,20 +155,23 @@ export default defineComponent({
153
155
  const warningSlot = (!props.noWarning && localField.value.Warning)
154
156
  && h('span', {
155
157
  class: 'input-field-warning no-wrap',
156
- },[
158
+ },
159
+ [
157
160
  h('span', { class: 'input-field-warning-icon' }),
158
161
  h('span', { class: 'input-field-warning-icon-sign-top' }),
159
162
  h('span', { class: 'input-field-warning-icon-sign-dot' }),
160
163
  h('span', { class: 'input-field-warning-text ellipsis' }, localField.value.Warning),
161
- ]);
164
+ ]
165
+ );
162
166
 
163
- if (realComponent) {
164
- const compEmits = {};
165
- (realComponent.emits || []).forEach((em) => {
166
- if (!em || em === 'input') return;
167
167
 
168
+ const compEmits = ref({});
169
+ watchEffect(() => {
170
+ (realComponent?.value?.emits || []).forEach((em) => {
171
+ if (!em || em === 'input') return;
172
+
168
173
  const captEm = `${em[0].toUpperCase()}${em.substring(1)}`;
169
- compEmits[`on${captEm}`] = (...args) => {
174
+ compEmits.value[`on${captEm}`] = (...args) => {
170
175
  // should not emit event directly as we were not inlucde these events in the emits list
171
176
  // but we could get any matched handller from the parent component and then call that
172
177
  // handller directly
@@ -176,46 +181,49 @@ export default defineComponent({
176
181
  outerHandller(...args);
177
182
  }
178
183
  };
179
- })
180
-
181
- const emitsRef = ref(realComponent.emits);
182
-
183
- expose ({
184
- emits: emitsRef,
185
- })
186
-
187
-
188
- return () =>
189
- h(
190
- "div",
191
- {
192
- class: wrapperClass,
193
- },
194
- [
195
- h(
196
- realComponent,
197
- {
198
- Field: localField.value,
199
- values: props.values,
200
- style: shouldHide.value ? "display:none;" : "",
201
- class: [
202
- props.Field.ReadOnly ? "free-field--readonly" : "",
203
- !shouldHide.value && hasError.value ? "hasError" : "",
204
- ],
205
- onInput: () => {
206
- emit("input", props.Field);
207
- },
208
- ...compEmits,
209
- },
210
- {
211
- ...slots,
212
- warning: slots.warning ? slots.warning : () => warningSlot,
213
- }
214
- ),
215
- ]
216
- );
217
- } else {
218
- return () => null;
219
- }
184
+ });
185
+ })
186
+
187
+ const readComp = computed(() => realComponent.value && h(
188
+ realComponent.value,
189
+ {
190
+ Field: localField.value,
191
+ values: props.values,
192
+ style: shouldHide.value ? "display:none;" : "",
193
+ class: [
194
+ props.Field.ReadOnly ? "free-field--readonly" : "",
195
+ !shouldHide.value && hasError.value ? "hasError" : "",
196
+ ],
197
+ onInput: () => {
198
+ emit("input", props.Field);
199
+ },
200
+ ...compEmits,
201
+ },
202
+ {
203
+ ...slots,
204
+ warning: slots.warning ? slots.warning : () => warningSlot,
205
+ }
206
+ ));
207
+
208
+ // const emitsRef = computed(() => realComponent?.value?.emits);
209
+
210
+ const {
211
+ validate,
212
+ } = useFormValidator(readComp);
213
+
214
+ expose ({
215
+ // emits: emitsRef.value,
216
+ validate: () => validate.value(props.Field.Name),
217
+ })
218
+
219
+ return realComponent.value ? () => h(
220
+ "div",
221
+ {
222
+ class: wrapperClass,
223
+ },
224
+ [
225
+ readComp.value,
226
+ ]
227
+ ) : () => null;
220
228
  },
221
229
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "free-fe-core-modules",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "main": "index.js",
5
5
  "repository": "git@gitlab.com:eis-base/modules/free-fe-core-modules.git",
6
6
  "author": "zhiquan",
@@ -56,7 +56,7 @@
56
56
  :key="fIndex"
57
57
  :values="editingMenu"
58
58
  :Field="field"
59
- :ref="`input_field_validator_${field.Name || field.Label}`"
59
+ ref="refsToValid"
60
60
  ></free-field>
61
61
 
62
62
  <div class="action-btns full-width row justify-center q-gutter-md">
@@ -86,12 +86,12 @@
86
86
  </template>
87
87
 
88
88
  <script>
89
- import { defineComponent } from 'vue';
89
+ import { defineComponent, ref } from 'vue';
90
90
  import { useObjectData, objectDataProps } from '../../composible/useObjectData';
91
+ import { useFormValidator } from '../../composible/useFormValidator';
91
92
 
92
93
  export default defineComponent({
93
94
  name: 'MenuPage',
94
- // mixins: [mixins.InputFieldValidator],
95
95
  props: {
96
96
  ...objectDataProps,
97
97
  addMenu: { type: Function, default: () => { } },
@@ -99,24 +99,28 @@ export default defineComponent({
99
99
  deleteMenu: { type: Function, default: () => { } },
100
100
  },
101
101
  setup(props, ctx) {
102
+ const selectedMenuNode = ref({});
103
+ const editingMenu = ref({});
104
+ const menuFields = ref([]);
105
+
102
106
  const {
103
107
  data,
104
108
  refreshData,
105
109
  } = useObjectData(props, ctx);
106
110
 
111
+ const {
112
+ validate,
113
+ } = useFormValidator('refsToValid');
114
+
107
115
  return {
116
+ selectedMenuNode,
117
+ editingMenu,
118
+ menuFields,
108
119
  data,
109
120
  refreshData,
121
+ validate,
110
122
  };
111
123
  },
112
- data() {
113
- return {
114
- selectedMenuNode: {},
115
- editingMenu: {},
116
- menuFields: [],
117
- };
118
- },
119
- watch: {},
120
124
  created() {
121
125
  this.menuFields = this.getModule('core-modules').config.menuFields;
122
126