In a Filament form I have the following field:
FileUpload::make('Files')
->acceptedFileTypes(self::$filetypes)
->disk('local')
->moveFiles()
->multiple(true)
Now before the form is submitted I want to validate the uploaded files based on their (original) names.
I have tried using ->rules()
but that only takes effekt after submitting the form.
I have also tried using ->afterStateUpdated()
like this:
->afterStateUpdated(function($state) {
foreach($state as $idx => $file) {
$filename = $file->getClientOriginalName();
if($filename == 'test.csv') {
$file->delete();
unset($state[$idx]);
}
}
})
This works for deleting the files and probably would not submit them (I have not tried that) but it does not update the field state to show that the file has been rejected.
Basically I'd want a $file->reject()
method so that my field looks like this. The file in the image was rejected due to its size, so there must be a way to validate the files before submission.
By using ->extraAlpineAttributes()
and the FilePond API which the FileUpload
field makes use of, I could accomplish something similar to what I wanted:
FileUpload::make('Files')
->acceptedFileTypes(self::$filetypes)
->disk('local')
->moveFiles()
->multiple(true)
->extraAlpineAttributes([
'x-init' => '$el.addEventListener(\'FilePond:processfileprogress\', (e) => { if(e.detail.file.filename === \'test.csv\') e.detail.file.abortProcessing() })'
])
->afterStateUpdated(function ($state) {
foreach ($state as $idx => $file) {
$filename = $file->getClientOriginalName();
if ($filename == 'test.csv') {
$file->delete();
}
}
})
With this method I cannot make it look red like the upload failed. It only says "aborted" and stays grey. Though the contrast to the successful green with multiple files should be good enough.
And I still need to use the ->afterStateUpdated()
method to handle things server-side and delete the uploaded files.