Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

UmaWorld's avatar

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

0 likes
9 replies
aleahy's avatar

When you inspect the code from the browser, is the javascript there?

UmaWorld's avatar

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;
}
aleahy's avatar

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

1 like
UmaWorld's avatar

@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

aleahy's avatar

It was a bit more complicated than I thought:

  1. Delete js/signature_pad.min.js. You imported it with npm so we don't need it. We will access it through app.js.

  2. 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.
    
  3. 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.

  4. 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.

1 like
aleahy's avatar

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
1 like
UmaWorld's avatar

@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

aleahy's avatar
aleahy
Best Answer
Level 25

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
1 like

Please or to participate in this conversation.