Skip to content

Commit 2abdff0

Browse files
committed
update form-element and add slots to fields
1 parent e63f857 commit 2abdff0

File tree

9 files changed

+912
-81
lines changed

9 files changed

+912
-81
lines changed

package-lock.json

Lines changed: 756 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
"nyc": "13.1.0",
7474
"pikaday": "1.8.0",
7575
"sinon": "7.0.0",
76-
"vue": "2.5.17",
76+
"vue": "^3.2.36",
7777
"vue-highlightjs": "1.3.3",
7878
"vue-markdown": "2.2.4",
7979
"vue-multiselect": "2.1.3",
@@ -86,5 +86,8 @@
8686
],
8787
"publishConfig": {
8888
"access": "public"
89+
},
90+
"dependencies": {
91+
"tiny-emitter": "^2.1.0"
8992
}
9093
}

src/EventBus.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import Emitter from 'tiny-emitter';
2+
3+
class CustomEmitter {
4+
constructor() {
5+
this.emitter = new Emitter();
6+
}
7+
8+
$on(...args) {
9+
this.emitter.on(...args);
10+
}
11+
12+
$once(...args) {
13+
this.emitter.once(...args);
14+
}
15+
16+
$off(...args) {
17+
this.emitter.off(...args);
18+
}
19+
20+
$emit(...args) {
21+
this.emitter.emit(...args);
22+
}
23+
}
24+
25+
export default CustomEmitter;

src/fields/abstractField.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { get as objGet, forEach, isFunction, isString, isArray, debounce, isNil, uniqueId } from "lodash";
22
import validators from "../utils/validators";
33
import { slugifyFormID } from "../utils/schema";
4+
//import { reactive } from 'vue';
45

