Docs›Componentes (Admin)›mad-seek (DB Seek)
Componentes (Admin)

mad-seek (DB Seek)

Busca com modal grid paginado e filtros.

Campo de busca com modal de listagem (DB Seek). Mostra um input readonly com botao de lupa que abre um modal contendo um grid pesquisavel/paginavel/ordenavel. Ao selecionar uma linha, preenche o id (hidden) e o display (visivel), alem de campos auxiliares opcionais.

Formas de uso:

Forma Quando usar
<mad-seek> (tag compilada) Recomendado — declarativo no Blade, com <mad-column> e <mad-action> filhos
MadSeek::of('Model')->... (API fluent PHP) Quando precisa montar dinamicamente em PHP
<mad-dbseek-field> Componente Blade renderizado por baixo de <mad-seek> e de MadSeek::of() — raramente usado direto

<mad-seek-field> (sem "db") não é uma terceira forma do mesmo componente — é um primitivo separado e mais simples: só um input com botão de lupa que, ao clicar, dispara o evento JS mad:seek ({ name, onSeek, el }), sem modal nem grid embutidos. Use-o apenas se for montar sua própria lógica de busca custom (com seu próprio listener para mad:seek); para o fluxo padrão com modal + grid, use <mad-seek> ou <mad-dbseek-field>.

Props do <mad-seek>

Prop Tipo Default Descricao
model string '' Classe do model Eloquent (obrigatorio, ex: Pessoa)
name string '' Nome do campo hidden que armazena o ID (obrigatorio)
label string '' Label do campo
display string '' Coluna do model exibida no input apos selecao (obrigatorio)
value string '' ID pre-selecionado
text string '' Texto pre-preenchido (display do registro pre-selecionado)
placeholder string '' Placeholder do input
hint string '' Texto de ajuda
required bool false Campo obrigatorio
disabled bool false Campo desabilitado
modal-title string label Titulo do modal de busca
modal-size string 'xl' Tamanho do modal: sm, md, lg, xl ou valor CSS
per-page int 15 Registros por pagina no grid (default herdado de MadDataGrid::$perPage)
database string MAIN_DATABASE Conexao do banco
handler string '' Classe handler para acoes customizadas no grid

A tag declarativa <mad-seek> nao tem prop de filtro (sem criteria/filters/query) — ela sempre lista todos os registros do model. Para filtrar o grid, use a API fluent MadSeek::of('Model')->query($builder)->... (ver secao "Filtrando registros do grid" abaixo).

Filhos suportados

Tag Descricao
<mad-column> / <mad-col> Coluna do grid (mesmas props do <mad-col> do MadDataGrid)
<mad-action> / <mad-act> Acao customizada na linha do grid
<mad-nav> Acao de navegacao
<mad-del> Atalho de acao "Excluir" (onMadGridDelete, confirm, icone trash-2) — pouco comum dentro de um modal de busca, mas suportado
<mad-fill target="..." source="..." /> Campo auxiliar — preenche outro campo da tela ao selecionar

Uso basico

<mad-seek model="Pessoa" name="cliente_id" label="Cliente" display="nome"
    placeholder="Buscar cliente..." required per-page="10">
    <mad-column field="id"   label="Cod." width="70" sort />
    <mad-column field="nome" label="Nome" sort filter />
    <mad-column field="fone" label="Telefone" width="130" />
</mad-seek>

Com valor pre-selecionado

<mad-seek model="Pessoa" name="cliente_id" label="Cliente" display="nome"
    :value="$clienteId" :text="$clienteNome"
    placeholder="Buscar cliente..." per-page="10">
    <mad-column field="id"   label="Cod." width="70" sort />
    <mad-column field="nome" label="Nome" sort filter />
</mad-seek>

value = ID e text = display sao usados juntos para mostrar a selecao inicial sem precisar consultar o banco no modal.

Filtrando registros do grid (API fluent)

A tag declarativa <mad-seek> sempre lista todos os registros do model — ela nao aceita prop de filtro. Quando precisar restringir o grid (ex: so vendedores de um grupo), monte o componente via API fluent MadSeek::of() passando um Eloquent Query Builder em ->query():

