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:modelautomatico: o blade sempre emitemad:model="<name>"no input — nao precisa declarar.- Valor inicial: quando
attrsnao trazmad:model/data-mad-model, o valor vem doMadRenderContext($form->fill($record)) e so cai na propvaluese a chave nao existir no contexto. mad:change/mad:scan: sao extraidos doattrspelo blade e viram o atributodata-mad-scan-actionno 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.escapeno 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" />