Allow and respect action/target in ValidatedForm and ModalDialog

pull/256/head
Candid Dauth 2024-03-05 04:44:39 +01:00
rodzic b211800973
commit 441780beab
3 zmienionych plików z 31 dodań i 9 usunięć

Wyświetl plik

@ -226,13 +226,13 @@
:id="`${id}-open-form`"
method="get"
:action="url"
@submit="handleSubmit"
@submit.prevent="handleSubmit"
ref="openFormRef"
></ValidatedForm>
<ValidatedForm
:id="`${id}-search-form`"
@submit="$event.waitUntil(search(searchQuery, 0))"
@submit.prevent="$event.waitUntil(search(searchQuery, 0))"
class="results"
></ValidatedForm>
</template>

Wyświetl plik

@ -20,6 +20,8 @@
okLabel?: string;
okVariant?: ThemeColour;
formValidationError?: string | undefined;
action?: string;
target?: string;
}>(), {
isModified: false,
size: "lg"
@ -34,7 +36,6 @@
const validatedFormRef = ref<InstanceType<typeof ValidatedForm>>();
const isSubmitting = computed(() => validatedFormRef.value?.formData.isSubmitting);
const submitRef = ref<HTMLElement>();
const modalElementRef = ref<InstanceType<typeof AttributePreservingElement>>();
const modalRef = toRef(() => modalElementRef.value?.elementRef);
@ -58,8 +59,13 @@
function handleSubmit(event: CustomSubmitEvent) {
if (isCloseButton.value) {
event.preventDefault();
modal.hide();
} else {
if (!props.action) {
event.preventDefault();
}
emit("submit", event);
}
}
@ -87,6 +93,8 @@
<div class="modal-dialog modal-dialog-scrollable">
<ValidatedForm
class="modal-content"
:action="props.action"
:target="props.target"
@submit="handleSubmit"
ref="validatedFormRef"
:noValidate="isCloseButton"
@ -124,7 +132,6 @@
class="btn btn-primary"
:class="props.okVariant && `btn-${props.okVariant}`"
:disabled="isSubmitting || props.isBusy"
ref="submitRef"
>
<div v-if="isSubmitting" class="spinner-border spinner-border-sm"></div>
{{props.okLabel ?? (isCloseButton ? 'Close' : 'Save')}}

Wyświetl plik

@ -1,6 +1,6 @@
<script lang="ts">
import { type Ref, onScopeDispose, reactive, readonly, ref, watchEffect, toRef } from "vue";
import { type ExtendableEventMixin, extendableEventMixin } from "../../../utils/utils";
import { type ExtendableEventMixin, extendableEventMixin, useDomEventListener } from "../../../utils/utils";
import { useToasts } from "../toasts/toasts.vue";
export interface ValidatedFormData {
@ -13,6 +13,7 @@
}
export interface CustomSubmitEvent extends ExtendableEventMixin {
preventDefault(): void;
}
const allForms = reactive(new Map<Ref<HTMLFormElement | undefined>, ValidatedFormData>());
@ -48,9 +49,19 @@
}
}
const event = { ...extendableEventMixin };
let prevented = false;
const event = {
...extendableEventMixin,
preventDefault() {
prevented = true;
}
};
onSubmit(event);
await event._awaitPromises();
if (!prevented) {
formRef.value?.submit();
}
} finally {
data.isSubmitting = false;
}
@ -77,6 +88,11 @@
data.isValidating = [...isValidating.values()].some((v) => v);
});
useDomEventListener(formRef, "submit", (e) => {
e.preventDefault();
data.submit();
});
allForms.set(formRef, data);
onScopeDispose(() => {
@ -120,11 +136,10 @@
<template>
<form
@submit.prevent="formData.submit()"
novalidate
ref="formRef"
:action="props.action"
:target="props.target ?? 'javascript:'"
:action="props.action ?? 'javascript:'"
:target="props.target"
:class="{ 'fm-was-validated': formData.isTouched }"
>
<slot :formData="formData"/>