When you inspect the code from the browser, is the javascript there?
Issue with signature_pad using laravel livewire
I created form with signature_pad using laravel livewire
installed npm signature_pad
i cant able to sign usng mouse
here i attached github link https://github.com/WorldUma/user-form-with-signature
check livewire/UserForm - component user-form.blade.php welcome.blade.php
check below code import SignaturePad from 'signature_pad';
document.addEventListener('DOMContentLoaded', function () { const canvas = document.getElementById('signatureCanvas'); if (canvas) { const signaturePad = new SignaturePad(canvas);
// Listen to form submission
document.querySelector('form').addEventListener('submit', function (e) {
e.preventDefault();
const signatureData = signaturePad.toDataURL(); // Get signature data as base64 string
// Livewire.emit('saveSignature', signatureData); // Emit an event to Livewire component
//Livewire.find('counter').set('signature', signatureData);
console.log(signatureData);
Livewire.find('saveSignature', signatureData)
//Livewire.emit('saveSignature', signatureData);
//Livewire.component('counter').call('saveSignature', signatureData);
});
}
}); i can able to see in console log
below one livewire component namespace App\Livewire;
use Livewire\Component; use App\Models\User; use App\Livewire\Rule; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Facades\Log;
class Counter extends Component {
public $name;
public $email;
public $password;
public $signatureImage;
public function render()
{
return view('livewire.counter')->layout('welcome');
}
public function createNewUser(){
$validated = $this->validate([
'name' => 'required|min:2|max:10',
'email' => 'required|email|unique:users',
'password' => 'required|min:8',
'signatureImage' => 'required'
]);
Log::info('Validated data:', $validated);
$signaturePath = $this->storeSignature($this->signatureImage);
User::create([
'name' => $validated['name'],
'email' => $validated['email'],
'password' => Hash::make($validated['password']),
'signature' => $signaturePath
]);
$this->reset(['name','email','password']);
request()>session()->flash('success','User Created Successfull');
}
public function storeSignature($signature)
{
$signature = str_replace('data:image/png;base64,', '', $signature);
$signature = str_replace(' ', '+', $signature);
$signatureName = 'signatures/' . uniqid() . '.png';
Storage::disk('public')->put($signatureName, base64_decode($signature));
return $signatureName;
}
Not in the source code, but when you inspect the code while running it in the browser.
To me it doesn't look like the javascript is being loaded at all.
You need to define @stack('scripts') in the welcome.blade.php file to get it to actually be inserted in the correct place. But since you're using livewire, you should use the @script and @endscript tags instead:
https://livewire.laravel.com/docs/javascript#using-javascript-in-livewire-components
But this is not going to be enough:
You will need to either define how to access signature_pad.min.js in the vite.config.js file, or put a copy in public/js instead of the resources folder, because that is how the browser will look for it.
If you want to keep it in the resources folder, use the @vite directive to access it instead and add it to vite.config.js. (This is the better solution - the public/js solution is the quick and easy hack).
@vite('resources/js/signature_pad.min.js')
vite.config.js:
plugins: [
laravel(['resources/js/signature_pad.min.js']),
],
Another alternative is to treat it as a static asset according to the docs here: https://laravel.com/docs/11.x/vite#blade-processing-static-assets
@aleahy if you dont mind can you give me simple code using laravel livewire one simple form username signature save button
while click on save button it should save along with signature in db also totally confused that why? can you share if you dont mind
am struggling past two days
It was a bit more complicated than I thought:
-
Delete js/signature_pad.min.js. You imported it with npm so we don't need it. We will access it through app.js.
-
Add this to resources/js/app.js:
import SignaturePad from "signature_pad"; window.SignaturePad = SignaturePad; ///This will allow the livewire component's scripts to be able to access the SignaturePad code. -
Add
@vite(['resources/css/app.css', 'resources/js/app.js'])to the head of your welcome.blade.php file so it will load your app.js file. -
Change your livewire component scripts to be like so:
@script
<script>
let canvas = document.getElementById('signature-pad');
let signaturePad = new SignaturePad(canvas);
Livewire.on('clearSignature', function () {
signaturePad.clear();
});
canvas.addEventListener('DOMContentLoaded', function () {
if (signaturePad) {
window.livewire.on('saveSignature', () => {
if (!signaturePad.isEmpty()) {
@this.set('signature', signaturePad.toDataURL());
} else {
alert("Please provide a signature first.");
}
});
}
});
</script>
@endscript
Notice that I am not using @push('scripts'). The @script directive is livewire's way of inserting javascript at the right time so we don't need the DOMContentLoaded listener.
One way of getting your signature into the livewire component is using the signature pad events to send the data each time the signature endStoke event is run:
signaturePad.addEventListener('endStroke', () => {
@this.set('signature', signaturePad.toDataURL());
})
This way, when you click on save, the data is already in the component, so you can validate it there.
So ignoring the clear signature, the javascript is just:
@script
<script>
let canvas = document.getElementById('signature-pad');
let signaturePad = new SignaturePad(canvas);
signaturePad.addEventListener('endStroke', () => {
@this.set('signature', signaturePad.toDataURL())
})
</script>
@endscript
@aleahy Thanks a lot
i solved that was my mistake problem with livewire and javascript in my livewire component script should be insert the div
For clearing the signature:
UserForm.php
public function clearSignature()
{
$this->signature = null;
$this->dispatch('clear-signature-event')->self();
}
user-form.blade.php
@script
<script>
...
$wire.on('clear-signature-event', () => {
signaturePad.clear();
});
</script>
@endscript
Please or to participate in this conversation.