{!! MadSeek::of('Pessoa')
    ->name('vendedor_id')
    ->label('Vendedor')
    ->display('nome')
    ->value($vendedorId ?? '')
    ->text($vendedorNome ?? '')
    ->query(
        Pessoa::query()->whereIn('id', function ($q) {
            $q->select('pessoa_id')->from('pessoa_grupo')
              ->where('grupo_pessoa_id', '=', GrupoPessoa::VENDEDOR);
        })
    )
    ->column('id',   'Cod.')->w(70)->sort()
    ->column('nome', 'Nome')->sort()->filter()
    ->placeholder('Buscar vendedor...')
    ->required()
    ->perPage(10)
!!}

->query() compila o builder para SQL parametrizado (bindings reais, nunca concatenacao de string) e o grid lista a partir dessa derived table — filtros, ordenacao e paginacao do grid continuam funcionando por cima.

Com campos auxiliares — preencher outros inputs ao selecionar

Use <mad-fill target="..." source="..." /> filho para preencher campos da tela com base no registro selecionado.

<mad-seek model="Pessoa" name="cliente_id" label="Cliente" display="nome">
    <mad-column field="id"   label="Cod." width="70" sort />
    <mad-column field="nome" label="Nome" sort filter />
    <mad-column field="email" label="Email" filter />

    <mad-fill target="cliente_email" source="email" />
    <mad-fill target="cliente_cidade" source="cidade->nome" />
</mad-seek>

<mad-input-field name="cliente_email" label="Email" />
<mad-input-field name="cliente_cidade" label="Cidade" />

source aceita notacao ponto/seta para navegar relacionamentos (cidade->estado->nome).

Com handler customizado e acoes no grid

<mad-seek model="Pessoa" name="cliente_id" label="Cliente" display="nome"
    handler="ClienteHandler" per-page="15">
    <mad-column field="id"   label="Cod." width="70" sort />
    <mad-column field="nome" label="Nome" sort filter />
    <mad-action method="onCadastrar" icon="plus" label="Novo" />
</mad-seek>

O handler aponta para uma classe que recebe as chamadas mad:click das acoes do grid (mesmo padrao do MadDataGrid).

Tamanho e titulo do modal

<mad-seek model="Produto" name="produto_id" label="Produto" display="nome"
    modal-title="Selecionar produto" modal-size="lg" per-page="20">
    <mad-column field="id" label="Cod." width="70" sort />
    <mad-column field="nome" label="Nome" sort filter />
    <mad-column field="valor" label="Preco" right />
</mad-seek>

API fluent PHP — MadSeek::of()

Quando precisar montar dinamicamente em PHP (raro — prefira a tag declarativa):

{!! MadSeek::of('Pessoa')
    ->name('cliente_id')
    ->label('Cliente')
    ->display('nome')
    ->value($clienteId ?? '')
    ->text($clienteNome ?? '')
    ->auxiliary('cliente_email', 'email')
    ->auxiliary('cliente_cidade', 'cidade->nome')
    ->column('id',   'Cod.')->w(60)->sort()
    ->column('nome', 'Nome')->sort()->filter()
    ->column('email','Email')->filter()
    ->perPage(10)
    ->required()
!!}

Builder methods principais:

Metodo Descricao
of($model) Inicia o builder
name($n) / label($l) / display($d) Props basicas
value($v) / text($t) Valor pre-selecionado
required() / disabled() Estado
placeholder($p) / hint($h) Textos auxiliares
modalTitle($t) / modalSize($s) Modal
perPage($n) / database($db) / handler($c) Grid
auxiliary($target, $source) Campo auxiliar
column($field, $label) Inicia uma coluna (encadeia ->w()->sort()->filter()->money()->date()->badge()->...)
action($method, $icon, $label) Acao no grid (->primary()->danger()->confirm($msg)->idField($f))

Submit do formulario

O <mad-seek> registra-se no MadForm como tipo seek. O valor enviado e o ID do registro selecionado (no name), igual a um <mad-dbcombo-field>. Use normalmente em $this->form->getData():

