Docs›Componentes (Admin)›mad-checklist-field
Componentes (Admin)

mad-checklist-field

Checklist com colunas customizadas.

Lista de seleção múltipla com busca, contador, select-all e colunas customizadas — para quando o <mad-checkbox-group-field> simples não basta (precisa mostrar mais de uma coluna por item, ex: código + nome + status). Integra com MadForm/MadRenderContext igual aos outros campos multi-select: form->fill() pré-marca os itens, form->save() persiste.

<mad-checklist-field> — items manuais (array em memória)

Props

Prop Tipo Default Descrição
name string '' Nome do campo (obrigatório, envia como name[])
label string '' Label acima da lista
items array [] Linhas — array de arrays/objetos (cada um vira uma row)
columns array [] Colunas a exibir — normalmente via <mad-col> filhos (ver abaixo)
id-column string 'id' Campo da row usado como identificador (o que vai em name[])
selected array auto IDs pré-marcados (auto via MadRenderContext quando omitido)
searchable bool true Mostra a busca client-side no topo
height string '320px' Altura máxima da área scrollável
placeholder string 'Buscar...' Placeholder do campo de busca
mode string 'comma' comma (CSV numa coluna) ou table (pivot 1:N)
pivot-model string '' Classe do model Eloquent da pivot (mode=table)
foreign-key string '' Coluna FK do registro pai na pivot (mode=table)
item-key string '' Coluna FK do item selecionado na pivot (mode=table)
database string MAIN_DATABASE ou business Conexão usada na leitura/escrita da pivot
hint string '' Texto de ajuda
error string '' Mensagem de erro
required bool false
disabled bool false
attrs string '' Atributos HTML extras

Colunas via <mad-col> (compilado em tempo de build)

As colunas se declaram como filhos <mad-col> — o compilador Blade do MAD extrai essas tags e injeta :columns="[...]" automaticamente, então não existe <mad-col> em runtime:

<mad-checklist-field name="opts" :items="['a' => 'Opt A', 'b' => 'Opt B']" :selected="['a']">
    <mad-col field="id" label="Cód" width="60px" center />
    <mad-col field="label" label="Nome" />
</mad-checklist-field>

Atributos aceitos em <mad-col> dentro do checklist: field (chave da row), label, width, center/right (alinhamento), transform (callable/expressão PHP). Um field prefixado com __ (ou a flag slot) vira coluna do tipo slot — <td> vazio (data-mad-cl-col/data-mad-cl-row) para injetar conteúdo dinâmico via JS depois da renderização (ex: botões de ação por linha), igual ao mecanismo de slot do mad-grid.

Uso básico

@php
    $items = [
        ['id' => 1, 'nome' => 'Leitura'],
        ['id' => 2, 'nome' => 'Escrita'],
        ['id' => 3, 'nome' => 'Exclusão'],
    ];
@endphp
<mad-checklist-field name="permissoes" label="Permissões" :items="$items" :selected="[1, 2]">
    <mad-col field="id" label="ID" width="60px" center />
    <mad-col field="nome" label="Permissão" />
</mad-checklist-field>

<mad-dbchecklist-field> — items via model Eloquent (auto-query)

Mesmo conceito do dbcombo-field: recebe model/display/filters e carrega via Eloquent/Query Builder — sem precisar montar items manualmente no controller.

Props adicionais (sobre as do mad-checklist-field)

Prop Tipo Default Descrição
model string '' Classe do model Eloquent fonte das options
database string MAIN_DATABASE Conexão
key string 'id' Campo PK
display string 'nome' Campo de exibição. Aceita template {nome} ({sigla})
order-by string display Ordenação
query Builder null Eloquent/Query Builder pronto (alternativa a model+filters)
filters array [] [['campo','op','val'], ...] — aplicado no Query Builder

Quando columns não é declarado (nem via <mad-col>), o componente auto-gera duas colunas: id (largura fixa, centralizada) + a coluna de display.

Uso básico

<mad-dbchecklist-field name="grupos" label="Grupos do usuário"
    model="SystemGroup" database="permission" display="name" height="400px">
    <mad-col field="id" label="ID" width="60px" center />
    <mad-col field="name" label="Nome" />
</mad-dbchecklist-field>

Com filtro

<mad-dbchecklist-field name="categorias" label="Categorias"
    model="Categoria" display="nome"
    :filters="[['ativo', '=', '1']]" />

Persistência — mode="table" + form->save() (recomendado)

Igual ao <mad-dbcheckbox-group-field mode="table">: declare pivot-model + foreign-key + item-key, e form->save($record) resolve tudo — apaga a pivot do registro pai e reinsere um row por item marcado. O selected carrega automaticamente da pivot no onEdit (via form->fill()), sem código extra.

<mad-dbchecklist-field name="grupos" label="Grupos do usuário"
    model="SystemGroup" database="permission" display="name"
    mode="table" pivot-model="SystemUserGroup"
    foreign-key="system_user_id" item-key="system_group_id">
    <mad-col field="id" label="ID" width="60px" center />
    <mad-col field="name" label="Nome" />
