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

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']"