F
Filament4w ago
Anik

script in modalContent(view('qr-scanner.php')) not working

Hello I am trying to integrate this package into filament action modal https://github.com/mebjas/html5-qrcode
Actions\Action::make('openModal')
->modalContent(view('filament-custom.qr-scanner'))
->mountUsing(function () {
// Dispatch the custom event to initialize the QR scanner
$this->dispatch('initialize-qr-scanner');
})
->action(function (array $data): void {
// Handle the action when the modal is submitted
// For example, you can process the $data here
}),
Actions\Action::make('openModal')
->modalContent(view('filament-custom.qr-scanner'))
->mountUsing(function () {
// Dispatch the custom event to initialize the QR scanner
$this->dispatch('initialize-qr-scanner');
})
->action(function (array $data): void {
// Handle the action when the modal is submitted
// For example, you can process the $data here
}),
<div class="border border-primary-500 w-[300px] h-[300px] mx-auto">
<div id="reader"></div>
</div>

<script src="https://unpkg.com/html5-qrcode"></script>
<script>
console.log('asbc')
function onScanSuccess(decodedText, decodedResult) {
// handle the scanned code as you like, for example:
console.log(`Code matched = ${decodedText}`, decodedResult);
document.getElementById("outputData").innerText = decodedText;
}

function onScanFailure(error) {
// handle scan failure, usually better to ignore and keep scanning.
// for example:
console.warn(`Code scan error = ${error}`);
}

document.addEventListener("DOMContentLoaded", function() {
const { Html5QrcodeScanner } = window;
let html5QrcodeScanner = new Html5QrcodeScanner(
"reader",
{ fps: 10, qrbox: {width: 250, height: 250} },
/* verbose= */ false);
html5QrcodeScanner.render(onScanSuccess, onScanFailure);
});

document.addEventListener('initialize-qr-scanner', function() {
const { Html5QrcodeScanner } = window;
let html5QrcodeScanner = new Html5QrcodeScanner(
"reader",
{ fps: 10, qrbox: {width: 250, height: 250} },
/* verbose= */ false);
html5QrcodeScanner.render(onScanSuccess, onScanFailure);
});
</script>
<div class="border border-primary-500 w-[300px] h-[300px] mx-auto">
<div id="reader"></div>
</div>

<script src="https://unpkg.com/html5-qrcode"></script>
<script>
console.log('asbc')
function onScanSuccess(decodedText, decodedResult) {
// handle the scanned code as you like, for example:
console.log(`Code matched = ${decodedText}`, decodedResult);
document.getElementById("outputData").innerText = decodedText;
}

function onScanFailure(error) {
// handle scan failure, usually better to ignore and keep scanning.
// for example:
console.warn(`Code scan error = ${error}`);
}

document.addEventListener("DOMContentLoaded", function() {
const { Html5QrcodeScanner } = window;
let html5QrcodeScanner = new Html5QrcodeScanner(
"reader",
{ fps: 10, qrbox: {width: 250, height: 250} },
/* verbose= */ false);
html5QrcodeScanner.render(onScanSuccess, onScanFailure);
});

