laravel-precognition-vue-inertia
Version:
Laravel Precognition (Vue w/ Inertia).
162 lines (161 loc) • 5.37 kB
JavaScript
import { toSimpleValidationErrors, resolveUrl, resolveMethod } from 'laravel-precognition';
import { useForm as usePrecognitiveForm, client } from 'laravel-precognition-vue';
import { useForm as useInertiaForm } from '@inertiajs/vue3';
import { watchEffect } from 'vue';
export { client };
export const useForm = (method, url, inputs, config = {}) => {
/**
* The Inertia form.
*/
const inertiaForm = useInertiaForm(inputs);
/**
* The Precognitive form.
*/
const precognitiveForm = usePrecognitiveForm(method, url, inputs, config);
/**
* Setup event listeners.
*/
precognitiveForm.validator().on('errorsChanged', () => {
inertiaClearErrors();
inertiaSetError(
// @ts-expect-error
toSimpleValidationErrors(precognitiveForm.validator().errors()));
});
/**
* The Inertia submit function.
*/
const inertiaSubmit = inertiaForm.submit.bind(inertiaForm);
/**
* The Inertia reset function.
*/
const inertiaReset = inertiaForm.reset.bind(inertiaForm);
/**
* The Inertia clear errors function.
*/
const inertiaClearErrors = inertiaForm.clearErrors.bind(inertiaForm);
/**
* The Inertia set error function.
*/
const inertiaSetError = inertiaForm.setError.bind(inertiaForm);
/**
* The Inertia trasform function.
*/
const inertiaTransform = inertiaForm.transform.bind(inertiaForm);
/**
* The transform function.
*/
let transformer = (data) => data;
/**
* Patch the form.
*/
const form = Object.assign(inertiaForm, {
validating: precognitiveForm.validating,
touched: precognitiveForm.touched,
touch(name) {
precognitiveForm.touch(name);
return form;
},
valid: precognitiveForm.valid,
invalid: precognitiveForm.invalid,
setData(data) {
Object.keys(data).forEach((input) => {
// @ts-expect-error
form[input] = data[input];
});
return form;
},
clearErrors(...names) {
inertiaClearErrors(...names);
if (names.length === 0) {
precognitiveForm.setErrors({});
}
else {
names.forEach(precognitiveForm.forgetError);
}
return form;
},
reset(...names) {
inertiaReset(...names);
precognitiveForm.reset(...names);
},
setErrors(errors) {
// @ts-expect-error
precognitiveForm.setErrors(errors);
return form;
},
forgetError(name) {
precognitiveForm.forgetError(name);
return form;
},
setError(key, value) {
let errors;
if (typeof key !== 'object') {
if (typeof value === 'undefined') {
throw new Error('The `value` is required.');
}
errors = { [key]: value };
}
else {
errors = key;
}
form.setErrors({
...inertiaForm.errors,
...errors,
});
return form;
},
transform(callback) {
inertiaTransform(callback);
transformer = callback;
return form;
},
validate(name, config) {
precognitiveForm.setData(transformer(inertiaForm.data()));
if (typeof name === 'object' && !('target' in name)) {
config = name;
name = undefined;
}
if (typeof config === 'object') {
// @ts-expect-error
config.onValidationError = config.onValidationError ?? config?.onError;
}
if (typeof name === 'undefined') {
precognitiveForm.validate(config);
}
else {
precognitiveForm.validate(name, config);
}
return form;
},
setValidationTimeout(duration) {
precognitiveForm.setValidationTimeout(duration);
return form;
},
validateFiles() {
precognitiveForm.validateFiles();
return form;
},
submit(submitMethod = {}, submitUrl, submitOptions) {
if (typeof submitMethod !== 'string') {
submitOptions = submitMethod;
submitUrl = resolveUrl(url);
submitMethod = resolveMethod(method);
}
inertiaSubmit(submitMethod, submitUrl, {
...submitOptions,
onError: (errors) => {
precognitiveForm.validator().setErrors(errors);
if (submitOptions?.onError) {
return submitOptions.onError(errors);
}
},
});
},
validator: precognitiveForm.validator,
});
// Due to the nature of `reactive` elements, reactivity is not inherited by
// the patched Inertia form as we have to destructure the Precog form. We
// can handle this by watching for changes and apply the changes manually.
watchEffect(() => form.validating = precognitiveForm.validating);
return form;
};