Formulärsmodal

Formulärsmodal är en standardmodal som kan presentera formulärsfält och hantera validering.

Formulärsmodalen baseras på en modal dialogruta av typen standard och visas i fullskärm i mobil (<640px).

Modalen har alltid en primärknapp för submit och en sekundärknapp för att avbryta och ångra. Alla fält valideras när användaren trycker på primärknappen.

  • Använd inte formulärsmodaler till stora formulär, begränsa formuläret till några få komponenter och undvik flerradiga inmatningsfält.
  • Öppna inte ytterligare modaler från en modal.

Användning

Du skapar själv upp din formulärsmodal genom att skapa upp en ny Vue-komponent där FFormModal-komponenten nyttjas.

Skapa först upp ett interface motsvarande den data din formulärsmodal ska arbeta med:

interface Person {
    name: string;
    age: string;
}

Din komponent ska innehålla en prop value motsvarande ett objekt av interfacet:

 export default defineComponent({
     props: {
+        value: {
+            type: Object as PropType<Person>,
+            required: true,
+        },
     },
 });

Template använder FFormModal och binder value dels som value-propen men också som v-model för respektive inmatningsfält. Inmatningsfälten läggs in i #input-text-fields-slotten.

<template>
    <f-form-modal :value>
        <template #header> Awesome Modal </template>
        <template #input-text-fields>
            <f-text-field v-model="value.name"> Namn </f-text-field>
            <f-text-field v-model="value.age"> Ålder </f-text-field>
        </template>
    </f-form-modal>
</template>
Fullständigt exempel
<template>
    <f-form-modal :value>
        <template #header> Awesome Modal </template>
        <template #input-text-fields>
            <f-text-field v-model="value.name"> Namn </f-text-field>
            <f-text-field v-model="value.age"> Ålder </f-text-field>
        </template>
    </f-form-modal>
</template>

<script lang="ts">
import { type PropType, defineComponent } from "vue";
import { FFormModal, FTextField } from "@fkui/vue";

interface Person {
    name: string;
    age: string;
}

export default defineComponent({
    components: { FFormModal, FTextField },
    props: {
        value: {
            type: Object as PropType<Person>,
            required: true,
        },
    },
});
</script>

Tänk på att

Data muteras direkt på value-propen. Det kan leda till oönskade konsekvenser om konsumenten skickas in existernade referenser till objekt istället för att skicka in en kopia eller nytt objekt. Du kan antingen låta din formulärsmodal hantera detta genom att internt kopiera value eller tydligt dokumentera att konsumenten måste skicka in en kopia.

Öppna modal

Du öppnar modalen med formModal() (options API) eller useModal() (composition API).

// options api
const result = await formModal<Person>(this, PersonFormModal);

// composition api
const { formModal } = useModal();

async function onOpen(): Promise<void> {
    const result = await formModal<Person>(PersonFormModal);
}

Returvärdet är Promise som löses ut med resolve(value) (det objekt som ligger lagrat i value när modalen stängs). Om användaren avbryter modalen avvisas Promise med reject() .

Förifylld data kan skickas in med propen value:

const result = await formModal<Person>(PersonFormModal, {
    props: {
        value: {
            name: "Kalle Anka",
            age: 60,
        },
    },
});

Användning med template (deprekerad)

Att använda FFormModal nästlad i template är deprekerat. Vi rekommenderar att du flyttar den till en egen Vue komponent och använder API för att öppna den. Se Användning för hur du använder FFormModal med API.

 <template>
     <div>
         <button type="button" @click="onClick">Open modal</button>
-        <f-form-modal></f-form-modal>
     </div>
 </template>

Formulärsmodal med flera knappar

Komponenten har en prop buttons som styr vilka knappar som finns i modalens sidfot. Med den kan du ta bort existerande knappar eller använda en helt egen uppsättning.

const formdata = await formModal(this, MyAwesomeModal, {
    props: {
        buttons: [
            /* ... */
        ],
    },
});

buttons är en lista av typen FModalButtonDescriptor:

export interface FModalButtonDescriptor {
    label: string;
    screenreader?: string;
    event?: string;
    reason?: string;
    type: "primary" | "secondary";
    submitButton?: boolean;
}
buttons: [{ label: "Stäng", event: "dismiss" }];

