Docs›Componentes (Admin)›mad-multi-search-field
Componentes (Admin)

mad-multi-search-field

Multi-select com chips + busca.

Select multiplo com busca client-side (chips) sobre options ja carregadas em memoria (:options). Suporta dois modos de persistencia: comma (CSV numa coluna) ou table (tabela pivot 1:N).

Nao confundir com <mad-dbmulti-search-field> — esse e um componente DIFERENTE (ver dbmulti-search.md), que faz busca AJAX server-side no banco via model/display (sem precisar de :options pre-carregadas). <mad-multi-search-field> nao tem prop model/display/query — so aceita options ja prontas.

Para texto livre (sem selecao de lista), ver search-field.md. Para selecao unica com busca, ver unique-search.md.

Props

Prop Tipo Default Descricao
name string '' Nome do campo (enviado como name[])
label string '' Label
width string '' Largura inline
max-width string '' Largura maxima inline
options array [] [id => label, ...]
selected array/string [] IDs pre-selecionados (array ou CSV). Auto-resolvido do MadRenderContext quando vazio
placeholder string 'Selecione...'
min-length int 0 Caracteres minimos antes de filtrar
max-size int 0 Maximo de itens (0 = ilimitado)
mode string 'comma' comma (CSV na coluna) ou table (pivot)
pivot-model string '' Classe do model Eloquent da tabela pivot (mode=table)
foreign-key string '' Coluna FK do registro pai (mode=table)
item-key string '' Coluna FK do item selecionado (mode=table)
database string MAIN_DATABASE (fallback business) Conexao usada para carregar/gravar o pivot (mode=table). Sem a constante MAIN_DATABASE definida, cai em business
hint string '' Texto de ajuda
error string '' Mensagem de erro
required bool false
disabled bool false
attrs string '' Atributos HTML extras
no-results-create-action string '' Classe::metodo — abre form em drawer/modal quando a busca nao acha nada
no-results-create-label string 'Cadastrar novo'
no-results-create-icon string 'plus' Icone Lucide
no-results-create-class string 'mad-btn mad-btn-primary mad-btn-sm'
no-results-quick-register-action string '' Classe::metodoEstatico — cadastro inline sem sair do select
no-results-quick-register-label string 'Adicionar'
no-results-quick-register-icon string 'check'
no-results-quick-register-class string 'mad-btn mad-btn-success mad-btn-sm'
no-results-quick-fields array [] Campos extras exibidos no cadastro rapido (ver dbcombo-field.md)
no-results-message string '' Texto exibido no topo do bloco de no-results

mode, pivot-model, foreign-key, item-key e database nao tem default declarado no @props() do componente — sao atributos Blade passados direto e resolvidos com fallback (?? 'comma', etc.) no @php do componente (mesmo efeito pratico de uma prop).

Mode comma — CSV numa coluna

<mad-multi-search-field name="tags" label="Tags"
    :options="$tagOptions" />

No banco: tags = '1,5,12'. O form->save() persiste como string. No onEdit, form->fill($record) distribui automaticamente.

Mode table — pivot 1:N

<mad-multi-search-field name="produtos" label="Produtos do pacote"
    :options="$prodOptions"
    mode="table"
    pivot-model="PacoteProduto"
    foreign-key="pacote_id"
    item-key="produto_id" />

O form->save($pacote) faz delete all + insert na tabela pacote_produto automaticamente no _afterStore(). No onEdit, o componente carrega os IDs ja vinculados via MadRenderContext::loadPivotSelected() — nao precisa fazer nada manual.

Com max-size

<mad-multi-search-field name="categorias" label="Categorias"
    :options="$catOptions" max-size="3"
    placeholder="Ate 3 categorias" />

Evento change (PHP)

Aceita mad:change="metodo" via attrs. Atencao: como o campo e um <select multiple> nativo por baixo, o evento change do browser so expoe el.value, que para um select multiplo retorna apenas o valor da primeira <option> selecionada (limitacao do DOM, nao do MAD) — nao a lista completa. Para reagir a toda a selecao, leia o array completo a partir do form no submit ($this->form->getData()->tags), nao do mad:change.

<mad-multi-search-field name="tags" label="Tags"
    :options="$tagOptions"
    attrs='mad:change="onTagsChange"' />
public function onTagsChange(string $value): void
{
    // $value e so a primeira option selecionada — uso tipico aqui e
    // disparar um efeito colateral leve (ex: log, contador), nao ler
    // a selecao inteira.
}

No-results: criar/cadastrar inline

Quando a busca nao encontra nada nas options carregadas, o componente pode mostrar um botao para abrir um form de cadastro (drawer/modal) ou um cadastro rapido inline — mesma API de no-results-* usada em todos os campos MAD Select do framework (unique-search, dbunique-search, dbmulti-search, dbcombo-field). Ver dbcombo-field.md para a API completa (formato do retorno do quickRegister, no-results-quick-fields, etc).

<mad-multi-search-field name="categorias" label="Categorias"
    :options="$catOptions"
    no-results-create-action="CategoriaForm::show"
    no-results-quick-register-action="CategoriaForm::quickRegister"
    no-results-message="Nao achou? Cadastre:" />

O quickRegister precisa ser metodo estatico publico que recebe ['term' => $nomeDigitado, 'field_name' => ..., ...] e retorna ['value' => $id, 'label' => $display].

Quando usar cada componente

Cenario Usar
Search box de filtro/listagem (texto livre) <mad-search-field> (ver search-field.md)
Selecao unica com options em memoria <mad-unique-search-field> (ver unique-search.md)
Selecao unica com busca AJAX no banco (lista grande) <mad-dbunique-search-field> (ver dbunique-search.md)
Selecao multipla com options em memoria <mad-multi-search-field> (esta pagina)
Selecao multipla com busca AJAX no banco (lista grande) <mad-dbmulti-search-field> (ver dbmulti-search.md)
Selecao multipla salva como CSV em coluna mode="comma"
Selecao multipla salva em tabela pivot mode="table"
Busca com modal grid (varias colunas, paginacao) <mad-seek> (ver seek.md)

NUNCA fazer

{{-- ERRADO: select multiplo nativo com size --}}
<select name="tags[]" multiple size="5">
    @foreach($tags as $id => $nome)
        <option value="{{ $id }}">{{ $nome }}</option>
    @endforeach
</select>

{{-- CERTO --}}
<mad-multi-search-field name="tags" :options="$tags" />

{{-- ERRADO: passar model/display esperando busca AJAX no banco --}}
<mad-multi-search-field name="produtos" model="Produto" display="nome" />
{{-- multi-search-field nao tem prop "model" — so aceita :options ja carregadas --}}

{{-- CERTO: usar dbmulti-search-field para busca AJAX no banco --}}
<mad-dbmulti-search-field name="produtos" model="Produto" display="nome" />

{{-- ERRADO: persistir multi manualmente em tabela pivot --}}
$this->form->save($pacote);
PacoteProduto::where('pacote_id', $pacote->id)->delete();
foreach ($_POST['produtos'] as $pid) { /* insert */ }

{{-- CERTO: declarar mode=table no Blade, save() faz tudo --}}
<mad-multi-search-field name="produtos" :options="$opts"
    mode="table" pivot-model="PacoteProduto"
    foreign-key="pacote_id" item-key="produto_id" />

{{-- ERRADO: widget de busca client-side manual --}}
<select id="meu-select" multiple class="mad-input"></select>
<script>/* inicializar lib de busca manualmente */</script>

{{-- CERTO --}}
<mad-multi-search-field name="campo" :options="$opts" />