/
useForm.js
145 lines (124 loc) · 4.04 KB
/
useForm.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import {Form, Modal} from 'ant-design-vue'
const AntUseForm = Form.useForm;
import { useForm as InertiaUseForm } from '@inertiajs/inertia-vue3'
import { reactive, nextTick } from 'vue'
export default function (props, rules={}, useInertia=true) {
const inertiaForm = InertiaUseForm(props)
const {
resetFields,
validate,
validateInfos,
clearValidate
} = AntUseForm(inertiaForm, reactive(rules))
const displayError = (errors) => {
console.debug('displayError', errors)
Object.keys(errors).forEach(field => {
if (!validateInfos[field]) {
validateInfos[field] = {}
}
validateInfos[field].help = [[ inertiaForm.errors[field] ]]
validateInfos[field].validateStatus = "error"
})
}
/**
* @param params
*/
const resetDisplayError = (...params) => {
if (params.length) {
for (let field of params) {
validateInfos[field] = {}
}
} else {
Object.keys(inertiaForm.validation).forEach(field => {
validateInfos[field] = {}
})
}
}
const onError = (onErrorHandler, errorTransformer) => {
return (errors) => {
if (onErrorHandler) {
onErrorHandler(errors)
}
if (errorTransformer) {
displayError(errorTransformer(errors))
} else {
displayError(errors)
}
}
}
const inertiaSubmit = inertiaForm.submit.bind(inertiaForm)
const inertiaReset = inertiaForm.reset.bind(inertiaForm)
const axiosSubmit = function (method, url, options) {
window.axios({
method: method,
url: url,
data: inertiaForm.data()
}).then(({data}) => {
options.onSuccess && options.onSuccess(data)
}).catch((error) => {
if (error.response?.status === 422) {
const errorHandler = onError(options.onError, options.errorTransformer)
// form validation errors
const errors = error.response.data.errors
for (let key in errors) {
errors[key] = errors[key][0]
}
inertiaForm.errors = errors
errorHandler(errors)
} else {
return Promise.reject(error)
}
})
}
const submit = function (method, url, options={}) {
// FIXME: this is a workaround for ant-design-vue v2.2.2
// @see: https://github.com/vueComponent/ant-design-vue/issues/4238
clearValidate(Object.keys(validateInfos))
const submitHandler = useInertia ? inertiaSubmit : axiosSubmit
validate().then(() => {
submitHandler(method, url, {
...options,
onError: onError(options.onError, options.errorTransformer)
})
}).catch((e) => {
if (e.errorFields.length === 0) {
submitHandler(method, url, {
...options,
onError: onError(options.onError, options.errorTransformer)
})
} else {
if (options.onValidateError) {
options.onValidateError()
}
}
})
}
/**
* Reset form
*
* @param params fields to reset
*/
const reset = function (...params) {
nextTick(() => {
if (params.length) {
resetDisplayError(...params)
clearValidate(...params)
inertiaReset(...params)
} else {
resetDisplayError()
clearValidate()
inertiaReset()
}
})
}
inertiaForm.validation = validateInfos
inertiaForm.submit = submit
inertiaForm.reset = reset
inertiaForm.validate = validate
inertiaForm.layout = {
colon: false,
labelCol: { span: 6 },
wrapperCol: { span: 18 },
}
return inertiaForm
}