laravellaravel-filamentfilamentphp

How do I display the clientOriginalFileName in a TextInput before form submission in Laravel?


I have a header action in a ListRecords type page where I show a simple modal with a FileUpload and a TextInput. The idea is the user will upload a file that will be saved with a random filename when submit form. Meanwhile, the file basename will be displayed to user in a TextInput, where de user could set a display name for the file.

Actual code works but the file it shows in the TextInput is the tmp one (/tmp/php2j831s). I need the clientOriginalFileName which is available for instance in getUploadedFileNameForStorageUsing but, this method is triggered after submit de form.

I appreciate any help, thanks!

public static function getUploadFileAction($sender, CreateProjectFolderTreeService $folderService, ?Project $project = null, $actionClass = \Filament\Forms\Components\Actions\Action::class)
    {
        // \Filament\Forms\Components\Actions\Action::class
        // \Filament\Tables\Actions\Action::class

        /** @var \Filament\Forms\Components\Actions\Action $actionClass */

        return $actionClass::make('create_folder')
            ->label(__('message.project.upload_file_button'))
            ->extraAttributes(['class' => 'create_folder_button'])
            ->icon('file-plus-01')
            ->requiresConfirmation(false)
            ->closeModalByClickingAway(false)
            ->closeModalByEscaping(false)
            ->modalHeading('')
            ->modalSubmitActionLabel(__('message.project.upload_file_modal.upload_file_button'))
            ->modalContent(fn(Get $get, ?Project $record) => self::createdNewFolderModal($record ?? $project, AppUtils::getSafeValueFromGet($get, 'current_folder_name')))
            ->modalCloseButton()
            ->form([
                \Filament\Forms\Components\FileUpload::make('uploaded_file')
                    ->label(__('message.project.upload_file_modal.select_file'))
                    ->disk('private') 
                    ->directory(fn() => "projects/{$project->id}") // Directorio dinámico por proyecto
                    ->required()
                    ->acceptedFileTypes(['application/pdf', 'image/*', 'video/*', 'text/plain'])
                    ->maxSize(10240)
                    ->getUploadedFileNameForStorageUsing(function (BaseFileUpload $component, \Livewire\Features\SupportFileUploads\TemporaryUploadedFile $file) {
                        return $component->shouldPreserveFilenames()
                            ? $file->getClientOriginalName()
                            : (Str::ulid() . '.' . $file->getClientOriginalExtension());
                    })
                    ->afterStateUpdated(function (Set $set, $component, ?string $state) {
                        $set('new_file_name', $state);
                    }),
                TextInput::make('new_file_name')
                    ->label(__('message.project.upload_file_modal.file_name'))
                    ->live()
                    ->required(),
            ])
            ->action(function (array $data, $record, Get $get, Set $set) use ($sender, $project, $folderService): void {

                dd($sender, $get(), $data, $record, $project);
                $parentId = $sender->parentId; 
                $projectId = $project->id;
                $fileName = $data['new_file_name'];
                $filePath = $data['uploaded_file']; 

                // Verificar si ya existe una carpeta con el mismo nombre y parent_id
                $existingFolder = \App\Models\ProjectFile::where('parent_id', $parentId)
                    ->where('project_id', $projectId)
                    ->where('name', $fileName)
                    ->first();

                if ($existingFolder) {
                    \Filament\Notifications\Notification::make()
                        ->title(__('message.project.file_name_error_title'))
                        ->body(__('message.project.file_name_error_body'))
                        ->danger()
                        ->send();
                    return;
                }

                $folderService->createProjectFile($project, $fileName, $folderService->getAbsoluteFullPhysicalFolderPath($project, $parentId), $parentId);

                $sender->resetTable();

            });
    }

Solution

  • I think you need to make the FileUpload component reactive ->reactive() to changes, triggering Livewire updates. Modified afterStateUpdated

    Retrieves the uploaded file instance, extracts its original name with proper type checking, and falls back to the basename if a path string is encountered. Lastly Add dehydrated(true).

    \Filament\Forms\Components\FileUpload::make('uploaded_file')
        ->label(__('message.project.upload_file_modal.select_file'))
        ->disk('private')
        ->directory(fn() => "projects/{$project->id}")
        ->required()
        ->acceptedFileTypes(['application/pdf', 'image/*', 'video/*', 'text/plain'])
        ->maxSize(10240)
        ->getUploadedFileNameForStorageUsing(function (BaseFileUpload $component, TemporaryUploadedFile $file) {
            return $component->shouldPreserveFilenames()
                ? $file->getClientOriginalName()
                : (Str::ulid() . '.' . $file->getClientOriginalExtension());
        })
        ->afterStateUpdated(function (Set $set, $component) {
            // Get the uploaded file instance and extract original name
            $file = $component->getState();
            $originalName = $file instanceof TemporaryUploadedFile 
                ? $file->getClientOriginalName()
                : basename($file);
            
            $set('new_file_name', $originalName);
        })
        ->reactive(), // Make the component reactive
    
    \Filament\Forms\Components\TextInput::make('new_file_name')
        ->label(__('message.project.upload_file_modal.file_name'))
        ->required()
        ->dehydrated(true),