<mad-form submit="onSave">
    <mad-seek model="Pessoa" name="cliente_id" label="Cliente" display="nome" required>
        <mad-column field="id" label="Cod." width="70" sort />
        <mad-column field="nome" label="Nome" sort filter />
    </mad-seek>
    <mad-btn type="submit" variant="primary" icon="save">Salvar</mad-btn>
</mad-form>
public function onSave(): MadResponse
{
    $data = $this->form->getData();
    // $data->cliente_id contem o ID selecionado
    // ...
}

Gotchas

  • model precisa ser uma classe resolvivel. Ao clicar em "Selecionar" no modal, o MadSeekGrid::onSelect() testa class_exists($model); se falhar, a tela mostra o toast Model não configurado. e o campo continua vazio — sem erro no log. Use o nome que o ModelRegistry resolve (o mesmo do <mad-dbcombo-field model="...">) ou o FQCN completo.
  • handler sem o metodo publico = exception. Acoes customizadas (<mad-action method="onCadastrar">) sao delegadas por __call() ao handler. Se a classe nao existir ou nao tiver o metodo publico com o mesmo nome, o grid lanca BadMethodCallException ("Configure ->handler('MinhaClasse') com o método ... público").
  • <mad-seek-field> nao e o mesmo componente. Ele so dispara o evento JS mad:seek ({ name, onSeek, el }) — sem modal e sem grid. Ver a tabela de formas de uso no topo.

Quando usar seek vs dbcombo

Cenario Usar
Lista pequena (< 100 registros) <mad-dbcombo-field>
Lista grande precisando busca/filtros multiplos/paginacao <mad-seek>
Precisa exibir multiplas colunas para o usuario decidir <mad-seek>
Apenas 1 campo de display (nome) <mad-dbcombo-field>
Precisa preencher campos auxiliares ao selecionar <mad-seek> com <mad-fill>

NUNCA fazer

{{-- ERRADO: usar dbcombo para listas grandes — carrega tudo no DOM --}}
<mad-dbcombo-field name="cliente_id" label="Cliente" model="Pessoa" display="nome" />

{{-- CERTO: seek pagina e busca server-side --}}
<mad-seek model="Pessoa" name="cliente_id" label="Cliente" display="nome">
    <mad-column field="id" label="Cod." width="70" sort />
    <mad-column field="nome" label="Nome" sort filter />
</mad-seek>

{{-- ERRADO: tentar filtrar a tag declarativa com :criteria/:filters/:query --}}
<mad-seek model="Pessoa" name="vendedor_id" :criteria="$crit" ... />
{{-- a tag <mad-seek> nao tem prop de filtro — isso e silenciosamente ignorado --}}

{{-- CERTO: usar a API fluent quando precisar filtrar --}}
{!! MadSeek::of('Pessoa')->name('vendedor_id')->query($builder)->... !!}

{{-- ERRADO: concatenar valor do usuario direto no subselect --}}
@php
    $builder = Pessoa::query()->whereIn('id', function ($q) use ($gid) {
        $q->selectRaw("pessoa_id")->fromRaw("pessoa_grupo")
          ->whereRaw("grupo_pessoa_id = '{$gid}'"); // concatenacao = SQL injection
    });
@endphp

{{-- CERTO: bindings parametrizados via where()/whereIn() do Eloquent --}}
@php
    $builder = Pessoa::query()->whereIn('id', function ($q) use ($gid) {
        $q->select('pessoa_id')->from('pessoa_grupo')
          ->where('grupo_pessoa_id', '=', $gid);
    });
@endphp

{{-- ERRADO: preencher campo auxiliar via JS manual --}}
<mad-seek ... attrs='onchange="document.querySelector(...).value = ..."' />

{{-- CERTO: usar <mad-fill> --}}
<mad-seek ...>
    <mad-fill target="email_input" source="email" />
</mad-seek>

{{-- ERRADO: omitir display — input fica vazio apos selecao --}}
<mad-seek model="Pessoa" name="cliente_id" label="Cliente">
    <mad-column field="nome" label="Nome" />
</mad-seek>

{{-- CERTO: display obrigatorio --}}
<mad-seek model="Pessoa" name="cliente_id" label="Cliente" display="nome">
    <mad-column field="nome" label="Nome" />
</mad-seek>