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

Commit 0a6257d

Browse files
committed
feat(fields): reactivity is working as expected
1 parent f610580 commit 0a6257d

File tree

11 files changed

+146
-73
lines changed

11 files changed

+146
-73
lines changed

dev/typescript/App.vue

Lines changed: 103 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
</template>
4646

4747
<script lang="ts">
48-
import { defineComponent, reactive, ref } from 'vue';
48+
import { mockAsync } from '@/core/utils/helpers';
49+
import { defineComponent, onMounted, reactive, ref } from 'vue';
4950
import {
5051
TextInput,
5152
SelectInput,
@@ -60,16 +61,43 @@ import {
6061
pattern,
6162
ColorInput,
6263
NumberInput,
64+
CustomInput,
6365
} from '../../src';
6466
/* } from '../../dist/as-dynamic-forms.esm'; */
6567
export default defineComponent({
6668
name: 'app',
6769
setup() {
6870
const title = ref('Vue Dynamic Forms');
6971
const formValues = reactive({});
72+
73+
const emailValidator: FormValidation = {
74+
validator: email,
75+
text: 'Email format is incorrect',
76+
};
77+
78+
const passwordValidator: FormValidation = {
79+
validator: pattern(
80+
'^(?=.*[a-z])(?=.*[A-Z])(?=.*)(?=.*[#$^+=!*()@%&]).{8,10}$',
81+
),
82+
text:
83+
'Password must contain at least 1 Uppercase, 1 Lowercase, 1 number, 1 special character and min 8 characters max 10',
84+
};
85+
7086
const form = reactive({
7187
id: 'example-form',
72-
fieldOrder: ['name'],
88+
fieldOrder: [
89+
'name',
90+
'email',
91+
'password',
92+
'console',
93+
'games',
94+
'stock',
95+
'steps',
96+
'character',
97+
'awesomeness',
98+
'color',
99+
'customField1',
100+
],
73101
fields: {
74102
name: {
75103
label: 'Name',
@@ -79,36 +107,20 @@ export default defineComponent({
79107
email: {
80108
label: 'Email',
81109
type: 'email',
110+
validations: [emailValidator],
82111
} as EmailInput,
83-
},
84-
/* fields: [
85-
new TextInput({
86-
label: 'Name',
87-
value: 'Alvaro',
88-
}),
89-
new EmailInput({
90-
label: 'Email',
91-
validations: [new FormValidation(email, 'Email format is incorrect')],
92-
}),
93-
new PasswordInput({
112+
password: {
94113
label: 'Password',
95-
validations: [
96-
new FormValidation(
97-
pattern(
98-
'^(?=.*[a-z])(?=.*[A-Z])(?=.*)(?=.*[#$^+=!*()@%&]).{8,10}$',
99-
),
100-
'Password must contain at least 1 Uppercase, 1 Lowercase, 1 number, 1 special character and min 8 characters max 10',
101-
),
102-
],
103-
}),
104-
new NumberInput({
105-
label: 'Number',
106-
min: 5,
107-
max: 60,
108-
step: 5,
109-
}),
110-
new SelectInput<string>({
114+
type: 'password',
115+
validations: [passwordValidator],
116+
} as PasswordInput,
117+
stock: {
118+
label: 'Stock',
119+
type: 'number',
120+
} as NumberInput,
121+
games: {
111122
label: 'Games',
123+
type: 'select',
112124
customClass: 'w-1/2',
113125
value: 'the-last-of-us',
114126
options: [
@@ -125,19 +137,28 @@ export default defineComponent({
125137
value: 'Nier Automata',
126138
},
127139
],
128-
}),
129-
new TextAreaInput({
130-
label: 'Bio',
131-
cols: 20,
132-
rows: 5,
133-
}),
134-
new CheckboxInput({
140+
} as SelectInput,
141+
console: {
142+
label: 'Console (Async Options)',
143+
type: 'select',
144+
customClass: 'w-1/2',
145+
options: [],
146+
} as SelectInput,
147+
steps: {
148+
label: 'Number',
149+
type: 'number',
150+
min: 5,
151+
max: 60,
152+
step: 5,
153+
value: 5,
154+
} as NumberInput,
155+
awesomeness: {
135156
label: "Check if you're awesome",
136-
name: 'awesomness',
137-
}),
138-
new RadioInput({
157+
type: 'checkbox',
158+
} as CheckboxInput,
159+
character: {
139160
label: 'Select one option',
140-
name: 'character',
161+
type: 'radio',
141162
options: [
142163
{
143164
key: 'mario',
@@ -157,33 +178,62 @@ export default defineComponent({
157178
disabled: true,
158179
},
159180
],
160-
}),
161-
new InputBase<string>({
181+
} as RadioInput,
182+
customField1: {
162183
type: 'custom-field',
163184
label: 'Custom Field',
164-
name: 'customField1',
165-
}),
166-
new ColorInput({
185+
} as CustomInput,
186+
color: {
167187
label: 'Color',
168-
name: 'color',
188+
type: 'color',
169189
value: '#4DBA87',
170-
}),
171-
],
172-
*/
190+
} as ColorInput,
191+
},
173192
});
193+
174194
function handleSubmit(values) {
175195
console.log('Values Submitted', values);
176196
}
197+
177198
function valueChanged(values) {
178199
Object.assign(formValues, values);
179-
setTimeout(() => {
180-
form.fields.email.value = '[email protected]';
181-
}, 2000);
200+
console.log('Values', values);
182201
}
202+
183203
function handleError(errors) {
184-
console.error(errors);
204+
console.error('Errors', errors);
185205
}
186206
207+
onMounted(async () => {
208+
setTimeout(() => {
209+
form.fields.email.value = '[email protected]';
210+
}, 2000);
211+
212+
try {
213+
const consoleOptions = await mockAsync(true, 4000, [
214+
{
215+
key: 'playstation',
216+
value: 'Playstation',
217+
},
218+
{
219+
key: 'nintendo',
220+
value: 'Nintendo',
221+
},
222+
{
223+
key: 'xbox',
224+
value: 'Xbox',
225+
},
226+
]);
227+
form.fields.console.options = consoleOptions as {
228+
key: string;
229+
value: string;
230+
disabled?: boolean;
231+
}[];
232+
} catch (e) {
233+
console.error(e);
234+
}
235+
});
236+
187237
return {
188238
title,
189239
form,

src/components/checkbox-input/CheckboxInput.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default defineComponent({
1111
name: 'asCheckboxInput',
1212
props,
1313
setup(props, { emit }) {
14-
const { onCheck, onFocus, onBlur } = useInputEvents(props?.control, emit);
14+
const { onCheck, onFocus, onBlur } = useInputEvents(props, emit);
1515
1616
return () => [
1717
h('input', {

src/components/dynamic-form/DynamicForm.vue

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ import DynamicInput from '../dynamic-input/DynamicInput.vue';
5151
5252
import { InputBase, FormControl } from '../../core/models';
5353
import { dynamicFormsSymbol } from '../../useApi';
54-
/* import { warn } from '../../core/utils/warning';
55-
*/
54+
5655
const props = {
5756
form: {
5857
type: Object as PropType<DynamicForm>,
@@ -153,12 +152,22 @@ export default defineComponent({
153152
154153
function mapControls(empty?) {
155154
controls.value =
156-
Object.entries(
157-
props.form?.fields,
158-
).map(([key, field]: [string, InputBase]) =>
159-
empty
160-
? ({ ...field, name: key, value: null } as FormControl)
161-
: ({ ...field, name: key } as FormControl),
155+
Object.entries(props.form?.fields).map(
156+
([key, field]: [string, InputBase]) =>
157+
empty
158+
? ({
159+
...field,
160+
name: key,
161+
value: undefined,
162+
dirty: false,
163+
touched: false,
164+
} as FormControl)
165+
: ({
166+
...field,
167+
name: key,
168+
dirty: false,
169+
touched: false,
170+
} as FormControl),
162171
) || [];
163172
}
164173
@@ -168,6 +177,7 @@ export default defineComponent({
168177
169178
function handleSubmit() {
170179
submited.value = true;
180+
171181
if (isValid.value) {
172182
ctx.emit('submited', formValues);
173183
resetForm();

src/components/dynamic-input/DynamicInput.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ export default defineComponent({
220220
},
221221
slots.customField({
222222
control: props.control,
223-
onChange: ($event: any) => {
223+
onChange: $event => {
224224
const newValue = {};
225225
const value = $event.target.value;
226226

src/components/number-input/NumberInput.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default defineComponent({
1111
name: 'asNumberInput',
1212
props,
1313
setup(props, { emit }) {
14-
const { onChange, onFocus, onBlur } = useInputEvents(props?.control, emit);
14+
const { onChange, onFocus, onBlur } = useInputEvents(props, emit);
1515
1616
return () =>
1717
h('input', {

src/components/radio-input/RadioInput.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export default defineComponent({
1111
name: 'asRadioInput',
1212
props,
1313
setup(props, { emit }) {
14-
const { onChange, onFocus, onBlur } = useInputEvents(props?.control, emit);
14+
const { onChange, onFocus, onBlur } = useInputEvents(props, emit);
1515
const renderRadios = props?.control?.options?.map(option => {
1616
return h('div', { class: 'radio-input' }, [
1717
h('input', {

src/components/select-input/SelectInput.vue

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ export default defineComponent({
1212
props,
1313
setup(props, { emit }) {
1414
return () => {
15-
const { onChange, onFocus, onBlur } = useInputEvents(
16-
props?.control,
17-
emit,
18-
);
15+
const { onChange, onFocus, onBlur } = useInputEvents(props, emit);
1916
2017
const options = props?.control?.options?.map(({ key, value, disabled }) =>
2118
h('option', { key, value: key, disabled }, value),

src/components/text-area-input/TextAreaInput.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default defineComponent({
1010
name: 'asTextAreaInput',
1111
props,
1212
setup(props, { emit }) {
13-
const { onChange, onFocus, onBlur } = useInputEvents(props?.control, emit);
13+
const { onChange, onFocus, onBlur } = useInputEvents(props, emit);
1414
1515
return () =>
1616
h('textarea', {

src/composables/input-events.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ export function useInputEvents(props: any, emit: any) {
2525
}
2626
}
2727

28-
watch(props, (value: any) => {
29-
emit('changed', value.control.value);
28+
watch(props, (form: any) => {
29+
if (!form.control.dirty) {
30+
form.control.dirty = true;
31+
emit('changed', form.control.value);
32+
}
3033
});
3134

3235
return {

src/core/models.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ export type InputTypeKeys =
88
| 'select'
99
| 'checkbox'
1010
| 'radio'
11-
| 'color';
11+
| 'color'
12+
| 'custom-field';
1213

1314
export type InputType =
1415
| TextInput

0 commit comments

Comments
 (0)