mad-cnpj-field
Campo de CNPJ com busca automática e auto-fill.
Campo de CNPJ com integracao nativa a API do madbuilder. Ao digitar um CNPJ valido (ou clicar no botao de lupa) o componente consulta a API, recebe os dados da empresa (razao social, telefone, endereco completo) e preenche automaticamente os campos do form via o atributo fill-fields. Zero codigo PHP no controller.
Por tras dos panos o JS chama o endpoint AJAX Mad\Service\MadCnpjService::onSearch() (framework), que consulta BuilderCNPJService::get()/getFull() (app/Service/Builder/BuilderCNPJService.php — proxy pra API do madbuilder). Em modo basico, se o app definir um CNPJService::get() proprio (ex: app/Service/CNPJService.php), ele e usado no lugar — convencao util pra resolver cidade_id/estado_id chamando um CEPService::get() interno com cache/auto-criacao de Cidade/Estado. Sem esse CNPJService no app, o campo degrada com graca: preenche so os dados crus do CNPJ (sem cidade_id/estado_id). Em modo :full="true", o enriquecimento de CEP e feito direto pelo framework (sem depender do CNPJService do app).
Props
| Prop | Tipo | Default | Descricao |
|---|---|---|---|
| name | string | '' | Nome do campo (obrigatorio) |
| label | string | '' | Label |
| value | string | '' | Valor inicial (sobrescrito pelo MadRenderContext quando o form esta populado) |
| fill-fields | array | [] |
Mapa 'form_field' => 'api_field' — ver secao abaixo |
| auto | bool | true |
Dispara busca automaticamente no blur quando o CNPJ tem 14 digitos. Desligar com :auto="false" |
| full | bool | false |
Usa BuilderCNPJService::getFull() (endpoint /full/) ao inves do basico — retorna mais campos mas e mais lento |
| width / max-width | string | '' | Largura / largura maxima do campo (CSS: px, %, calc()) |
| placeholder | string | '00.000.000/0000-00' |
|
| hint | string | '' | Texto de ajuda |
| error | string | '' | Mensagem de erro |
| required | bool | false | |
| disabled | bool | false | |
| strip-mask | bool | false | Remove a mascara no getData() — backend recebe so os 14 digitos |
| attrs | string | '' | Atributos HTML extras |
| id | string | $name |
ID do input |
Resolucao automatica de cidade/estado (opt-in)
Alem do fill-fields (que preenche textos crus), o campo resolve cidade_id /
estado_id no seu banco a partir do codigo IBGE que a API devolve. E o
MESMO contrato do <mad-cep-field> — mesmos nomes de prop, mesmos defaults e o
mesmo fallback de projeto (MAD_CEP_AUTO_CREATE).
A resolucao so liga quando voce declara city-model e/ou state-model.
| Prop | Tipo | Default | Descricao |
|---|---|---|---|
| city-model | string | '' | Model Eloquent da cidade — ativa a resolucao de cidade |
| state-model | string | '' | Model Eloquent do estado — ativa a resolucao de estado |
| city-match-column | string | 'codigo_ibge' |
Coluna do model de cidade comparada com o valor da API |
| state-match-column | string | 'codigo_ibge' |
Idem para o estado |
| city-api-field | string | 'cidade_cod_ibge' |
Campo da resposta da API usado no match da cidade |
| state-api-field | string | 'estado_cod_ibge' |
Idem para o estado |
| city-key | string | 'id' |
PK do model de cidade (valor gravado no form) |
| state-key | string | 'id' |
PK do model de estado |
| city-target | string | 'cidade_id' |
Campo do FORM que recebe o ID resolvido da cidade |
| state-target | string | 'estado_id' |
Campo do form que recebe o ID do estado |
| city-state-fk | string | '' | Coluna FK do estado no model de cidade |
| city-scope-by-state | bool | false | Restringe o lookup da cidade ao estado ja resolvido (exige city-state-fk) |
| database | string | '' | Override da conexao usada nos models de cidade/estado |
| city-create | array|bool | false | Auto-cria a cidade quando nao existir. true usa o mapa ['nome' => 'cidade']; array = mapa coluna_do_model => campo_da_api |
| state-create | array|bool | false | Idem para o estado |
<mad-cnpj-field name="documento" label="CNPJ"
city-model="Cidade" state-model="Estado"
city-state-fk="estado_id" city-scope-by-state
:city-create="true" :state-create="true"
:fill-fields="[
'razao_social' => 'razao_social',
'endereco' => 'logradouro',
'bairro' => 'bairro',
'cep' => 'cep',
]" />
A config de resolucao viaja cifrada num token gerado no render — o cliente nao escolhe model, coluna nem conexao.
Mapeamento fill-fields
Sintaxe: 'nome_do_input_no_form' => 'nome_do_campo_na_resposta_da_api'.
Campos disponiveis na resposta basica (:full="false", default):
| Campo API | Descricao |
|---|---|
razao_social |
Nome oficial da empresa |
nome_fantasia |
Nome comercial |
cnpj |
CNPJ (ver formato retornado pela API) |
ddd_telefone_1 |
Telefone principal (com DDD) |
ddd_telefone_2 |
Telefone secundario |
logradouro |
Nome da rua |
numero |
Numero do endereco |
complemento |
Complemento |
bairro |
|
cidade |
Nome da cidade (texto) |
cep |
CEP |
cidade_id |
ID da cidade no banco — resolvido via CEPService interno quando o CNPJ retorna CEP |
estado_id |
ID do estado no banco — idem |
Com :full="true", o endpoint /full/ retorna campos adicionais (situacao cadastral, capital social, atividades secundarias, quadro societario, etc). Consultar a resposta real da API para nomes exatos.
Uso basico
<mad-cnpj-field name="documento" label="CNPJ" :fill-fields="[
'razao_social' => 'razao_social',
'nome_fantasia' => 'nome_fantasia',
'fone' => 'ddd_telefone_1',
'endereco' => 'logradouro',
'numero' => 'numero',
'complemento' => 'complemento',
'bairro' => 'bairro',
'cep' => 'cep',
'estado_id' => 'estado_id',
'cidade_id' => 'cidade_id',
]" />
<mad-input-field name="razao_social" label="Razao Social" />
<mad-input-field name="fone" label="Telefone" />
<mad-input-field name="endereco" label="Endereco" />
<mad-input-field name="cep" label="CEP" />
<mad-dbcombo-field name="estado_id" label="Estado" model="Estado" display="nome" />
<mad-dbcombo-field name="cidade_id" label="Cidade" model="Cidade" display="nome"
depends-on="estado_id" />
Ao digitar o CNPJ e sair do campo (ou clicar na lupa), o componente preenche TODOS os campos acima de uma vez, incluindo os combos com depends-on (ordem de preenchimento ja e tratada pelo JS — ver regra cep-field-rules.md para detalhes).
Dentro de formulario completo
<mad-form submit="onSave">
<mad-form-section title="Dados da empresa" icon="building-2">
<mad-form-grid :cols="2">
<mad-cnpj-field name="cnpj" label="CNPJ" required :fill-fields="[
'razao_social' => 'razao_social',
'fone' => 'ddd_telefone_1',
'logradouro' => 'logradouro',
'numero' => 'numero',
'bairro' => 'bairro',
'cep' => 'cep',
'estado_id' => 'estado_id',
'cidade_id' => 'cidade_id',
]" />
<mad-input-field name="razao_social" label="Razao Social" required />
</mad-form-grid>
<mad-form-grid :cols="2">
<mad-input-field name="fone" label="Telefone" />
<mad-input-field name="email" label="E-mail" type="email" />
</mad-form-grid>
</mad-form-section>
<mad-form-section title="Endereco" icon="map-pin">
<mad-form-grid :cols="3">
<mad-input-field name="cep" label="CEP" />
<mad-input-field name="logradouro" label="Logradouro" />
<mad-input-field name="numero" label="Numero" />
</mad-form-grid>
<mad-form-grid :cols="3">
<mad-input-field name="bairro" label="Bairro" />
<mad-dbcombo-field name="estado_id" label="Estado"
model="Estado" display="nome" />
<mad-dbcombo-field name="cidade_id" label="Cidade"
model="Cidade" display="nome" depends-on="estado_id" />
</mad-form-grid>
</mad-form-section>
<mad-form-actions>
<mad-btn type="submit" variant="primary" icon="save">Salvar</mad-btn>
</mad-form-actions>
</mad-form>
Modo /full/ — mais campos
<mad-cnpj-field name="cnpj" label="CNPJ" :full="true" :fill-fields="[
'razao_social' => 'razao_social',
'situacao' => 'situacao_cadastral',
'atividade' => 'cnae_fiscal_descricao',
'capital_social' => 'capital_social',
'data_abertura' => 'data_inicio_atividade',
]" />
Use :full="true" apenas quando precisar de campos alem do basico — o endpoint /full/ e mais lento.
Desligando o auto-blur (so manual)
<mad-cnpj-field name="cnpj" label="CNPJ"
:auto="false"
:fill-fields="['razao_social' => 'razao_social']" />
A busca so acontece ao clicar no botao de lupa — util quando o usuario pode querer digitar o CNPJ sem disparar a consulta.
Sem fill-fields
Se voce nao passar fill-fields, o campo ainda funciona com mascara e validacao de 14 digitos, mas nenhum campo do form e preenchido automaticamente. Util quando voce so quer guardar o CNPJ digitado.
Comportamento do blur
Idem mad-cep-field: dispara quando o usuario sai do campo e o valor limpo tem exatamente 14 digitos. Falha = toast warning + campos nao alterados. Durante o fetch o botao mostra spinner.
Valor enviado no form
Por padrao o mad:model coleta o valor com mascara (12.345.678/0001-90).
Para o backend receber so os 14 digitos, use :strip-mask="true" em vez de
normalizar manualmente no setter:
<mad-cnpj-field name="cnpj" label="CNPJ" :strip-mask="true" :fill-fields="[...]" />
NUNCA fazer
{{-- ERRADO: input manual + botao "Buscar CNPJ" + metodo onBuscarCnpj --}}
<mad-input-field name="cnpj" label="CNPJ" />
<mad-btn mad:click="onBuscarCnpj">Buscar</mad-btn>
public function onBuscarCnpj(): MadResponse {
$dados = CNPJService::get($this->form->getData()->cnpj);
// ... 30 linhas de fillRecord ...
}
{{-- CERTO --}}
<mad-cnpj-field name="cnpj" label="CNPJ" :fill-fields="[
'razao_social' => 'razao_social',
'endereco' => 'logradouro',
// ...
]" />
{{-- ERRADO: chamar BuilderCNPJService direto do Blade --}}
@php $dados = BuilderCNPJService::get($cnpj); @endphp
{{-- CERTO: deixar o componente cuidar de tudo --}}
<mad-cnpj-field name="cnpj" :fill-fields="[...]" />
{{-- ERRADO: passar :full="true" por padrao --}}
<mad-cnpj-field name="cnpj" :full="true" :fill-fields="['razao_social' => 'razao_social']" />
{{-- CERTO: so usar full quando precisa dos campos extras --}}
<mad-cnpj-field name="cnpj" :fill-fields="['razao_social' => 'razao_social']" />
{{-- ERRADO: direcao invertida do mapa --}}
:fill-fields="['razao_social' => 'nome']"
{{-- Isso tenta preencher 'nome' na API (que nao existe), nao o contrario --}}
{{-- CERTO: chave = input do form, valor = campo retornado pela API --}}
:fill-fields="['nome' => 'razao_social']"