</mad-dbchecklist-field>
use Illuminate\Support\Facades\DB;

public function onSave(): MadResponse
{
    DB::connection('business')->transaction(function () {
        $user = SystemUsers::findOrNew($this->registroId);
        $this->form->save($user); // salva campos + sincroniza a pivot automaticamente
    });

    return (new MadResponse())->toast('Salvo!', 'success')->closeDrawer();
}

Persistência — mode="comma" (CSV numa coluna)

Sem pivot-model, o mode padrão é comma: form->save($record) grava os IDs selecionados como CSV na própria coluna name.

<mad-checklist-field name="categorias_csv" label="Categorias" :items="$items" />
$this->form->save($record);
// $record->categorias_csv = '1,3,7'

Persistência manual — MadChecklistTrait (quando precisa de dados extras por item)

Use o trait Mad\Form\MadChecklistTrait (saveChecklist/loadChecklist) em vez do mode="table" automático quando a tabela pivot tem colunas extras por linha (ex: permissões granulares por grupo) que não cabem no contrato padrão de foreign-key/item-key:

use Mad\Form\MadChecklistTrait;

class GrupoProgramaForm extends MadComponent
{
    use MadChecklistTrait;

    public function onEdit(int $id): void
    {
        $cl = $this->loadChecklist(IamGroupProgram::class, 'program_id', $id, 'group_id',
            fn ($record) => json_decode($record->actions ?: '[]', true)
        );
        $this->form->setItems('groups', $this->gruposDisponiveis(), $cl['selected']);
        // $cl['extras'] = [groupId => actions, ...] — use pra pré-preencher colunas extras
    }

    public function onSave(): MadResponse
    {
        $data = $this->form->getData();

        DB::connection('iam')->transaction(function () use ($data) {
            $this->saveChecklist(IamGroupProgram::class, 'program_id', $this->registroId,
                'group_id', $data->groups,
                fn ($record, $itemId) => $record->actions = json_encode($_POST["{$itemId}_actions"] ?? [])
            );
        });

        return (new MadResponse())->toast('Salvo!', 'success')->closeDrawer();
    }
}

Resumo de decisão

Preciso... Usar
Booleano simples (sim/não) <mad-checkbox-field>
N entre N, sem precisar de colunas extras por item <mad-checkbox-group-field> / <mad-dbcheckbox-group-field>
N entre N, com múltiplas colunas por item (código, nome, status...) <mad-checklist-field> / <mad-dbchecklist-field>
Pivot 1:N simples (sem dado extra por linha) mode="table" + form->save()
Pivot 1:N com colunas extras por linha (ex: permissões por grupo) MadChecklistTrait (saveChecklist/loadChecklist)

NUNCA fazer

{{-- ERRADO: @foreach manual de checkboxes pra simular um checklist com colunas --}}
@foreach($grupos as $g)
    <label><input type="checkbox" name="grupos[]" value="{{ $g->id }}"> {{ $g->name }} ({{ $g->id }})</label>
@endforeach

{{-- CERTO --}}
<mad-dbchecklist-field name="grupos" model="SystemGroup" display="name">
    <mad-col field="id" label="ID" width="60px" center />
    <mad-col field="name" label="Nome" />
</mad-dbchecklist-field>

{{-- ERRADO: carregar items do banco no controller pra passar pro checklist manual --}}
@php $itens = Categoria::orderBy('nome')->get()->toArray(); @endphp
<mad-checklist-field name="cats" :items="$itens" />

{{-- CERTO: dbchecklist-field carrega sozinho --}}
<mad-dbchecklist-field name="cats" model="Categoria" display="nome" />

{{-- ERRADO: sincronizar a pivot manualmente quando mode=table resolve --}}
foreach ($_POST['grupos'] as $gid) {
    $ug = new SystemUserGroup();
    $ug->system_user_id = $user->id;
    $ug->system_group_id = $gid;
    $ug->save();
}

{{-- CERTO: mode=table + form->save() --}}
<mad-dbchecklist-field name="grupos" model="SystemGroup"
    mode="table" pivot-model="SystemUserGroup"
    foreign-key="system_user_id" item-key="system_group_id" />

{{-- ERRADO: <template x-for> aninhado dentro de <tr> pra renderizar colunas custom --}}
<template x-for="item in items">
    <tr>
        <template x-for="col in cols"><td x-text="item[col.key]"></td></template>
    </tr>
</template>
{{-- O parser HTML do browser remove <template> inválido dentro de <table>, quebrando o
     scoping do Alpine — é exatamente por isso que <mad-col> é resolvido em PHP (build time),
     não em Alpine x-for aninhado. --}}

{{-- CERTO: <mad-col> compilado em PHP, sem x-for aninhado em tr/td --}}
<mad-checklist-field name="opts" :items="$items">
    <mad-col field="id" label="ID" />
    <mad-col field="nome" label="Nome" />
</mad-checklist-field>