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

Commit c2e9528

Browse files
committed
Improvements and validations
1 parent e0873f0 commit c2e9528

File tree

20 files changed

+3446
-1640
lines changed

20 files changed

+3446
-1640
lines changed

README.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,39 @@
1414

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

17-
## Project setup
17+
## Documentation
18+
19+
Complete documentation and examples available at
20+
21+
- **[API Documentation]()**
22+
- **[Sandbox Demo]()**
23+
- **[CodePen Template]()**
24+
- **[GitHub Projects]()**
25+
26+
## Install
27+
28+
```bash
29+
$ npm install @asigloo/vue-dynamic-forms
30+
```
31+
32+
Register the component
33+
34+
```js
35+
import Vue from 'vue';
36+
import VueDynamicForms from '@asigloo/vue-dynamic-forms';
37+
38+
Vue.use(VueDynamicForms);
39+
```
40+
41+
## Development
42+
43+
### Project setup
1844

1945
```
2046
yarn install
2147
```
2248

23-
### Compiles and hot-reloads for development
49+
### Compiles and hot-reloads
2450

2551
```
2652
yarn run serve

dev/App.vue

Lines changed: 84 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@
99
:fields="testForm.fields"
1010
@change="valuesChanged"
1111
/>
12+
<div class="row d-flex justify-content-end p-4">
13+
<button submit="true" :form="testForm.id" class="btn btn-primary">
14+
Submit
15+
</button>
16+
</div>
1217
</div>
1318
<div class="col-6">
19+
<pre>{{ formData }}</pre>
1420
<pre>{{ testForm }}</pre>
1521
</div>
1622
</div>
@@ -20,62 +26,92 @@
2026

2127
<script>
2228
import { email, required, pattern } from '../src/core/utils/validators';
29+
import { FormField } from '../src/core/utils/form-control.model';
2330
2431
const DynamicForm = () => import('@/components/dynamic-form/DynamicForm.vue');
2532
2633
const data = () => ({
34+
formData: {},
2735
testForm: {
2836
id: 'test-form',
2937
fields: [
30-
{
38+
new FormField({
3139
type: 'text',
3240
label: 'Name',
3341
name: 'name',
34-
},
35-
{
42+
}),
43+
new FormField({
3644
type: 'email',
3745
label: 'Email',
3846
name: 'email',
39-
validations: [required, email],
40-
errorTexts: ['This field is required', 'Format of email is incorrect'],
41-
},
42-
{
47+
validations: [
48+
{ validator: required, text: 'This field is required' },
49+
{ validator: email, text: 'Format of email is incorrect' },
50+
],
51+
}),
52+
new FormField({
4353
type: 'password',
4454
label: 'Password',
4555
name: 'password',
46-
validations: [
56+
/* validations: [
4757
required,
4858
pattern(
4959
'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[#$^+=!*()@%&]).{8,10}$',
5060
),
51-
],
52-
errorTexts: [
61+
], */
62+
value: 'sdsdsd',
63+
/* errorTexts: [
5364
'This field is required',
5465
'Password must contain at least 1 Upercase, 1 Lowercase, 1 number, 1 special character and min 8 characters max 10',
55-
],
56-
},
57-
{
66+
], */
67+
}),
68+
new FormField({
5869
type: 'textarea',
5970
label: 'Bio',
6071
name: 'bio',
6172
cols: 30,
6273
rows: 5,
63-
validations: [required],
64-
errorTexts: ['This field is required'],
65-
},
66-
{
74+
/* validations: [required],
75+
errorTexts: ['This field is required'], */
76+
}),
77+
new FormField({
6778
type: 'select',
6879
label: 'Category',
6980
name: 'category',
70-
options: [],
71-
validations: [],
72-
value: null,
7381
options: [
7482
{ value: null, text: 'Please select an option' },
7583
{ value: 'arduino', text: 'Arduino' },
7684
{ value: 'transistors', text: 'Transistors' },
7785
],
78-
},
86+
}),
87+
new FormField({
88+
type: 'checkbox',
89+
label: 'Read the conditions',
90+
name: 'conditions',
91+
inline: false,
92+
/* validations: [required],
93+
errorTexts: ['This field is required'], */
94+
}),
95+
new FormField({
96+
type: 'radio',
97+
label: 'Prefered Animal',
98+
name: 'animal',
99+
/* validations: [], */
100+
inline: true,
101+
options: [
102+
{ text: 'Dogs', value: 'dogs' },
103+
{ text: 'Cats', value: 'cats' },
104+
{ text: 'Others', value: 'others' },
105+
],
106+
}),
107+
new FormField({
108+
type: 'number',
109+
label: 'Number',
110+
name: 'number',
111+
value: 0,
112+
/* validations: [required],
113+
errorTexts: ['This field is required'], */
114+
}),
79115
],
80116
},
81117
});
@@ -87,6 +123,10 @@ const components = {
87123
const methods = {
88124
valuesChanged(values) {
89125
this.$forceUpdate(); // this is only to refresh the fields on the <pre> tags, not necessary for other purpouses
126+
this.formData = {
127+
...this.formData,
128+
...values,
129+
};
90130
console.log('Values', values);
91131
},
92132
};
@@ -99,4 +139,26 @@ export default {
99139
};
100140
</script>
101141

102-
<style lang="scss"></style>
142+
<style lang="scss">
143+
.form-group {
144+
width: 100%;
145+
margin-bottom: 0.5rem;
146+
147+
&--error {
148+
.form-label {
149+
color: #dc3545;
150+
}
151+
152+
.form-control {
153+
border-color: #dc3545;
154+
background: #f7e1e3;
155+
}
156+
}
157+
158+
.error {
159+
font-size: 11px;
160+
161+
color: #dc3545;
162+
}
163+
}
164+
</style>

docs/.vuepress/config.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
title: 'Vue Dynamic Forms',
3+
description:
4+
'Easy way to dynamically create reactive forms in vue based on varying business object model',
5+
};

docs/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
![repository-banner.png](https://res.cloudinary.com/alvarosaburido/image/upload/v1564929632/as-readme-banner_tqdgrx.png)
2+
3+
# Vue Dynamic Forms
4+
5+
![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)
6+
7+
Easy way to dynamically create reactive forms in vue based on varying business object model

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
"build": "vue-cli-service build --target lib --name as-dynamic-forms src/main.js",
1010
"lint": "vue-cli-service lint",
1111
"test": "vue-cli-service test:unit --verbose --no-cache --watchAll",
12-
"publish": "npm publish --access public"
12+
"publish": "npm publish --access public",
13+
"docs:dev": "vuepress dev docs",
14+
"docs:build": "vuepress build docs"
1315
},
1416
"main": "dist/@asigloo/core.common.js",
1517
"dependencies": {
@@ -34,6 +36,7 @@
3436
"node-sass": "^4.13.0",
3537
"prettier": "^1.19.1",
3638
"sass-loader": "^8.0.0",
37-
"vue-template-compiler": "^2.6.11"
39+
"vue-template-compiler": "^2.6.11",
40+
"vuepress": "^1.2.0"
3841
}
3942
}

src/components/dynamic-form/DynamicForm.js

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { debounce } from '@/core/utils/helpers';
1+
import { FormControl } from '../../core/utils/form-control.model';
22

33
const DynamicInput = () =>
44
import('@/components/dynamic-input/DynamicInput.vue');
@@ -29,39 +29,37 @@ const props = {
2929
fields: {
3030
type: Array,
3131
},
32-
feedbackText: {
33-
default: null,
34-
type: String,
35-
},
3632
};
3733

3834
const methods = {
3935
mapControls() {
40-
this.controls = this.fields.map(field => ({
41-
...field,
42-
valid: true,
43-
touched: false,
44-
dirty: false,
45-
errors: {},
46-
submited: this.submited,
47-
}));
36+
this.controls = this.fields.map(
37+
field =>
38+
new FormControl({
39+
...field,
40+
valid: true,
41+
touched: false,
42+
dirty: false,
43+
errors: {},
44+
submited: this.submited,
45+
}),
46+
);
4847
},
4948
updateControls() {
50-
this.controls = this.controls.map(field => ({
51-
...field,
52-
submited: this.submited,
53-
}));
49+
this.controls = this.controls.map(
50+
field =>
51+
new FormControl({
52+
...field,
53+
submited: this.submited,
54+
}),
55+
);
5456
},
5557
handleSubmit() {
5658
this.submited = true;
5759
this.updateControls();
5860
this.$nextTick(() => {
5961
if (this.isValid) {
6062
this.$emit('submit', this.values);
61-
this.showFeedback = true;
62-
setTimeout(() => {
63-
this.showFeedback = false;
64-
}, 4000);
6563
this.resetForm();
6664
} else {
6765
this.$emit('form error', this.allErrors);
@@ -70,15 +68,18 @@ const methods = {
7068
},
7169
resetForm() {
7270
this.submited = false;
73-
this.controls = this.fields.map(field => ({
74-
...field,
75-
valid: true,
76-
value: null,
77-
touched: false,
78-
dirty: false,
79-
errors: {},
80-
submited: this.submited,
81-
}));
71+
this.controls = this.fields.map(
72+
field =>
73+
new FormControl({
74+
...field,
75+
valid: true,
76+
value: null,
77+
touched: false,
78+
dirty: false,
79+
errors: {},
80+
submited: this.submited,
81+
}),
82+
);
8283
},
8384
};
8485

@@ -121,9 +122,9 @@ const watch = {
121122
deep: true,
122123
},
123124
values: {
124-
handler: debounce(function() {
125+
handler: function() {
125126
this.$emit('change', this.values);
126-
}, 400),
127+
},
127128
deep: true,
128129
},
129130
};
@@ -136,6 +137,9 @@ const DynamicForm = {
136137
props,
137138
watch,
138139
computed,
140+
mounted() {
141+
this.mapControls();
142+
},
139143
};
140144

141145
export default DynamicForm;

0 commit comments

Comments
 (0)