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

mad-scanner-field

Leitor de barcode/QR via câmera.

Campo de formulario que le codigos de barras e QR codes via camera, num unico input. Usa html5-qrcode.

Dependencia JS — self-hosted, nao CDN

O leitor e o html5-qrcode, que nao vem de CDN: desde 2026-06-14 ele e servido pelo proprio app dentro do bundle independent-plugins.min.js (manifesto em public/lib/independent/independent-plugins.txt, arquivo lib/independent/js/html5-qrcode.min.js). Ou seja: funciona offline / intranet, sem unpkg, e nao ha <script src="https://..."> para adicionar no layout.

Se o bundle nao estiver carregado na pagina, o componente Alpine madScanner (assets/builder-ui/mad-ui.js) detecta typeof Html5Qrcode === 'undefined', loga html5-qrcode not loaded no console e nao abre a camera — o input de texto continua funcionando para digitacao manual.

Props

Prop Tipo Default Descricao
name string '' Nome do campo (obrigatorio)
label string '' Label do campo
value string '' Valor pre-preenchido
type string 'both' barcode, qr, both
placeholder string 'Escaneie ou digite...' Placeholder
width string '' Largura CSS do wrapper
max-width string '' max-width CSS do wrapper
hint string '' Texto de ajuda
error string '' Mensagem de erro
required bool false Campo obrigatorio
disabled bool false Campo desabilitado
continuous bool false Modo inventario (nao fecha camera)
beep bool true Som ao detectar codigo
attrs string '' Atributos HTML extras

Eventos

Evento Descricao
mad:change="method" Metodo PHP chamado ao escanear
mad:scan="method" Alias de mad:change

Uso basico

{{-- Le barcode + QR --}}
<mad-scanner-field name="cod_barras" label="Codigo de barras" />

{{-- Apenas QR --}}
<mad-scanner-field name="qr_code" label="QR Code" type="qr" />

{{-- Apenas barcode --}}
<mad-scanner-field name="ean" label="EAN" type="barcode" />

Com evento no servidor

<mad-scanner-field name="cod" label="Scanner"
    mad:change="onCodeScanned" />
public function onCodeScanned(string $value): MadResponse
{
    $produto = Produto::where('cod_barras', '=', $value)->first();

    if ($produto) {
        $this->form->set('produto_id', $produto->id);
        $this->form->set('nome', $produto->nome);
        return MadToast::success("Produto: {$produto->nome}");
    }
    return MadToast::warning("Produto nao encontrado: {$value}");
}

Modo continuo (inventario)

<mad-scanner-field name="scanner" label="Inventario"
    continuous mad:scan="onItemScanned" />

Camera nao fecha apos leitura. Lista dos ultimos codigos aparece abaixo do viewfinder.

Dentro de formulario

<mad-form submit="onSave">
    <mad-form-grid :cols="2">
        <mad-scanner-field name="ean" label="EAN" required />
        <mad-input-field name="qtd" label="Quantidade" type="number" />
    </mad-form-grid>
    <mad-btn type="submit" variant="primary" icon="save">Salvar</mad-btn>
</mad-form>

Tipos de codigo suportados

Tipo Formatos
barcode EAN-13, EAN-8, Code 128, Code 39, UPC-A, UPC-E, ITF, Codabar
qr QR Code
both Todos acima

Comportamento

  • mad:model automatico: o blade sempre emite mad:model="<name>" no input — nao precisa declarar.
  • Valor inicial: quando attrs nao traz mad:model/data-mad-model, o valor vem do MadRenderContext ($form->fill($record)) e so cai na prop value se a chave nao existir no contexto.
  • mad:change / mad:scan: sao extraidos do attrs pelo blade e viram o atributo data-mad-scan-action no wrapper — por isso nao aparecem como atributo no <input> final.
  • Toggle de tipo no viewfinder (Todos / QR / Barcode): so aparece com type="both".
  • Lista de leituras abaixo do viewfinder: so aparece com continuous.
  • Esc fecha o scanner (keydown.escape no wrapper).

Camera e HTTPS

A API de camera do navegador requer HTTPS (ou localhost). Em HTTP, o scanner mostra toast de aviso e o usuario pode digitar o codigo manualmente.

NUNCA fazer

{{-- ERRADO: montar leitor de camera manualmente com html5-qrcode --}}
<div id="reader"></div>
<script>new Html5Qrcode('reader').start(...);</script>

{{-- CERTO --}}
<mad-scanner-field name="cod" label="Codigo" />

{{-- ERRADO: dois campos separados para barcode e QR --}}
<mad-scanner-field name="bar" type="barcode" />
<mad-scanner-field name="qr" type="qr" />

{{-- CERTO: um campo unificado que le ambos --}}
<mad-scanner-field name="cod" type="both" />