marcelorodrigo/filament-barcode-scanner-field
Installation:
composer require marcelorodrigo/filament-barcode-scanner-field
Publish assets (optional for customization):
php artisan vendor:publish --tag=filament-barcode-scanner-field-assets
First Use Case: Add the scanner field to a Filament form:
use Marcelorodrigo\FilamentBarcodeScannerField\Forms\Components\BarcodeInput;
BarcodeInput::make('product_barcode')
->required()
->label('Scan Product Barcode')
->columnSpanFull(),
Where to Look First:
src/Forms/Components/BarcodeInput.php for method signatures and configuration options.resources/views/components/barcode-input.blade.php for UI structure.Form Integration:
Replace traditional TextInput with BarcodeInput for barcode/QR scanning:
BarcodeInput::make('scanned_code')
->live(onBlur: true) // Auto-submit on blur
->rules(['required', 'string'])
->columnSpan('full'),
Modal Handling: The scanner opens in a modal triggered by clicking the input field. Configure modal behavior:
BarcodeInput::make('qr_code')
->modalWidth('lg') // Adjust modal size
->modalMaximizeButton() // Add maximize button
->modalCloseButton(), // Add close button
Real-Time Feedback: Use events to handle scan results:
BarcodeInput::make('tracking_number')
->extraAttributes([
'x-on:scanned' => 'handleScan($event.detail)',
]),
Then add JavaScript in your form's Blade view:
<script>
function handleScan(scannedData) {
console.log('Scanned:', scannedData);
// Trigger form submission or update state
}
</script>
Validation & Processing: Chain validation rules or use Filament's built-in validation:
BarcodeInput::make('serial_number')
->rules([
'required',
'string',
function ($attribute, $value, $fail) {
if (!preg_match('/^[A-Z0-9]{12}$/', $value)) {
$fail('Invalid barcode format.');
}
},
]),
Asset Customization: Override default styles by publishing assets and extending the CSS:
/* resources/css/filament/barcode-scanner-field.css */
.fi-barcode-scanner-modal {
--fi-barcode-scanner-bg: #1a1a2e;
}
Livewire/Alpine Sync:
Use wire:model or Alpine.js to sync scanned values with Livewire components:
BarcodeInput::make('livewire_sync')
->wireModel('scannedValue'),
<x-barcode-input wire:model="scannedValue" />
Multi-Field Forms: Combine with other Filament components for complex workflows:
$form->schema([
BarcodeInput::make('primary_barcode'),
TextInput::make('manual_fallback')
->hidden(fn ($state) => $state['primary_barcode'] !== null),
]);
Conditional Logic: Show/hide the scanner based on conditions:
BarcodeInput::make('conditional_scan')
->visible(fn ($record) => $record->requires_scanning),
Camera Permissions:
BarcodeInput::make('scan_here')
->helperText('Ensure camera permissions are enabled in browser settings.'),
Mobile vs. Desktop:
modalWidth('full') for better mobile UX:
BarcodeInput::make('mobile_scan')
->modalWidth('full')
->modalMaximizeButton(),
Asset Loading:
// In ServiceProvider
FilamentAsset::register([...], 'marcelorodrigo/filament-barcode-scanner-field');
Conflict with Other Packages:
BarcodeInput::make('unique_scan')
->extraAttributes(['data-scanner-id' => 'custom-scanner-123']),
Console Logs: Enable debug mode in the scanner's JavaScript:
BarcodeInput::make('debug_scan')
->extraAttributes(['data-debug' => 'true']),
Check browser console for scan events:
EventListener fired: scanned -> { detail: '123456789012' }
Network Requests:
View Overrides:
resources/views/vendor/filament-barcode-scanner-field/.Custom Scanning Logic: Override the scanner’s JavaScript by extending the package:
// resources/js/filament/barcode-scanner.js
document.addEventListener('alpine:init', () => {
Alpine.data('customScanner', () => ({
init() {
// Extend default scanner behavior
},
}));
});
Then attach to the component:
BarcodeInput::make('custom_scan')
->extraAttributes(['x-data' => 'customScanner()']),
New Barcode Formats: Extend the scanner’s supported formats by modifying the JavaScript library (e.g., ZXing):
BarcodeInput::make('extended_scan')
->extraAttributes([
'data-formats' => 'CODE_128,PDF_417,EAN_8',
]),
Server-Side Processing: Handle scanned data in Livewire hooks:
public function handleScan(string $scannedData): void
{
$this->validateScannedData($scannedData);
$this->processBarcode($scannedData);
}
Modal Z-Index:
.fi-barcode-scanner-modal {
z-index: 9999 !important;
}
Auto-Focus:
BarcodeInput::make('auto_focus_scan')
->extraAttributes(['autofocus' => 'autofocus']),
Fallback for Unsupported Browsers:
BarcodeInput::make('fallback_scan')
->fallback(
TextInput::make('manual_entry')
->placeholder('Enter barcode manually')
),
Lazy Loading: Load the scanner’s JavaScript only when needed:
BarcodeInput::make('lazy_scan')
->extraAttributes(['x-load' => 'lazy']),
Debounce Scanning:
Reduce rapid scans by debouncing the scanned event:
// In your form's Alpine.js
<script>
let scanDebounce;
document.addEventListener('scanned', (e) => {
clearTimeout(scanDebounce);
scanDebounce = setTimeout(() => {
// Process scan
}, 300);
});
</script>
Asset Optimization: Minify custom CSS/JS before publishing:
npm run dev -- --watch
How can I help you explore Laravel packages today?