56
const convertValidator = (validator) => {
67
if (isString(validator)) {
@@ -14,7 +15,8 @@ const convertValidator = (validator) => {
1415
};
1516

1617
function attributesDirective(el, binding, vnode) {
17-
let attrs = vnode.context.schema && vnode.context.schema.attributes ? vnode.context.schema.attributes : {};
18+
let attrs = vnode.context && vnode.context.schema && vnode.context.schema.attributes ? vnode.context.schema.attributes : {};
19+
1820
let container = binding.value || "input";
1921
if (isString(container)) {
2022
attrs = objGet(attrs, container) || attrs;
@@ -251,6 +253,10 @@ export default {
251253
},
252254

253255
clearValidationErrors() {
256+
if (this.errors === undefined || this.errors.splice === undefined) {
257+
console.warn('no this.errors in AbstractField');
258+
return;
259+
}
254260
this.errors.splice(0);
255261
},
256262

@@ -273,12 +279,16 @@ export default {
273279
o = o[k];
274280
} else {
275281
// Create missing property (new level)
276-
this.$root.$set(o, k, {});
282+
//TODO disabled for vue 3 migration
283+
//this.$root.$set(o, k, {});
284+
o[k] = {};
277285
o = o[k];
278286
}
279287
else {
280288
// Set final property value
281-
this.$root.$set(o, k, value);
289+
o[k] = value;
290+
//TODO disabled for vue 3 migration
291+
//this.$root.$set(o, k, value);
282292
return;
283293
}
284294

@@ -354,7 +364,7 @@ export default {
354364
}*/
355365
}
356366
},
357-
beforeDestroy() {
367+
beforeUnmount() {
358368
this.eventBus.$off("clear-validation-errors", this.clearValidationErrors);
359369
this.eventBus.$off("validate-fields", this.validate);
360370
this.eventBus.$emit("field-deregistering", this);

src/fields/core/fieldCheckbox.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default {
1818
mixins: [abstractField],
1919
computed: {
2020
randomId() {
21-
return this.fieldId + '-' + Math.trunc(Math.random()*100000);
21+
return this.fieldID + '-' + Math.trunc(Math.random()*100000);
2222
}
2323
}
2424
};

src/formElement.vue

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,30 @@
22
<div class="form-element"
33
:class="[fieldRowClasses]"
44
:style="field.wrapperStyle">
5+
<slot name="wrapper-hook"
6+
:field="field"
7+
:getValueFromOption="getValueFromOption"
8+
/>
59
<label
610
v-if="fieldTypeHasLabel"
711
:for="fieldID"
812
:style="field.labelStyle"
913
:class="field.labelClasses">
1014
<slot name="label"
11-
:field="field"
15+
:field="field"
16+
:fieldID="fieldID"
17+
:fieldComponent="fieldComponent"
1218
:getValueFromOption="getValueFromOption"
1319
/>
1420
<slot name="help"
1521
:field="field"
1622
:getValueFromOption="getValueFromOption"
1723
/>
1824
</label>
19-
2025
<div class="field-wrap" :style="field.fieldStyle">
2126
<component
2227
ref="child"
28+
v-if="fieldFound"
2329
:is="fieldType"
2430
:model="model"
2531
:schema="field"
@@ -29,6 +35,14 @@
2935
@field-touched="onFieldTouched"
3036
@errors-updated="onChildValidated"
3137
/>
38+
<div v-else class="field-not-found">
39+
<slot name="field-not-found"
40+
:field="field"
41+
:getValueFromOption="getValueFromOption"
42+
>
43+
Field not found
44+
</slot>
45+
</div>
3246
<div
3347
v-if="buttonsAreVisible"
3448
class="buttons">
@@ -63,6 +77,7 @@
6377
import { isNil } from "lodash";
6478
import { slugifyFormID } from "./utils/schema";
6579
import formMixin from "./formMixin.js";
80+
import { resolveComponent } from 'vue';
6681
6782
export default {
6883
name: "form-element",
@@ -102,6 +117,9 @@ export default {
102117
};
103118
},
104119
computed: {
120+
fieldComponent() {
121+
return this;
122+
},
105123
fieldID() {
106124
const idPrefix = this.options.fieldIdPrefix || "";
107125
return slugifyFormID(this.field, idPrefix);
@@ -110,6 +128,12 @@ export default {
110128
fieldType() {
111129
return "field-" + this.field.type;
112130
},
131+
fieldFound() {
132+
if(this.field && this.field.type) {
133+
const capitalized = this.field.type.charAt(0).toUpperCase() + this.field.type.slice(1)
134+
return !!resolveComponent('Field' + capitalized);
135+
}
136+
},
113137
// Should field type have a label?
114138
fieldTypeHasLabel() {
115139
if (isNil(this.field.label)) {

src/formGenerator.vue

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
<template>
22
<div class="vue-form-generator"
33
v-if='schema != null'>
4-
<form-group
4+
<vfg-form-group
55
:tag="tag"
66
:fields="fields"
77
:model="model"
88
:options="options"
99
:errors="errors"
1010
:event-bus="eventBus">
11-
<template slot="group-legend"
12-
slot-scope="{ group, groupLegend }" >
11+
<template #field-invisible="{ field }">
12+
<slot name="field-invisible"
13+
:field="field"
14+
/>
15+
</template>
16+
<template #group-legend="{ group, groupLegend }">
1317
<slot name="group-legend"
1418
:group="group"
1519
:group-legend="groupLegend" >
@@ -18,8 +22,7 @@
1822
</legend>
1923
</slot>
2024
</template>
21-
<template slot="group-help"
22-
slot-scope="{ group }">
25+
<template #group-help="{ group }">
2326
<slot
2427
name="group-help"
2528
:group="group">
@@ -31,27 +34,30 @@
3134
</span>
3235
</slot>
3336
</template>
34-
<template slot="element"
35-
slot-scope="slotProps">
36-
<form-element
37+
<template #element="slotProps">
38+
<vfg-form-element
3739
:field="slotProps.field"
3840
:model="slotProps.model"
3941
:options="slotProps.options"
4042
:errors="slotProps.errors"
4143
:event-bus="eventBus">
42-
43-
<template slot="label"
44-
slot-scope="{ field, getValueFromOption }">
44+
<template #label="{ field, getValueFromOption }">
4545
<slot
4646
name="label"
4747
:field="field"
4848
:getValueFromOption="getValueFromOption">
4949
<span v-html="field.label" ></span>
5050
</slot>
5151
</template>
52+
<template #wrapper-hook="{ field, getValueFromOption }">
53+
<slot
54+
name="wrapper-hook"
55+
:field="field"
56+
:getValueFromOption="getValueFromOption">
57+
</slot>
58+
</template>
5259

53-
<template slot="help"
54-
slot-scope="{ field, getValueFromOption }">
60+
<template #help="{ field, getValueFromOption }">
5561
<slot
5662
name="help"
5763
:field="field"
@@ -64,8 +70,14 @@
6470
</span>
6571
</slot>
6672
</template>
67-
<template slot="hint"
68-
slot-scope="{ field, getValueFromOption }">
73+
<template #field-not-found="{ field, getValueFromOption }">
74+
<slot
75+
name="field-not-found"
76+
:field="field"
77+
:getValueFromOption="getValueFromOption"
78+
/>
79+
</template>
80+
<template #hint="{ field, getValueFromOption }">
6981
<slot
7082
name="hint"
7183
:field="field"
@@ -75,8 +87,7 @@
7587
</slot>
7688
</template>
7789

78-
<template slot="errors"
79-
slot-scope="{ childErrors, field, getValueFromOption }">
90+
<template #errors="{ childErrors, field, getValueFromOption }">
8091
<slot
8192
name="errors"
8293
:errors="childErrors"
@@ -90,20 +101,20 @@
90101
</div>
91102
</slot>
92103
</template>
93-
</form-element>
104+
</vfg-form-element>
94105
</template>
95-
</form-group>
106+
</vfg-form-group>
96107
</div>
97108
</template>
98109

99110
<script>
100-
import Vue from "vue";
101111
import formGroup from "./formGroup.vue";
102112
import formElement from "./formElement.vue";
113+
import EventBus from './EventBus';
103114
104115
export default {
105116
name: "form-generator",
106-
components: { formGroup, formElement },
117+
components: { 'vfg-form-group': formGroup, 'vfg-form-element': formElement },
107118
props: {
108119
schema: {
109120
type: Object,
@@ -147,9 +158,8 @@ export default {
147158
},
148159
149160
data() {
150-
const eventBus = new Vue();
151161
return {
152-
eventBus,
162+
eventBus: new EventBus(),
153163
totalNumberOfFields: 0,
154164
errors: [] // Validation errors
155165
};
@@ -231,7 +241,7 @@ export default {
231241
232242
let formErrors = [];
233243
234-
this.eventBus.$on("field-deregistering", () => {
244+
this.eventBus.$on("field-deregistering", (...args) => {
235245
// console.warn("Fields were deleted during validation process");
236246
this.eventBus.$emit("fields-validation-terminated", formErrors);
237247
reject(formErrors);
@@ -269,7 +279,11 @@ export default {
269279
270280
// Clear validation errors
271281
clearValidationErrors() {
272-
this.errors.splice(0);
282+
if (this.errors === undefined) {
283+
console.warn('no this.errors in AbstractField');
284+
} else {
285+
this.errors.splice(0);
286+
}
273287
this.eventBus.$emit("clear-validation-errors", this.clearValidationErrors);
274288
}
275289
},
@@ -283,7 +297,7 @@ export default {
283297
this.eventBus.$on("field-registering", () => {
284298
this.totalNumberOfFields = this.totalNumberOfFields + 1;
285299
});
286-
this.eventBus.$on("field-deregistering", () => {
300+
this.eventBus.$on("field-deregistering", (f) => {
287301
this.totalNumberOfFields = this.totalNumberOfFields - 1;
288302
});
289303
},

0 commit comments

Comments
 (0)