| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- import { ref, nextTick } from "vue";
- export function useSubmitHandler(options = {}) {
- const { onSuccess, onError, formRef, scrollFn, containerRef } = options;
- const loading = ref(false);
- const validationErrors = ref({});
- const getFormRefs = () => {
- const refs = formRef?.value;
- if (!refs) return [];
- return Array.isArray(refs) ? refs : [refs];
- };
- const scrollToFirstError = async () => {
- if (!formRef?.value || !scrollFn) return;
- await nextTick();
- const refsToSearch = getFormRefs();
- for (const ref of refsToSearch) {
- if (!ref) continue;
- const components = ref.getValidationComponents();
- if (!components) continue;
- const firstErrorComponent = components.find((c) => c.hasError);
- if (firstErrorComponent) {
- const container = containerRef?.value || containerRef;
- firstErrorComponent.focus();
- scrollFn(firstErrorComponent, container);
- return;
- }
- }
- };
- const execute = async (apiCallThunk) => {
- loading.value = true;
- validationErrors.value = {};
- let allValid = true;
- const refsToValidate = getFormRefs();
- if (refsToValidate.length > 0) {
- for (const ref of refsToValidate) {
- if (ref) {
- const success = await ref.validate(true);
- if (!success) {
- allValid = false;
- }
- }
- }
- }
- if (!allValid) {
- loading.value = false;
- await scrollToFirstError();
- throw new Error("Frontend validation failed.");
- }
- try {
- const response = await apiCallThunk();
- if (typeof onSuccess === "function") {
- await onSuccess(response);
- } else {
- return response;
- }
- } catch (error) {
- await handleError(error);
- } finally {
- loading.value = false;
- }
- };
- const handleError = async (error) => {
- if (error?.response?.status === 422) {
- const errors = error.response.data.errors || {};
- for (const key in errors) {
- const message = errors[key][0];
- validationErrors.value[key] = message;
- }
- await scrollToFirstError();
- }
- await nextTick();
- if (typeof onError === "function") {
- await onError(error);
- } else {
- throw error;
- }
- };
- return {
- loading,
- validationErrors,
- execute,
- };
- }
|