rb-document-form-constructor 0.8.60 → 0.8.62

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.
@@ -1,289 +1,289 @@
1
- <template>
2
- <b-form v-if="formConfig" class="rb-doc-form">
3
- <b-container
4
- v-if="formConfig && formConfig.sections"
5
- v-for="section in formConfig.sections"
6
- :key="section.labelRu"
7
- class="rb-form-section"
8
- >
9
- <b-row>
10
- <b-col lg="12">
11
- <h4>{{ getDisplayField(section) }}</h4>
12
- </b-col>
13
- <template v-for="column in section.columns">
14
- <b-col :key="column.index" :lg="getColumnSize(section)" :sm="12">
15
- <template v-for="field in column.fields">
16
- {{ field.valueName }}
17
- <b-form-row :key="field.name" v-if="field.visible">
18
- <b-col lg="12">
19
- <b-form-group
20
- :data-field="field.name"
21
- :state="validationState[field.name]"
22
- :invalid-feedback="validationState[`${field.name}__feedback`]"
23
- ref="inputContainer"
24
- >
25
- <component
26
- v-bind:is="field.input.type"
27
- v-model="doc[field.name]"
28
- :resolve-value="getResolveValue(field)"
29
- :disabled="!editable || !field.editable"
30
- :id="field.name"
31
- :state="validationState[field.name]"
32
- :ref="field.ref? field.ref: field.name"
33
- :required="field.required"
34
- @hook:created="onEventFired('created', $event, field)"
35
- @hook:destroyed="onEventFired('destroyed', $event, field)"
36
- @hook:activated="onEventFired('activated', $event, field)"
37
- @hook:mounted="onEventFired('mounted', $event, field)"
38
- @input="onEventFired('input', $event, field)"
39
- @change="onEventFired('change', $event, field)"
40
- @click="onEventFired('click', $event, field)"
41
- @set-resolve-value="setResolveValue"
42
- v-bind="field.input.propsData"
43
- ></component>
44
- <template #label>
45
- <span :title="getDisplayField(field)">{{ getDisplayField(field) }}</span>
46
- <span v-if="showRequiredInLabel && field.required" class="text-danger"
47
- >*</span
48
- >
49
- </template>
50
- </b-form-group>
51
- </b-col>
52
- </b-form-row>
53
- </template>
54
- </b-col>
55
- </template>
56
- </b-row>
57
- </b-container>
58
- </b-form>
59
- </template>
60
-
61
- <script>
62
- import Vue from 'vue';
63
- import {UtFormConstructor} from '../utils/UtFormConstructor';
64
- import typeOf from 'typeof';
65
- import {UtFormConfig} from '@/utils/UtFormConfig';
66
- // import safeEval from "notevil";
67
-
68
- export default {
69
- name: 'DocForm',
70
- props: {
71
- formConfig: Object,
72
- applyDefaultValues: {type: Boolean, default: true},
73
- doc: {type: Object, default: () => ({})},
74
- refSuffix: {type: String, default: 'Id'},
75
- editable: {type: Boolean, default: true},
76
- displayField: {type: String, default: 'labelRu'},
77
- showRequiredInLabel: {type: Boolean, default: true},
78
- },
79
- data() {
80
- return {
81
- validationState: {},
82
- };
83
- },
84
- watch: {
85
- formConfig() {
86
- this.validationState = {};
87
- this.execApplyDefaultValues();
88
- this.execApplyDefaultValRule();
89
- },
90
- },
91
- methods: {
92
- getResolveValueName(field) {
93
- if ((field.dict || field.ref) && !field.multiple) {
94
- return field.name.substring(0, field.name.length - 2);
95
- }
96
- return field.name;
97
- },
98
- getResolveValue(field) {
99
- return this.doc[this.getResolveValueName(field)]
100
- ? this.doc[this.getResolveValueName(field)]
101
- : null;
102
- },
103
- setResolveValue({field, multiple = false}) {
104
- let resolveValue = this.getResolveValue(field);
105
- if (resolveValue && !multiple) {
106
- resolveValue = null;
107
- }
108
- },
109
- getDisplayField(value) {
110
- if (!value[this.displayField]) {
111
- return value.labelRu
112
- } else {
113
- return value[this.displayField]
114
- }
115
- },
116
- onEventFired(eventName, event, field) {
117
- if (eventName === 'input' && field.ref && !field.multiple) {
118
- let dataField = null;
119
- if (field.name.lastIndexOf(this.refSuffix) >= 0) {
120
- dataField = field.name.substring(0, field.name.lastIndexOf(this.refSuffix));
121
- }
122
-
123
- if (dataField && dataField.length > 0) {
124
- this.doc[dataField] = null;
125
- }
126
- }
127
-
128
- if (field.rules) {
129
- field.rules.forEach((rule) => {
130
- if (rule.event === eventName && rule.script) {
131
- this.runRule(rule, {event, eventName});
132
- }
133
- });
134
- }
135
- },
136
- onGlobalEventFired(eventName, event) {
137
- let fields = UtFormConfig.getFields(this.formConfig);
138
- fields.forEach((f) => {
139
- if (f.rules) {
140
- f.rules.forEach((r) => {
141
- if (r.event === eventName) {
142
- this.runRule(r, {event, eventName});
143
- }
144
- });
145
- }
146
- });
147
- },
148
- createRuleContext(additionalContext) {
149
- return Object.assign(
150
- {
151
- form: this,
152
- doc: this.doc,
153
- ...additionalContext,
154
- },
155
- UtFormConstructor.getRuleContext(),
156
- );
157
- },
158
- runRule(rule, context) {
159
- UtFormConstructor.runRule(this.createRuleContext(context), rule.script);
160
- },
161
- isValueEmpty(fieldName) {
162
- if (this.doc[fieldName] == null) {
163
- return true;
164
- }
165
- if (Array.isArray(this.doc[fieldName]) && !this.doc[fieldName]?.length) {
166
- return true;
167
- }
168
-
169
- if (typeof this.doc[fieldName] === 'string' && this.doc[fieldName] === '') {
170
- return true;
171
- }
172
- return false;
173
- },
174
- isValueLessThanMax(fieldname, max) {
175
- if (this.doc[fieldname] && max) {
176
- return this.doc[fieldname]?.length > parseInt(max);
177
- }
178
- return false;
179
- },
180
- isValueLessThanMin(fieldname, min) {
181
- if (this.doc[fieldname] && min) {
182
- return parseInt(this.doc[fieldname]) < parseInt(min);
183
- }
184
-
185
- return false;
186
- },
187
- validate() {
188
- this.formConfig.sections.forEach((s) => {
189
- s.columns.forEach((c) => {
190
- c.fields.forEach((f) => {
191
-
192
- let feedback = '';
193
-
194
- if (f.required && this.isValueEmpty(f.name)) {
195
- feedback += `Поле "${this.getDisplayField(f)}" обязательно`;
196
- }
197
-
198
- if (f.type === 'integer' && this.isValueLessThanMin(f.name, f.input.propsData.min)) {
199
- feedback += `\nМинимальное значение для этого поля ${f.input.propsData.min}`;
200
- }
201
- // TODO: Костыль так как на бэке нету типа memo
202
- if (f.input.type === 'b-form-textarea' && this.isValueLessThanMax(f.name, f.input.propsData?.max)) {
203
- feedback += `\nМаксимальное значение для этого поля ${f.input.propsData?.max}`;
204
- }
205
-
206
- if (feedback) {
207
- Vue.set(this.validationState, f.name, false);
208
- Vue.set(this.validationState, `${f.name}__feedback`, feedback);
209
- } else {
210
- Vue.set(this.validationState, f.name, null);
211
- }
212
-
213
- this.onEventFired(
214
- 'validate',
215
- {
216
- validationState: this.validationState,
217
- doc: this.doc,
218
- },
219
- f,
220
- );
221
- });
222
- });
223
- });
224
- for (let fieldName in this.validationState) {
225
- if (this.validationState[fieldName] === false) {
226
- return false;
227
- }
228
- }
229
-
230
- return true;
231
- },
232
- getColumnSize(section) {
233
- const MAX_COLUMN_SIZE = 12;
234
- if (!section || !section.columnCount) {
235
- return MAX_COLUMN_SIZE;
236
- }
237
-
238
- let colSize = Math.floor(MAX_COLUMN_SIZE / section.columnCount);
239
- return colSize;
240
- },
241
- execApplyDefaultValues() {
242
- if (this.applyDefaultValues) {
243
- this.formConfig.sections.forEach((r) => {
244
- r.columns.forEach((c) => {
245
- c.fields.forEach((f) => {
246
- if (f.defaultValue) {
247
- let defValue;
248
- if (this.defaultValue && typeof f.defaultValue === 'function') {
249
- defValue = f.defaultValue();
250
- } else {
251
- defValue = f.defaultValue == null ? null : f.defaultValue;
252
- }
253
-
254
- this.$set(this.doc, f.name, (f.defaultValue = defValue));
255
- }
256
- });
257
- });
258
- });
259
- }
260
- },
261
- execApplyDefaultValRule() {
262
- this.formConfig.sections.forEach((el) => {
263
- el.columns.forEach((c) => {
264
- c.fields.forEach((f) => {
265
- if (f.rules) {
266
- if (!f.defaultValue) {
267
- const rule = f.rules.find((rule) => rule.event === 'defaultValue');
268
- if (rule && !this.doc[f.name]) {
269
- this.$set(this.doc, f.name, (f.defaultValue = eval(rule.script)));
270
- }
271
- }
272
- }
273
- });
274
- });
275
- });
276
- },
277
- },
278
- mounted() {
279
- this.execApplyDefaultValues();
280
- this.execApplyDefaultValRule();
281
- this.onGlobalEventFired('form-mounted', this);
282
- },
283
- activated() {
284
- this.execApplyDefaultValues();
285
- this.execApplyDefaultValRule();
286
- this.onGlobalEventFired('form-activated', this);
287
- },
288
- };
289
- </script>
1
+ <template>
2
+ <b-form v-if="formConfig && formConfig.sections" class="rb-doc-form" @submit.prevent>
3
+ <b-container
4
+ v-for="section in formConfig.sections"
5
+ :key="section.labelRu"
6
+ class="rb-form-section"
7
+ >
8
+ <b-row>
9
+ <b-col lg="12">
10
+ <h4>{{ getDisplayField(section) }}</h4>
11
+ </b-col>
12
+ <template v-for="column in section.columns">
13
+ <b-col :key="column.index" :lg="getColumnSize(section)" :sm="12">
14
+ <template v-for="field in column.fields">
15
+ {{ field.valueName }}
16
+ <b-form-row :key="field.name" v-if="field.visible">
17
+ <b-col lg="12">
18
+ <b-form-group
19
+ :data-field="field.name"
20
+ :state="validationState[field.name]"
21
+ :invalid-feedback="validationState[`${field.name}__feedback`]"
22
+ ref="inputContainer"
23
+ >
24
+ <component
25
+ v-bind:is="field.input.type"
26
+ v-model="doc[field.name]"
27
+ :resolve-value="getResolveValue(field)"
28
+ :disabled="!editable || !field.editable"
29
+ :id="field.name"
30
+ :state="validationState[field.name]"
31
+ :ref="field.ref? field.ref: field.name"
32
+ :required="field.required"
33
+ @hook:created="onEventFired('created', $event, field)"
34
+ @hook:destroyed="onEventFired('destroyed', $event, field)"
35
+ @hook:activated="onEventFired('activated', $event, field)"
36
+ @hook:mounted="onEventFired('mounted', $event, field)"
37
+ @input="onEventFired('input', $event, field)"
38
+ @change="onEventFired('change', $event, field)"
39
+ @click="onEventFired('click', $event, field)"
40
+ @set-resolve-value="setResolveValue"
41
+ v-bind="field.input.propsData"
42
+ ></component>
43
+ <template #label>
44
+ <span :title="getDisplayField(field)">{{ getDisplayField(field) }}</span>
45
+ <span v-if="showRequiredInLabel && field.required" class="text-danger"
46
+ >*</span
47
+ >
48
+ </template>
49
+ </b-form-group>
50
+ </b-col>
51
+ </b-form-row>
52
+ </template>
53
+ </b-col>
54
+ </template>
55
+ </b-row>
56
+ </b-container>
57
+ </b-form>
58
+ </template>
59
+
60
+ <script>
61
+ import Vue from 'vue';
62
+ import {UtFormConstructor} from '../utils/UtFormConstructor';
63
+ import typeOf from 'typeof';
64
+ import {i18n} from '../locales/i18n'
65
+ import {UtFormConfig} from '@/utils/UtFormConfig';
66
+ // import safeEval from "notevil";
67
+
68
+ export default {
69
+ name: 'DocForm',
70
+ props: {
71
+ formConfig: Object,
72
+ applyDefaultValues: {type: Boolean, default: true},
73
+ doc: {type: Object, default: () => ({})},
74
+ refSuffix: {type: String, default: 'Id'},
75
+ editable: {type: Boolean, default: true},
76
+ displayField: {type: String, default: 'labelRu'},
77
+ showRequiredInLabel: {type: Boolean, default: true},
78
+ },
79
+ data() {
80
+ return {
81
+ validationState: {},
82
+ };
83
+ },
84
+ watch: {
85
+ formConfig() {
86
+ this.validationState = {};
87
+ this.execApplyDefaultValues();
88
+ this.execApplyDefaultValRule();
89
+ },
90
+ },
91
+ methods: {
92
+ getResolveValueName(field) {
93
+ if ((field.dict || field.ref) && !field.multiple) {
94
+ return field.name.substring(0, field.name.length - 2);
95
+ }
96
+ return field.name;
97
+ },
98
+ getResolveValue(field) {
99
+ return this.doc[this.getResolveValueName(field)]
100
+ ? this.doc[this.getResolveValueName(field)]
101
+ : null;
102
+ },
103
+ setResolveValue({field, multiple = false}) {
104
+ let resolveValue = this.getResolveValue(field);
105
+ if (resolveValue && !multiple) {
106
+ resolveValue = null;
107
+ }
108
+ },
109
+ getDisplayField(value) {
110
+ if (!value[this.displayField]) {
111
+ return value.labelRu;
112
+ } else {
113
+ return value[this.displayField];
114
+ }
115
+ },
116
+ onEventFired(eventName, event, field) {
117
+ if (eventName === 'input' && field.ref && !field.multiple) {
118
+ let dataField = null;
119
+ if (field.name.lastIndexOf(this.refSuffix) >= 0) {
120
+ dataField = field.name.substring(0, field.name.lastIndexOf(this.refSuffix));
121
+ }
122
+
123
+ if (dataField && dataField.length > 0) {
124
+ this.doc[dataField] = null;
125
+ }
126
+ }
127
+
128
+ if (field.rules) {
129
+ field.rules.forEach((rule) => {
130
+ if (rule.event === eventName && rule.script) {
131
+ this.runRule(rule, {event, eventName});
132
+ }
133
+ });
134
+ }
135
+ },
136
+ onGlobalEventFired(eventName, event) {
137
+ let fields = UtFormConfig.getFields(this.formConfig);
138
+ fields.forEach((f) => {
139
+ if (f.rules) {
140
+ f.rules.forEach((r) => {
141
+ if (r.event === eventName) {
142
+ this.runRule(r, {event, eventName});
143
+ }
144
+ });
145
+ }
146
+ });
147
+ },
148
+ createRuleContext(additionalContext) {
149
+ return Object.assign(
150
+ {
151
+ form: this,
152
+ doc: this.doc,
153
+ ...additionalContext,
154
+ },
155
+ UtFormConstructor.getRuleContext(),
156
+ );
157
+ },
158
+ runRule(rule, context) {
159
+ UtFormConstructor.runRule(this.createRuleContext(context), rule.script);
160
+ },
161
+ isValueEmpty(fieldName) {
162
+ if (this.doc[fieldName] == null) {
163
+ return true;
164
+ }
165
+ if (Array.isArray(this.doc[fieldName]) && !this.doc[fieldName]?.length) {
166
+ return true;
167
+ }
168
+
169
+ if (typeOf(this.doc[fieldName] === 'string') && this.doc[fieldName] === '') {
170
+ return true;
171
+ }
172
+ return false;
173
+ },
174
+ isValueLessThanMax(fieldname, max) {
175
+ if (this.doc[fieldname] && max) {
176
+ return this.doc[fieldname]?.length > parseInt(max);
177
+ }
178
+ return false;
179
+ },
180
+ isValueLessThanMin(fieldname, min) {
181
+ if (this.doc[fieldname] && min) {
182
+ return parseInt(this.doc[fieldname]) < parseInt(min);
183
+ }
184
+
185
+ return false;
186
+ },
187
+ validate() {
188
+ this.formConfig.sections.forEach((s) => {
189
+ s.columns.forEach((c) => {
190
+ c.fields.forEach((f) => {
191
+
192
+ let feedback = '';
193
+
194
+ if (f.required && this.isValueEmpty(f.name)) {
195
+ feedback += i18n.t('validate.required', {field: this.getDisplayField(f)});
196
+ }
197
+
198
+ if (f.type === 'integer' && this.isValueLessThanMin(f.name, f.input.propsData.min)) {
199
+ feedback += `\n${i18n.t('validate.min', {min: f.input.propsData.min})}`;
200
+ }
201
+ // TODO: Костыль так как на бэке нету типа memo
202
+ if (f.input.type === 'b-form-textarea' && this.isValueLessThanMax(f.name, f.input.propsData?.max)) {
203
+ feedback += `\nМаксимальное значение для этого поля ${f.input.propsData?.max}`;
204
+ }
205
+
206
+ if (feedback) {
207
+ Vue.set(this.validationState, f.name, false);
208
+ Vue.set(this.validationState, `${f.name}__feedback`, feedback);
209
+ } else {
210
+ Vue.set(this.validationState, f.name, null);
211
+ }
212
+
213
+ this.onEventFired(
214
+ 'validate',
215
+ {
216
+ validationState: this.validationState,
217
+ doc: this.doc,
218
+ },
219
+ f,
220
+ );
221
+ });
222
+ });
223
+ });
224
+ for (let fieldName in this.validationState) {
225
+ if (this.validationState[fieldName] === false) {
226
+ return false;
227
+ }
228
+ }
229
+
230
+ return true;
231
+ },
232
+ getColumnSize(section) {
233
+ const MAX_COLUMN_SIZE = 12;
234
+ if (!section || !section.columnCount) {
235
+ return MAX_COLUMN_SIZE;
236
+ }
237
+
238
+ let colSize = Math.floor(MAX_COLUMN_SIZE / section.columnCount);
239
+ return colSize;
240
+ },
241
+ execApplyDefaultValues() {
242
+ if (this.applyDefaultValues) {
243
+ this.formConfig.sections.forEach((r) => {
244
+ r.columns.forEach((c) => {
245
+ c.fields.forEach((f) => {
246
+ if (f.defaultValue) {
247
+ let defValue;
248
+ if (this.defaultValue && typeOf(f.defaultValue) === 'function') {
249
+ defValue = f.defaultValue();
250
+ } else {
251
+ defValue = f.defaultValue == null ? null : f.defaultValue;
252
+ }
253
+
254
+ this.$set(this.doc, f.name, (f.defaultValue = defValue));
255
+ }
256
+ });
257
+ });
258
+ });
259
+ }
260
+ },
261
+ execApplyDefaultValRule() {
262
+ this.formConfig.sections.forEach((el) => {
263
+ el.columns.forEach((c) => {
264
+ c.fields.forEach((f) => {
265
+ if (f.rules) {
266
+ if (!f.defaultValue) {
267
+ const rule = f.rules.find((rule) => rule.event === 'defaultValue');
268
+ if (rule && !this.doc[f.name]) {
269
+ this.$set(this.doc, f.name, (f.defaultValue = eval(rule.script)));
270
+ }
271
+ }
272
+ }
273
+ });
274
+ });
275
+ });
276
+ },
277
+ },
278
+ mounted() {
279
+ this.execApplyDefaultValues();
280
+ this.execApplyDefaultValRule();
281
+ this.onGlobalEventFired('form-mounted', this);
282
+ },
283
+ activated() {
284
+ this.execApplyDefaultValues();
285
+ this.execApplyDefaultValRule();
286
+ this.onGlobalEventFired('form-activated', this);
287
+ },
288
+ };
289
+ </script>