Components
PickListRemote
Doppia lista per trasferimento elementi con caricamento remoto: spostamento tra lista disponibili e lista selezionati.
Panoramica
PickListRemote è un componente a doppia lista che carica gli elementi disponibili da una sorgente remota e consente di spostarli tra una lista "source" (disponibili) e una lista "target" (selezionati). Il valore emesso è l'array degli elementi nel target.
Caratteristiche principali:
- Caricamento asincrono elementi disponibili tramite
fetchFn - Separazione automatica source/target basata su
modelValue - Spostamento singolo o multiplo con pulsanti freccia
- Controlli di ordinamento per ogni lista
- Template personalizzato per la visualizzazione degli elementi
- Gestione eventi
moveToTargetemoveToSource
Casi d'uso tipici: assegnazione utenti a ruoli/gruppi, selezione permessi da assegnare, configurazione colonne visibili, selezione prodotti per un bundle.
Anteprima live (con fetchFn mockato)
Utilizzo nello schema
const schema = [{
name: 'utentiAssegnati',
type: 'picklist',
label: 'Assegna utenti al gruppo',
props: {
fetchFn: fetchTuttiUtenti,
optionLabel: 'nomeCompleto',
optionValue: 'id',
sourceTitle: 'Utenti disponibili',
targetTitle: 'Utenti nel gruppo',
}
}]
Utilizzo diretto
<PickListRemote
v-model="utentiAssegnati"
:fetch-fn="fetchTuttiUtenti"
option-label="nomeCompleto"
option-value="id"
source-title="Utenti disponibili"
target-title="Utenti assegnati"
label="Assegnazione utenti"
@move-to-target="handleAssegna"
@move-to-source="handleRevoca"
/>
Con template personalizzato
<PickListRemote
v-model="permessiSelezionati"
:fetch-fn="fetchPermessi"
option-value="codice"
source-title="Permessi disponibili"
target-title="Permessi assegnati"
>
<template #option="{ option }">
<div class="flex items-center gap-2">
<i :class="option.icona" class="text-blue-500" />
<div>
<div class="font-medium">{{ option.nome }}</div>
<div class="text-xs text-gray-500">{{ option.categoria }}</div>
</div>
</div>
</template>
</PickListRemote>
Come funziona la sincronizzazione source/target
// All'arrivo dei dati da fetchFn:
// - allData = tutti gli elementi dal server
// - modelValue = elementi già nel target
// Il componente calcola:
// source = allData.filter(item => !targetValues.includes(item[optionValue]))
// target = modelValue
// Esempio:
// allData = [{id:1, nome:'Mario'}, {id:2, nome:'Luigi'}, {id:3, nome:'Peach'}]
// modelValue = [{id:2, nome:'Luigi'}]
// source = [{id:1, nome:'Mario'}, {id:3, nome:'Peach'}]
// target = [{id:2, nome:'Luigi'}]
Props
| Prop | Tipo | Default | Descrizione |
|---|---|---|---|
modelValue | Array<Record<string, unknown>> | null | [] | Elementi nel target (v-model) |
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 trasferimento |
invalid | boolean | false | Attiva visivamente lo stato di errore |
fetchFn | FetchFn | — | Funzione per caricare tutti gli elementi disponibili |
filter | string | FilterCriteria | — | Filtro statico passato alla fetchFn |
optionLabel | string | 'label' | Proprietà da usare come etichetta |
optionValue | string | 'value' | Proprietà da usare come identificatore univoco |
sourceTitle | string | (da i18n: 'Disponibili') | Titolo lista sorgente |
targetTitle | string | (da i18n: 'Selezionati') | Titolo lista destinazione |
dataKey | string | (uguale a optionValue) | Chiave univoca per PrimeVue PickList |
scrollHeight | string | '14rem' | Altezza area scrollabile di ogni lista |
showSourceControls | boolean | true | Mostra pulsanti di ordinamento nella lista source |
showTargetControls | boolean | true | Mostra pulsanti di ordinamento nella lista target |
Slot
| Slot | Props | Descrizione |
|---|---|---|
sourceheader | — | Header lista source (sovrascrive sourceTitle) |
targetheader | — | Header lista target (sovrascrive targetTitle) |
option | { option, index } | Template personalizzato per ogni elemento |
Metodi esposti
| Metodo | Descrizione |
|---|---|
reload() | Ricarica tutti gli elementi chiamando nuovamente la fetchFn |
Eventi
| Evento | Payload | Descrizione |
|---|---|---|
update:modelValue | Array<Record<string, unknown>> | Elementi aggiornati nel target |
moveToTarget | Array<Record<string, unknown>> | Elementi appena spostati nel target |
moveToSource | Array<Record<string, unknown>> | Elementi appena spostati nel source |
Nota: Gli eventi
move-all-to-targetemove-all-to-sourcedi PrimeVue vengono internamente mappati sumoveToTarget/moveToSource.
Validazione suggerita
import { z } from 'zod'
const schema = z.object({
utentiAssegnati: z.array(z.object({ id: z.number() }))
.min(1, 'Assegna almeno un utente')
.max(10, 'Massimo 10 utenti per gruppo'),
})