Components
DynamicFormDrawer
Drawer laterale con form dinamico per creazione/modifica record con autoload remoto.
Panoramica
DynamicFormDrawer apre un drawer laterale (PrimeVue Drawer) contenente un DynamicFormLayouts. A differenza di DynamicFormDialog, supporta:
- Posizione configurabile:
left,right,top,bottom - Auto-fetch del record: se passi
keyValue+fetchFn, il drawer carica automaticamente i dati alla apertura - Dimensione configurabile: tramite la prop
sizedelDrawerdi@pzeta/vue-components(small/medium/large/full)
Casi d'uso tipici:
- Modifica record cliccando una riga di una lista, senza navigazione
- Form di dettaglio scivola da destra mantenendo visibile la lista
- Wizard di creazione multi-step con
displayMode="wizard"
Anteprima live (con createFn mockato)
Utilizzo
Creazione
<!-- Codice reale con API -->
<script setup lang="ts">
import { ref } from 'vue'
import { DynamicFormDrawer } from '@pzeta/vue-form'
const showDrawer = ref(false)
const schema = {
sections: [
{
title: 'Nuovo utente',
rows: [
{
fields: [
{ name: 'nome', type: 'text', label: 'Nome', validation: 'required', required: true },
{ name: 'cognome', type: 'text', label: 'Cognome', validation: 'required', required: true }
]
},
{
fields: [
{ name: 'email', type: 'email', label: 'Email', validation: 'required|email', required: true }
]
}
]
}
]
}
async function handleCreate(data: Record<string, unknown>) {
return api.createUtente(data)
}
</script>
<template>
<Button label="Nuovo utente" icon="pi pi-plus" @click="showDrawer = true" />
<DynamicFormDrawer
v-model:visible="showDrawer"
:schema="schema"
:is-edit="false"
:create-fn="handleCreate"
header="Nuovo utente"
position="right"
size="medium"
/>
</template>
Modifica con auto-fetch
<!-- Codice reale con API -->
<script setup lang="ts">
import { ref } from 'vue'
import { DynamicFormDrawer } from '@pzeta/vue-form'
const showDrawer = ref(false)
const utenteSelezionatoId = ref<number | null>(null)
async function fetchUtente(id: string | number) {
const response = await fetch(`/api/utenti/${id}`)
return response.json()
}
async function updateUtente(id: string | number, data: Record<string, unknown>) {
const response = await fetch(`/api/utenti/${id}`, {
method: 'PUT',
body: JSON.stringify(data)
})
return response.json()
}
function modifica(id: number) {
utenteSelezionatoId.value = id
showDrawer.value = true
}
</script>
<template>
<Button label="Modifica" icon="pi pi-pencil" @click="modifica(42)" />
<DynamicFormDrawer
v-model:visible="showDrawer"
:schema="schema"
:is-edit="true"
:key-value="utenteSelezionatoId ?? undefined"
:fetch-fn="fetchUtente"
:update-fn="updateUtente"
header="Modifica utente"
position="right"
/>
</template>
Quando isEdit=true + keyValue + fetchFn sono presenti, il drawer chiama fetchFn(keyValue) all'apertura e popola initialData con il risultato.
Props
| Prop | Tipo | Default | Descrizione |
|---|---|---|---|
visible | boolean | — | Visibilità drawer (v-model:visible) |
schema | FormSchema | — | Schema del form |
displayMode | 'normal' | 'tabs' | 'wizard' | 'accordion' | 'normal' | Modalità del DynamicFormLayouts interno |
isEdit | boolean | false | Modalità modifica (vs creazione) |
initialData | Record<string, unknown> | {} | Dati iniziali (sovrascritti da fetchFn se presente) |
position | 'left' | 'right' | 'top' | 'bottom' | 'right' | Posizione del drawer |
header | string | '' | Titolo header drawer |
size | 'small' | 'medium' | 'large' | 'full' | 'medium' | Dimensione del drawer (mappa alla prop size del Drawer di @pzeta/vue-components) |
keyValue | string | number | '' | ID del record per la modalità modifica |
fetchFn | (id) => Promise<Record<string, unknown>> | — | Funzione di fetch del record per la modifica |
createFn | (data) => Promise<Record<string, unknown>> | — | Funzione di creazione |
updateFn | (id, data) => Promise<Record<string, unknown>> | — | Funzione di aggiornamento |
drawerClass | string | — | Deprecata e non funzionante: il Drawer di @pzeta/vue-components usa <Teleport> e non eredita l'attributo class. Usare size. Verrà rimossa in una major successiva |
Eventi
| Evento | Payload | Descrizione |
|---|---|---|
update:visible | boolean | Cambio visibilità (compatibile v-model:visible). Emesso a false su click X o overlay |
save | Record<string, unknown> | Submit completato. Payload: dirtyValues in modalità isEdit, altrimenti formData completo |
update:initial-data | Record<string, unknown> | Emesso dopo fetchFn (load record) o dopo createFn/updateFn (record salvato/ricaricato). Utile per sincronizzare lo stato del parent |
error | Error | Errore in fetch/create/update |
Differenza con DynamicFormDrawerWithTable
| Aspetto | DynamicFormDrawer | DynamicFormDrawerWithTable |
|---|---|---|
| Lista record | ❌ — solo form di un singolo record | ✅ — tabella + form integrati |
| Auto-fetch del record | ✅ via fetchFn(keyValue) | ✅ via fetchAllFn(filters) per la lista |
| Operazioni delete | ❌ | ✅ via deleteFn |
| Quando usarlo | Form di dettaglio standalone | Pannello completo CRUD entità |