Två event har speciell innebörd:

  • dismiss: stänger modalen utan att spara formulärsdata.
  • submit: stänger modalen och returnerar formulärsdata till anroparen.

Skärmläsare

Du kan lägga till extra skärmläsartext på knappar med screenreader property:

-buttons: [{ label: "Stäng", event: "dismiss" }];
+buttons: [{ label: "Stäng", screenreader: "formuläret", event: "dismiss" }];

Om du använder screenreader för en knapp så kommer skärmläsare att läsa upp den texten efter knapptexten i label. Detta används för att tydliggöra vad knappen kommer att göra i de fallen där det kan vara otydligt för skärmläsaranvändare.

Validering av inmatad data

Inmatningsfälten valideras redan med vanlig validering, men om du behöver utföra extra validering (manuella steg, korsvalidering eller validering på backend och så vidare) så kan du använda beforeSubmit:

<f-form-modal
    :is-open="isOpen"
    :value="value"
    :before-submit="onBeforeSubmit"
    @submit="onSubmit"
>
</f-form-modal>

Notera att det är metoden onBeforeSubmit som ska skickas in i sin helhelt, anropa inte metoden med :before-submit="onBeforeSubmit()". I onBeforeSubmit har du möjlighet att sätta nya valideringsfel på inmatningsfält:

onBeforeSubmit(): void {
    const myField = getElementFromVueRef(this.$refs.myField);
    ValidationService.setError(myField, "This value is invalid!");
},

Vi rekommenderar att alla fel är kopplade till ett specifikt inmatningsfält men om du istället vill avbryta inskicket och presentera ett fel med exempelvis en meddeladeruta kan du returnera FFormModalAction.CANCEL från onBeforeSubmit:

onBeforeSubmit(): FFormModalAction {
    this.showErrorMessage = true;
    return FFormModalAction.CANCEL;
},

API

Props

fullscreen: boolean Optional

Enable fullscreen mode in mobile.

Default: true

isOpen: boolean Optional

If the modal is open. Use this to toggle if the modal should be visible or not.

Default: true

size: string Optional

See <f-modal> size props.

Default: ""

value: object Optional

The data that has been submitted.

Default: {}

useErrorList: boolean Optional

Include the error list component.

Default: true

formId: string Optional

The id for the form id attribute. If the prop is not set a random value will be generated.

Default: () => ElementIdService.generateElementId()

ariaCloseText: string Optional

The aria-label attribute text for the top right close button.

Default: undefined

beforeSubmit: FValidationFormCallback Optional

If given, this function is called before the [[submit]] event is emitted. See <f-validation-form> beforeSubmit props for more info.

Default: function() { /* do nothing */ }

beforeValidation: FValidationFormCallback Optional

If given, this function is called before the form data is validated and the [[submit]] event is emitted. See <f-validation-form> beforeValidation props for more info.

Default: function() { /* do nothing */ }

buttons: FModalButtonDescriptor[] Optional

Default: (): FModalButtonDescriptor[] => [ { label: TranslationService.provider.translate("fkui.form-modal.button.submit.text", "Spara"), event: "submit", type: "primary", submitButton: true, }, { label: TranslationService.provider.translate("fkui.form-modal.button.cancel.text", "Avbryt"), event: "dismiss", type: "secondary", }, ]

Events

cancel

Event that is dispatched when escape is pressed or when the cancel or close buttons are clicked. In most use cases the isOpen prop should be set to false when this event is triggered.

close

Event that is dispatched when escape is pressed or when the cancel or close buttons are clicked. In most use cases the isOpen prop should be set to false when this event is triggered.

Arguments:

  • <anonymous>: undefined
submit

Event that is dispatched when the submit button is is clicked. The event payload is the data that has been submitted.

Arguments:

  • <anonymous>: undefined

Slots

header

Slot for the header.

default

Slot for main content above text fields and buttons.

error-message

Slot for error message

input-text-fields

Slot for input text fields for entering text.

Relaterat

  • useModal() (composition API) formModal() (options API) för programatiskt användande av formulärsmodal.
  • Modal för mer information om modaler.

Esc för att stänga Pil upp/ner för att navigera Enter för att välja