Components
ListboxRemote
Listbox con caricamento dati remoto, selezione singola o multipla, raggruppamento e immagini nelle opzioni.
Panoramica
ListboxRemote è un componente listbox che carica le opzioni in modo asincrono tramite fetchFn. A differenza di SelectRemote (dropdown), la listbox mostra tutte le opzioni in una lista scorrevole sempre visibile.
Caratteristiche principali:
- Selezione singola o multipla con checkbox visivi
- In alternativa a
fetchFn, la chiamata PostgREST può essere composta dal componente dichiarando la risorsa: Sorgente datiendpoint - Raggruppamento opzioni per categoria
- Filtri dinamici su altri campi del form
- Template personalizzato per etichette
- Immagini nelle opzioni
- Messaggio personalizzabile per lista vuota
Casi d'uso tipici: selezione permessi/ruoli, assegnazione tag multipli, selezione elementi da una lista breve sempre visibile.
Anteprima live (con fetchFn mockato)
Utilizzo nello schema
const schema = [{
name: 'permessi',
type: 'listboxremote',
label: 'Permessi utente',
props: {
fetchFn: fetchPermessi,
optionLabel: 'nome',
optionValue: 'id',
multiple: true,
checkmark: true,
showFilter: true,
}
}, {
name: 'paese',
type: 'listboxremote',
label: 'Paese',
props: {
fetchFn: fetchPaesi,
optionLabel: 'nome',
optionValue: 'codice',
optionImage: 'bandiera',
multiple: false,
}
}, {
// Con raggruppamento
name: 'categorieSelezionate',
type: 'listboxremote',
label: 'Categorie',
props: {
fetchFn: fetchCategorieGruppate,
optionGroupLabel: 'nomeGruppo',
optionGroupChildren: 'voci',
optionLabel: 'nome',
optionValue: 'id',
multiple: true,
}
}]
Utilizzo diretto
Con slot header, footer e opzione personalizzata
Sorgente dati endpoint
In alternativa a fetchFn, ListboxRemote può comporre da sé la chiamata PostgREST a partire dalla risorsa dichiarata:
props: {
endpoint: 'auth.ruoli',
order: 'descrizione.asc',
optionLabel: 'descrizione',
optionValue: 'idruolo',
multiple: true
}
fetchFn ha sempre la precedenza: se sono presenti entrambe, endpoint viene ignorato. La forma dell'endpoint, la traduzione dei filtri e l'ordine con cui viene risolto il trasporto sono descritti in Sorgente dati endpoint.
Props
| Prop | Tipo | Default | Descrizione |
|---|---|---|---|
modelValue | unknown | — | Valore/i selezionato/i (v-model); array se multiple: true |
label | string | — | Etichetta del campo |
helperText | string | — | Testo di supporto sotto il campo |
error | string | — | Messaggio di errore (attiva stato invalid) |
disabled | boolean | false | Disabilita il campo |
invalid | boolean | false | Attiva visivamente lo stato di errore |
required | boolean | false | Indica campo obbligatorio |
fetchFn | FetchFn | — | Funzione asincrona per caricare le opzioni |
filter | string | FilterCriteria | — | Filtro statico passato alla fetchFn |
filterFields | RemoteFilterField[] | [] | Campi del form da osservare per filtri dinamici; la forma estesa { field, column, operator } permette colonna e operatore diversi |
fullData | Record<string, unknown> | {} | Dati completi del form (per filtri dinamici) |
endpoint | string | — | Risorsa PostgREST [schema.]risorsa, alternativa a fetchFn — vedi Sorgente dati endpoint |
select | string | — | Colonne da selezionare (solo con endpoint) |
order | string | — | Ordinamento PostgREST, es. 'nome.asc' (solo con endpoint) |
limit | number | — | Numero massimo di righe restituite (solo con endpoint) |
baseUrl | string | '' | Prefisso del gateway PostgREST, se l'endpoint dichiara uno schema |
keyName | string | 'id' | Chiave primaria della risorsa (solo client PostgREST standalone) |
optionLabel | string | 'label' | Proprietà da usare come etichetta |
optionTemplate | string | — | Template interpolato per l'etichetta |
optionValue | string | 'value' | Proprietà da usare come valore |
optionImage | string | — | Proprietà contenente URL immagine |
optionDisabled | string | Function | — | Proprietà o funzione per disabilitare opzioni |
optionGroupLabel | string | — | Proprietà per etichetta gruppo |
optionGroupChildren | string | — | Proprietà contenente figli del gruppo |
multiple | boolean | false | Abilita selezione multipla |
showFilter | boolean | false | Mostra campo di ricerca |
filterPlaceholder | string | (da i18n) | Placeholder del campo di ricerca |
checkmark | boolean | true | Mostra checkmark sugli elementi selezionati |
emptyMessage | string | (da i18n) | Messaggio lista vuota |
listStyle | string | 'max-height: 200px' | Stile CSS inline per la lista |
Slot
| Slot | Props | Descrizione |
|---|---|---|
header | — | Contenuto sopra la lista |
footer | — | Contenuto sotto la lista |
option | { option } | Template personalizzato per ogni opzione |
optiongroup | { option } | Template personalizzato per intestazione gruppo |
empty | — | Contenuto lista vuota |
loader | — | Contenuto durante il caricamento |
Metodi esposti
| Metodo | Descrizione |
|---|---|
reload() | Ricarica i dati chiamando nuovamente la fetchFn |
Eventi
| Evento | Payload | Descrizione |
|---|---|---|
update:modelValue | unknown | Valore aggiornato |
change | { originalEvent: Event, value: unknown } | Emesso al cambio selezione |
Validazione suggerita
import { z } from 'zod'
const schema = z.object({
// Selezione singola
paese: z.string().min(1, 'Seleziona un paese').nullable(),
// Selezione multipla
permessi: z.array(z.number())
.min(1, 'Seleziona almeno un permesso'),
})