document.addEventListener('initialize-qr-scanner', function() {
const { Html5QrcodeScanner } = window;
let html5QrcodeScanner = new Html5QrcodeScanner(
"reader",
{ fps: 10, qrbox: {width: 250, height: 250} },
/* verbose= */ false);
html5QrcodeScanner.render(onScanSuccess, onScanFailure);
});
</script>
the console log in the script works only when called from a web.php route. the script doesnt execute when implemented through modalContent(view()). how can i solve this? any ideas would also be helpful. Thank you.
GitHub
GitHub - mebjas/html5-qrcode: A cross platform HTML5 QR code reader...
A cross platform HTML5 QR code reader. See end to end implementation at: https://scanapp.org - mebjas/html5-qrcode
Solution:
add to the appserviceprovider ```php public function boot(): void {...
Jump to solution
16 Replies
Anik
Anik4w ago
bump
Dennis Koch
Dennis Koch4w ago
In a form this is probably the issue, as the DOM is already loaded: document.addEventListener("DOMContentLoaded", function() {
LeandroFerreira
you could also use alpine
<div x-data="{

onScanSuccess(decodedText, decodedResult) {
//...
},
onScanFailure(error) {
//...
},

init() {
let html5QrcodeScanner = new Html5QrcodeScanner('reader', { fps: 10, qrbox: {width: 250, height: 250} });
html5QrcodeScanner.render(this.onScanSuccess, this.onScanFailure);
}
}">
<div class="border border-primary-500 w-[300px] h-[300px] mx-auto">
<div id="reader"></div>
</div>
</div>
<div x-data="{

onScanSuccess(decodedText, decodedResult) {
//...
},
onScanFailure(error) {
//...
},

init() {
let html5QrcodeScanner = new Html5QrcodeScanner('reader', { fps: 10, qrbox: {width: 250, height: 250} });
html5QrcodeScanner.render(this.onScanSuccess, this.onScanFailure);
}
}">
<div class="border border-primary-500 w-[300px] h-[300px] mx-auto">
<div id="reader"></div>
</div>
</div>
Anik
Anik4w ago
thanks for the reply. I have tried it this way. The script runs but I have not been able to get the html5Qrcodescanner object. Heres my code
<div x-data="{
onScanSuccess(decodedText, decodedResult) {
console.log(`Code matched = ${decodedText}`, decodedResult);
},
onScanFailure(error) {
console.warn(`Code scan error = ${error}`);
},

init() {
// undefined
const { Html5QrcodeScanner } = window;
console.log(Html5QrcodeScanner)
let html5QrcodeScanner = new Html5QrcodeScanner('reader', { fps: 10, qrbox: {width: 250, height: 250} });
html5QrcodeScanner.render(this.onScanSuccess, this.onScanFailure);
}
}">
<div class="border border-primary-500 w-[300px] h-[300px] mx-auto">
<div id="reader"></div>
</div>
</div>
<div x-data="{
onScanSuccess(decodedText, decodedResult) {
console.log(`Code matched = ${decodedText}`, decodedResult);
},
onScanFailure(error) {
console.warn(`Code scan error = ${error}`);
},

init() {
// undefined
const { Html5QrcodeScanner } = window;
console.log(Html5QrcodeScanner)
let html5QrcodeScanner = new Html5QrcodeScanner('reader', { fps: 10, qrbox: {width: 250, height: 250} });
html5QrcodeScanner.render(this.onScanSuccess, this.onScanFailure);
}
}">
<div class="border border-primary-500 w-[300px] h-[300px] mx-auto">
<div id="reader"></div>
</div>
</div>
import Alpine from "alpinejs";
import AlpineFloatingUI from "@awcodes/alpine-floating-ui";
import { Html5QrcodeScanner, Html5Qrcode } from "html5-qrcode"; // Import Html5Qrcode and Html5QrcodeScanner

Alpine.plugin(AlpineFloatingUI);

window.Alpine = Alpine;
window.Html5QrcodeScanner = Html5QrcodeScanner; // Make Html5QrcodeScanner available globally
window.Html5Qrcode = Html5Qrcode; // Make Html5Qrcode available globally'

Alpine.start();
import Alpine from "alpinejs";
import AlpineFloatingUI from "@awcodes/alpine-floating-ui";
import { Html5QrcodeScanner, Html5Qrcode } from "html5-qrcode"; // Import Html5Qrcode and Html5QrcodeScanner

Alpine.plugin(AlpineFloatingUI);

window.Alpine = Alpine;
window.Html5QrcodeScanner = Html5QrcodeScanner; // Make Html5QrcodeScanner available globally
window.Html5Qrcode = Html5Qrcode; // Make Html5Qrcode available globally'

Alpine.start();
I have been trying to figure out how to get Html5Qrcode objects inside init function The script tag doesnt seem to run when used from Action modalContent. I have tried using a different event but the script simply doesnt execute
->mountUsing(function () {
// Dispatch the custom event to initialize the QR scanner
$this->dispatch('initialize-qr-scanner');
})
->mountUsing(function () {
// Dispatch the custom event to initialize the QR scanner
$this->dispatch('initialize-qr-scanner');
})
document.addEventListener('initialize-qr-scanner', function() {
const { Html5QrcodeScanner } = window;
let html5QrcodeScanner = new Html5QrcodeScanner(
"reader",
{ fps: 10, qrbox: {width: 250, height: 250} },
/* verbose= */ false);
html5QrcodeScanner.render(onScanSuccess, onScanFailure);
});
document.addEventListener('initialize-qr-scanner', function() {
const { Html5QrcodeScanner } = window;
let html5QrcodeScanner = new Html5QrcodeScanner(
"reader",
{ fps: 10, qrbox: {width: 250, height: 250} },
/* verbose= */ false);
html5QrcodeScanner.render(onScanSuccess, onScanFailure);
});
However the same code works pretty well when routed directly from web.php. the script works fine and the components are loaded
LeandroFerreira
I don't know why you need to dispatch an event if you can use the x-init in the modal content..
Anik
Anik4w ago
just trying different approaches to figure out which one works
LeandroFerreira
did you try my code?
Anik
Anik4w ago
@Leandro Ferreira of course this is the version
LeandroFerreira
could you share the modal content? sorry I didn't notice that.. Did you register the js as I mentioned?
LeandroFerreira
remove imports and use this 👆
Anik
Anik4w ago
<div x-data="{
onScanSuccess(decodedText, decodedResult) {
console.log(`Code matched = ${decodedText}`, decodedResult);
},
onScanFailure(error) {
console.warn(`Code scan error = ${error}`);
},

init() {
const { Html5QrcodeScanner } = window;
console.log(Html5QrcodeScanner)
let html5QrcodeScanner = new Html5QrcodeScanner('reader', { fps: 10, qrbox: {width: 250, height: 250} });
html5QrcodeScanner.render(this.onScanSuccess, this.onScanFailure);
}
}">
<div class="border border-primary-500 w-[300px] h-[300px] mx-auto">
<div id="reader"></div>
</div>
</div>
<div x-data="{
onScanSuccess(decodedText, decodedResult) {
console.log(`Code matched = ${decodedText}`, decodedResult);
},
onScanFailure(error) {
console.warn(`Code scan error = ${error}`);
},

init() {
const { Html5QrcodeScanner } = window;
console.log(Html5QrcodeScanner)
let html5QrcodeScanner = new Html5QrcodeScanner('reader', { fps: 10, qrbox: {width: 250, height: 250} });
html5QrcodeScanner.render(this.onScanSuccess, this.onScanFailure);
}
}">
<div class="border border-primary-500 w-[300px] h-[300px] mx-auto">
<div id="reader"></div>
</div>
</div>
https://filamentphp.com/docs/3.x/support/assets/#registering-javascript-files-from-a-url I will try this.
Solution
LeandroFerreira
add to the appserviceprovider
public function boot(): void
{
FilamentAsset::register([
Js::make('html5-code-script', 'https://unpkg.com/html5-qrcode')
]);
}
public function boot(): void
{
FilamentAsset::register([
Js::make('html5-code-script', 'https://unpkg.com/html5-qrcode')
]);
}
Anik
Anik4w ago
this one did the job. Sorry I missed it earlier
Anik
Anik4w ago
hello, I am trying a few more things to complete the feature. I need to programatically close the modal on success. But I am unsure of how to set/get modal id? Can you give me an idea on how to accomplish this?
<div x-data="{
onScanSuccess(decodedText, decodedResult) {
console.log(`Code matched = ${decodedText}`, decodedResult);
$wire.scanResult(decodedText)
$wire.dispatch('close-modal', { id: 'scan-qr' });
},
onScanFailure(error) {
console.warn(`Code scan error = ${error}`);
},

init() {
if (window.Html5QrcodeScanner) {
const { Html5QrcodeScanner } = window;
let html5QrcodeScanner = new Html5QrcodeScanner('reader', { fps: 10, qrbox: {width: 100, height: 100} });
html5QrcodeScanner.render(this.onScanSuccess, this.onScanFailure);
} else {
console.error('Html5QrcodeScanner is not available.');
}
}
}">
<div class="mx-auto">
<div id="reader"></div>
</div>
</div>
<div x-data="{
onScanSuccess(decodedText, decodedResult) {
console.log(`Code matched = ${decodedText}`, decodedResult);
$wire.scanResult(decodedText)
$wire.dispatch('close-modal', { id: 'scan-qr' });
},
onScanFailure(error) {
console.warn(`Code scan error = ${error}`);
},

init() {
if (window.Html5QrcodeScanner) {
const { Html5QrcodeScanner } = window;
let html5QrcodeScanner = new Html5QrcodeScanner('reader', { fps: 10, qrbox: {width: 100, height: 100} });
html5QrcodeScanner.render(this.onScanSuccess, this.onScanFailure);
} else {
console.error('Html5QrcodeScanner is not available.');
}
}
}">
<div class="mx-auto">
<div id="reader"></div>
</div>
</div>
protected function getHeaderActions(): array
{
return [
Actions\Action::make('scan-qr')->label('Scan QR')
->modalContent(view('filament-custom.qr-scanner'))
->modalSubmitAction(false),

];
}
public function scanResult($decodedText)
{
$this->dispatch('close-modal', id: 'scan-qr');
}
protected function getHeaderActions(): array
{
return [
Actions\Action::make('scan-qr')->label('Scan QR')
->modalContent(view('filament-custom.qr-scanner'))
->modalSubmitAction(false),

];
}
public function scanResult($decodedText)
{
$this->dispatch('close-modal', id: 'scan-qr');
}
got this https://discord.com/channels/883083792112300104/1273718758812422215 I have tried implementing your code but the modal doesn't yet close for some reason
<div x-data="{
modalId: null,
onScanSuccess(decodedText, decodedResult) {
console.log(`Code matched = ${decodedText}`, decodedResult);
$wire.scanResult(decodedText)
$wire.dispatch('close-modal', {id: this.modalId});
},
onScanFailure(error) {
console.warn(`Code scan error = ${error}`);
},

init() {
this.modalId = this.$refs.modalContainer.getAttribute('wire:key')
this.modalId = this.modalId.substring(0,this.modalId.indexOf('.')) + '-action'
if (window.Html5QrcodeScanner) {
const { Html5QrcodeScanner } = window;
let html5QrcodeScanner = new Html5QrcodeScanner('reader', { fps: 10, qrbox: {width: 100, height: 100} });
html5QrcodeScanner.render(this.onScanSuccess, this.onScanFailure);
} else {
console.error('Html5QrcodeScanner is not available.');
}
}
}">
<div class="mx-auto">
<div id="reader"></div>
</div>
</div>
<div x-data="{
modalId: null,
onScanSuccess(decodedText, decodedResult) {
console.log(`Code matched = ${decodedText}`, decodedResult);
$wire.scanResult(decodedText)
$wire.dispatch('close-modal', {id: this.modalId});
},
onScanFailure(error) {
console.warn(`Code scan error = ${error}`);
},

init() {
this.modalId = this.$refs.modalContainer.getAttribute('wire:key')
this.modalId = this.modalId.substring(0,this.modalId.indexOf('.')) + '-action'
if (window.Html5QrcodeScanner) {
const { Html5QrcodeScanner } = window;
let html5QrcodeScanner = new Html5QrcodeScanner('reader', { fps: 10, qrbox: {width: 100, height: 100} });
html5QrcodeScanner.render(this.onScanSuccess, this.onScanFailure);
} else {
console.error('Html5QrcodeScanner is not available.');
}
}
}">
<div class="mx-auto">
<div id="reader"></div>
</div>
</div>
the modalID is correctly extracted.
Want results from more Discord servers?
Add your server