Skip to content
This repository was archived by the owner on Jun 27, 2023. It is now read-only.

Commit 9ddab17

Browse files
authored
Merge pull request #13 from alvarosaburido/feature/custom_fields_nested_slot_templates
Custom Fields via dynamic scoped slots
2 parents a442510 + 9325522 commit 9ddab17

File tree

9 files changed

+85
-11
lines changed

9 files changed

+85
-11
lines changed

.prettierrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
"singleQuote": true,
33
"semi": true,
44
"trailingComma": "all",
5-
"disableLanguages": ["markdown"]
5+
"disableLanguages": ["markdown"],
6+
"arrowParens": "avoid"
67
}

dev/App.vue

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,23 @@
88
:id="testForm.id"
99
:fields="testForm.fields"
1010
@change="valuesChanged"
11-
/>
11+
>
12+
<template slot="custom-field-1" slot-scope="props">
13+
<div class="pika-field">
14+
<input
15+
v-if="props.field"
16+
class="form-control"
17+
v-model="props.field.value"
18+
:type="props.field.type"
19+
:name="props.field.name"
20+
@change="props.valueChange()"
21+
@focus="props.onFocus()"
22+
@blur="props.onBlur()"
23+
/>
24+
<img src="./assets/pika.png" alt="" />
25+
</div>
26+
</template>
27+
</dynamic-form>
1228
<div class="row d-flex justify-content-end p-4">
1329
<button submit="true" :form="testForm.id" class="btn btn-primary">
1430
Submit
@@ -104,12 +120,23 @@ const data = () => ({
104120
{ text: 'Others', value: 'others' },
105121
],
106122
}),
123+
new FormField({
124+
type: 'custom-field',
125+
label: 'Custom Field 1',
126+
name: 'custom-field-1',
127+
}),
107128
new FormField({
108129
type: 'number',
109130
label: 'Number',
110131
name: 'number',
111132
value: 0,
112133
}),
134+
135+
new FormField({
136+
type: 'custom-field',
137+
label: 'File',
138+
name: 'custom-field-2',
139+
}),
113140
],
114141
},
115142
});
@@ -130,3 +157,13 @@ export default {
130157
methods,
131158
};
132159
</script>
160+
<style lang="scss">
161+
.pika-field {
162+
position: relative;
163+
164+
img {
165+
position: absolute;
166+
right: 0;
167+
}
168+
}
169+
</style>

dev/assets/pika.png

2.28 KB
Loading

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
"author": "Alvaro Saburido <[email protected]>",
66
"license": "MIT",
77
"repository": {
8-
"type" : "git",
9-
"url" : "https://github.com/alvarosaburido/vue-dynamic-forms.git"
8+
"type": "git",
9+
"url": "https://github.com/alvarosaburido/vue-dynamic-forms.git"
1010
},
1111
"bugs": {
1212
"url": "https://github.com/alvarosaburido/vue-dynamic-forms/issues"

src/components/dynamic-form/DynamicForm.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,27 @@ const computed = {
111111
}, {})
112112
: {};
113113
},
114+
deNormalizedScopedSlots() {
115+
return Object.keys(this.$scopedSlots);
116+
},
117+
normalizedControls() {
118+
let controls = {};
119+
this.controls.forEach(element => {
120+
controls[element.name] = element;
121+
});
122+
return controls;
123+
},
114124
};
115125

116126
const watch = {
117127
fields: {
118-
handler: function() {
128+
handler: function () {
119129
this.mapControls();
120130
},
121131
deep: true,
122132
},
123133
values: {
124-
handler: function() {
134+
handler: function () {
125135
this.$emit('change', this.values);
126136
},
127137
deep: true,

src/components/dynamic-form/DynamicForm.vue

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,20 @@
1414
v-for="field in controls"
1515
:key="field.name"
1616
:form-control="field"
17-
/>
17+
>
18+
<template slot="custom-field" slot-scope="props">
19+
<div v-for="slot in deNormalizedScopedSlots" :key="slot">
20+
<slot
21+
v-if="props.control.name === slot"
22+
:name="slot"
23+
:field="normalizedControls[slot]"
24+
:valueChange="props.valueChange"
25+
:onFocus="props.onFocus"
26+
:onBlur="props.onBlur"
27+
></slot>
28+
</div>
29+
</template>
30+
</dynamic-input>
1831
</form>
1932
<div v-if="showFeedback" class="dynamic-form__feedback">
2033
{{ feedbackText }}

src/components/dynamic-input/DynamicInput.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ const methods = {
2525
valueChange(val) {
2626
this.$emit('change', val);
2727
},
28+
onBlur() {
29+
this.$emit('blur');
30+
},
31+
onFocus() {
32+
this.$emit('focus');
33+
},
2834
validate() {
2935
const control = this.formControl;
3036
if (control.validations && control.validations.length > 0) {

src/components/dynamic-input/DynamicInput.vue

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
<input-text
1414
v-if="
1515
formControl.type === 'text' ||
16-
formControl.type === 'email' ||
17-
formControl.type === 'password' ||
18-
formControl.type === 'number'
16+
formControl.type === 'email' ||
17+
formControl.type === 'password' ||
18+
formControl.type === 'number'
1919
"
2020
:formControl="formControl"
2121
@change="valueChange"
@@ -40,6 +40,13 @@
4040
:formControl="formControl"
4141
@change="valueChange"
4242
/>
43+
<slot
44+
:name="'custom-field'"
45+
:control="formControl"
46+
:valueChange="valueChange"
47+
:onFocus="onFocus"
48+
:onBlur="onBlur"
49+
/>
4350
<div v-if="hasErrors">
4451
<p
4552
v-for="(errorText, $index) in errorMessages"

0 commit comments

Comments
 (0)