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 (semcriteria/filters/query) — ela sempre lista todos os registros domodel. Para filtrar o grid, use a API fluentMadSeek::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
modelprecisa ser uma classe resolvivel. Ao clicar em "Selecionar" no modal, oMadSeekGrid::onSelect()testaclass_exists($model); se falhar, a tela mostra o toastModel não configurado.e o campo continua vazio — sem erro no log. Use o nome que oModelRegistryresolve (o mesmo do<mad-dbcombo-field model="...">) ou o FQCN completo.handlersem o metodo publico = exception. Acoes customizadas (<mad-action method="onCadastrar">) sao delegadas por__call()aohandler. Se a classe nao existir ou nao tiver o metodo publico com o mesmo nome, o grid lancaBadMethodCallException("Configure->handler('MinhaClasse')com o método ... público").<mad-seek-field>nao e o mesmo componente. Ele so dispara o evento JSmad: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>