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

Commit e0873f0

Browse files
committed
Input Select and Textarea
1 parent d9e33bc commit e0873f0

File tree

20 files changed

+289
-40
lines changed

20 files changed

+289
-40
lines changed

.vuegenerator

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"componentDestination": "./src/components/",
3+
"templatePath": "./templates/"
4+
}

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
- `vue --version`:3.0.3
99
- `webpack -v` : v4.1.1
1010

11-
# vue-dynamic-forms
11+
# Vue Dynamic Forms
1212

13-
[![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)
13+
![Current Relase](https://img.shields.io/github/package-json/v/alvarosaburido/vue-dynamic-forms) [![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)
1414

1515
Easy way to dynamically create reactive forms in vue based on varying business object model
1616

dev/App.vue

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,23 @@
44
<h1 class="title text-center">Dynamic Forms Example</h1>
55
<div class="row mt-5">
66
<div class="col-6">
7-
<dynamic-form :id="testForm.id" :fields="testForm.fields" />
7+
<dynamic-form
8+
:id="testForm.id"
9+
:fields="testForm.fields"
10+
@change="valuesChanged"
11+
/>
812
</div>
913
<div class="col-6">
10-
<pre>{{ testForm.fields }}</pre>
14+
<pre>{{ testForm }}</pre>
1115
</div>
1216
</div>
1317
</div>
1418
</div>
1519
</template>
1620

1721
<script>
22+
import { email, required, pattern } from '../src/core/utils/validators';
23+
1824
const DynamicForm = () => import('@/components/dynamic-form/DynamicForm.vue');
1925
2026
const data = () => ({
@@ -25,7 +31,50 @@ const data = () => ({
2531
type: 'text',
2632
label: 'Name',
2733
name: 'name',
34+
},
35+
{
36+
type: 'email',
37+
label: 'Email',
38+
name: 'email',
39+
validations: [required, email],
40+
errorTexts: ['This field is required', 'Format of email is incorrect'],
41+
},
42+
{
43+
type: 'password',
44+
label: 'Password',
45+
name: 'password',
46+
validations: [
47+
required,
48+
pattern(
49+
'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$^+=!*()@%&]).{8,10}$',
50+
),
51+
],
52+
errorTexts: [
53+
'This field is required',
54+
'Password must contain at least 1 Upercase, 1 Lowercase, 1 number, 1 special character and min 8 characters max 10',
55+
],
56+
},
57+
{
58+
type: 'textarea',
59+
label: 'Bio',
60+
name: 'bio',
61+
cols: 30,
62+
rows: 5,
63+
validations: [required],
64+
errorTexts: ['This field is required'],
65+
},
66+
{
67+
type: 'select',
68+
label: 'Category',
69+
name: 'category',
70+
options: [],
2871
validations: [],
72+
value: null,
73+
options: [
74+
{ value: null, text: 'Please select an option' },
75+
{ value: 'arduino', text: 'Arduino' },
76+
{ value: 'transistors', text: 'Transistors' },
77+
],
2978
},
3079
],
3180
},
@@ -35,10 +84,18 @@ const components = {
3584
DynamicForm,
3685
};
3786
87+
const methods = {
88+
valuesChanged(values) {
89+
this.$forceUpdate(); // this is only to refresh the fields on the <pre> tags, not necessary for other purpouses
90+
console.log('Values', values);
91+
},
92+
};
93+
3894
export default {
3995
name: 'app',
4096
data,
4197
components,
98+
methods,
4299
};
43100
</script>
44101

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"serve": "vue-cli-service serve",
99
"build": "vue-cli-service build --target lib --name as-dynamic-forms src/main.js",
1010
"lint": "vue-cli-service lint",
11-
"test": "vue-cli-service test:unit --verbose --no-cache --watchAll"
11+
"test": "vue-cli-service test:unit --verbose --no-cache --watchAll",
12+
"publish": "npm publish --access public"
1213
},
1314
"main": "dist/@asigloo/core.common.js",
1415
"dependencies": {

src/components/dynamic-form/DynamicForm.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ const watch = {
122122
},
123123
values: {
124124
handler: debounce(function() {
125-
this.$emit('changed', this.values);
125+
this.$emit('change', this.values);
126126
}, 400),
127127
deep: true,
128128
},

src/components/dynamic-input/DynamicInput.js

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
const data = () => ({});
1+
const InputText = () => import('@/components/input-text/InputText.vue');
2+
const InputTextarea = () =>
3+
import('@/components/input-textarea/InputTextarea.vue');
4+
const InputSelect = () => import('@/components/input-select/InputSelect.vue');
25

3-
const components = {};
6+
const components = {
7+
InputText,
8+
InputTextarea,
9+
InputSelect,
10+
};
411

512
const props = {
613
formControl: {
@@ -18,15 +25,8 @@ const props = {
1825
};
1926

2027
const methods = {
21-
valueChange() {
22-
this.$emit('value changed', this.formControl.value);
23-
},
24-
onFocus() {
25-
this.$emit('input focused');
26-
},
27-
onBlur() {
28-
this.$emit('input blur');
29-
this.formControl.touched = true;
28+
valueChange(val) {
29+
this.$emit('change', val);
3030
},
3131
validate() {
3232
const control = this.formControl;
@@ -40,9 +40,8 @@ const methods = {
4040
...val,
4141
};
4242
}, {});
43-
const validKeys = Object.keys(validation) || [];
4443
control.errors = validation;
45-
control.valid = validKeys.length === 0;
44+
control.valid = Object.keys(validation).length === 0;
4645
}
4746
},
4847
};
@@ -52,7 +51,7 @@ const watch = {
5251
handler() {
5352
this.formControl.dirty = true;
5453
this.validate();
55-
this.$emit('value changed', this.formControl.value);
54+
this.$emit('change', this.formControl.value);
5655
},
5756
deep: true,
5857
},
@@ -100,13 +99,11 @@ const computed = {
10099

101100
const DynamicInput = {
102101
name: 'asDynamicInput',
103-
data,
104102
components,
105103
watch,
106104
props,
107105
computed,
108106
methods,
109-
mounted() {},
110107
};
111108

112109
export default DynamicInput;

src/components/dynamic-input/DynamicInput.vue

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,25 @@
66
<label class="form-label" :for="formControl.name">
77
{{ formControl.label }}
88
</label>
9-
<input
9+
<input-text
1010
v-if="
1111
formControl.type === 'text' ||
1212
formControl.type === 'email' ||
1313
formControl.type === 'password' ||
1414
formControl.type === 'number'
1515
"
16-
:id="formControl.name"
17-
v-model="formControl.value"
18-
:name="formControl.name"
19-
class="form-control"
20-
:type="formControl.type"
21-
:placeholder="formControl.placeholder"
22-
@change="valueChange()"
23-
@focus="onFocus()"
24-
@blur="onBlur()"
16+
:formControl="formControl"
17+
@change="valueChange"
18+
/>
19+
<input-textarea
20+
v-if="formControl.type === 'textarea'"
21+
:formControl="formControl"
22+
@change="valueChange"
23+
/>
24+
<input-select
25+
v-if="formControl.type === 'select'"
26+
:formControl="formControl"
27+
@change="valueChange"
2528
/>
2629
<div v-if="hasErrors">
2730
<p
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
const props = {
2+
formControl: {
3+
default: () => ({
4+
type: null,
5+
value: null,
6+
validations: [],
7+
label: null,
8+
name: null,
9+
options: [],
10+
placeholder: null,
11+
errors: {},
12+
}),
13+
type: Object,
14+
},
15+
};
16+
17+
const InputSelect = {
18+
name: 'asInputSelect',
19+
props,
20+
};
21+
22+
export default InputSelect;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { shallowMount } from '@vue/test-utils';
2+
import InputSelect from './InputSelect.vue';
3+
4+
describe('InputSelect', () => {
5+
let cmp;
6+
7+
beforeEach(() => {
8+
cmp = shallowMount(InputSelect);
9+
});
10+
it('is a Vue instance', () => {
11+
expect(cmp.isVueInstance()).toBeTruthy();
12+
});
13+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<template>
2+
<select
3+
:id="formControl.name"
4+
v-model="formControl.value"
5+
:name="formControl.name"
6+
class="form-control"
7+
>
8+
<option v-for="opt in formControl.options" :key="opt.value">
9+
{{ opt.text }}
10+
</option>
11+
</select>
12+
</template>
13+
<script src="./InputSelect.js"></script>

0 commit comments

Comments
 (0)