Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Trying to save the signature to database but failed #14

Open
abhi051002 opened this issue Feb 13, 2024 · 4 comments
Open

[Bug]: Trying to save the signature to database but failed #14

abhi051002 opened this issue Feb 13, 2024 · 4 comments
Labels
bug Something isn't working

Comments

@abhi051002
Copy link

What happened?

Is their any way to save the signature in to database

How to reproduce the bug

I'm trying every possible way i know to save the signature

Package Version

2.0.0

PHP Version

8.2.0

Laravel Version

10.0.0

Which operating systems does with happen with?

Linux

Notes

No response

@abhi051002 abhi051002 added the bug Something isn't working label Feb 13, 2024
@abhi051002 abhi051002 changed the title [Bug]: [Bug]: Trying to save the signature to database but failed Feb 13, 2024
@nourdar
Copy link

nourdar commented Jun 23, 2024

I have solved that by creating a hidden field

` SignaturePad::make('signature_pad')
                                            ->label('Signature')
                                            ->clearable()
                                            ->disabled(fn ($state) => !empty($state))
                                            ->downloadable(false)
                                            ->undoable()
                                            ->live()
                                            ->visible(fn ($get) => empty($get('signature')))
                                            ->afterStateUpdated(fn ($state, $set) => $set('signature', $state))
                                            ->confirmable(false),

                                        Hidden::make('signature'),

                                        ViewField::make('signature')
                                            ->visibleOn('edit')
                                            ->visible(fn ($state) => !empty($state))
                                            ->view('filament.forms.components.image'),

`

@saade
Copy link
Owner

saade commented Jun 23, 2024

It should just work. I'm using it.
Would you mind creating a reproduction repo?

@amrmsccs
Copy link

@nourdar please share full details the view file how it looks like and the signature column type in DB?

@uarefans
Copy link

uarefans commented Aug 31, 2024

@amrmsccs @saade @abhi051002 Maybe it helps

Concept

  1. Set Signature
  2. Convert base64PNGencode to File
  3. Save to Livewire Temporary File with afterStateUpdate and
  4. Auto Passing to Filament FileUpload Forms so you can upload to S3 or whatever you want
  5. File Upload in the background with AlpineJS help
  6. Hint Action to Delete
    a. If save to DB then delete file from storage and set back record to NULL
    b. Else delete file from livewire-tmp then you can re-assign signature

Reference

Credit to silvanhagen
Video https://www.youtube.com/watch?v=sIsxq7j_4vY
Code Snippet https://silvanhagen.com/writing/background-file-upload-in-filament-forms/

Implementation

    public function form(Form $form): Form
    {
        return $form
            ->schema([
                SignaturePad::make('signature')
                    ->label(__('Sign here'))
                    ->downloadable(false)
                    ->undoable()
                    ->live()
                    ->visible(fn($get) => empty($get('ttd')))
                    ->confirmable(true)
                    ->afterStateUpdated(function ($state, $livewire) {
                        if ($state) {
                            $base64_string = substr($state, strpos($state, ',') + 1);
                            $image_data = base64_decode($base64_string);
                            $file_name = Str::random(40);
                            $file = self::createTemporaryFileUploadFromUrl($image_data, $file_name);
                            $livewire->dispatch('test', $file);
                        }
                    })
                    ->columnSpan(4),

                Forms\Components\FileUpload::make('ttd')
                    ->label('Signature Result')
                    ->downloadable()
                    ->disabled()
                    ->dehydrated()
                    ->directory('abc')
                    ->required()
                    ->hintAction(
                        Action::make('Delete')
                            ->icon('heroicon-m-trash')
                            ->visible(fn($state) => filled($this->user['ttd']) || $state)
                            ->requiresConfirmation()
                            ->action(function ($state, $set) {
                                if (!empty($this->user['ttd'] ?? null)) {
                                    Storage::disk('public')->delete($this->user['ttd']);
                                    $this->user['ttd'] = null;
                                    $this->user->save();

                                    return redirect(request()->header('Referer'));
                                } else {
                                    $file = reset($state);
                                    if ($file instanceof \Livewire\Features\SupportFileUploads\TemporaryUploadedFile) {
                                        Storage::delete($file->getPathName());
                                        $set('ttd', null);
                                    }
                                }
                            })
                    )
                    ->extraAlpineAttributes([
                        'x-on:test.window' => '
                                    const pond = FilePond.find($el.querySelector(".filepond--root"));
                                    setTimeout(() => {
                                        pond.removeFiles({ revert: false });
                                        pond.addFile($event.detail);
                                    }, 750);',
                    ])
                    ->image()
                    ->columnSpanFull(),
            ])
            ->statePath('data');
    }

    public static function createTemporaryFileUploadFromUrl($favicon, $filename): string
    {
        // Step 1: Save the file to a temporary location
        $tempFilePath = tempnam(sys_get_temp_dir(), 'upload');
        file_put_contents($tempFilePath, $favicon);

        // Step 2: Create a UploadedFile instance
        $mimeType = mime_content_type($tempFilePath);
        $tempFile = new UploadedFile($tempFilePath, basename($filename), $mimeType);
        $path = Storage::put('livewire-tmp', $tempFile);

        // Step 3: Create a TemporaryUploadedFile instance
        $file = TemporaryUploadedFile::createFromLivewire($path);

        return URL::temporarySignedRoute(
            'livewire.preview-file',
            now()->addMinutes(30)->endOfHour(),
            ['filename' => $file->getFilename()]
        );
    }

Video Preview

File.Delete.Filament.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants