Josh777
Josh777
FFilament
Created by Josh777 on 11/24/2023 in #❓┊help
Why Select field does not save as null when no options exist i.e. only placeholder
I have a problem where I have a Select with dynamic options generated within a repeater. If the Select has options and the user has saved the form with an option selected, the data is submitted to the json field in the database - as expected. If the Select no longer has any options i.e. an empty state with the placeholder "Select an option", this should save a null value back to the database but it doesn't. It still has the data attached that existed before, even though the Select is empty. I can prove this by dumping $data within mutateFormDataBeforeSave(array $data), the field has the data from before and I am very confused as to why. It is my understanding $data includes client side submitted values only and does not fetch anything from the database at this stage. So why would it be fetching the previous data from the Select that no longer exists? Steps: Before:
Repeater::make('maintenance')
->schema([
Select::make('type')
->label('Maintenance Type')
->options(['water' => 'Water', 'filter' => 'Filter'])
]);
Repeater::make('maintenance')
->schema([
Select::make('type')
->label('Maintenance Type')
->options(['water' => 'Water', 'filter' => 'Filter'])
]);
User selects 'water', then value is saved to database in json e.g. "type": "water" After:
Repeater::make('maintenance')
->schema([
Select::make('type')
->label('Maintenance Type')
->options([])
]);
Repeater::make('maintenance')
->schema([
Select::make('type')
->label('Maintenance Type')
->options([])
]);
User cannot select anything, submits form and in the $data array, "water" still exists within the submitted data. How?!
9 replies
FFilament
Created by Josh777 on 11/1/2023 in #❓┊help
ViewColumn does not open modal with Modal Blade component
No description
10 replies
FFilament
Created by Josh777 on 10/26/2023 in #❓┊help
Queue FileUpload(s) for large data (videos/images)
I have run into a situation that I have searched far and wide but can't see an answer for. Imagine you need to upload a 100MB video to your S3 bucket via the FileUpload component. This will upload say up to 80MB to S3 before the server gateway response times out with a 504. Instead of having this happen directly in the request, is there an obvious way we can queue uploads and job them from this component? Or chunk the uploads somehow? I've tried doing this locally by sending the following snippet to the job, but I'm hit with serialization errors that are related to both the $file and $component.
$this->saveUploadedFileUsing(static function (BaseFileUpload $component, TemporaryUploadedFile $file): ?string {
try {
if (!$file->exists()) {
return null;
}
} catch (UnableToCheckFileExistence $exception) {
return null;
}

// dispatch rest of logic in job
Job::dispatch($file, $component);

// Error: Serialization of 'Closure' is not allowed
$this->saveUploadedFileUsing(static function (BaseFileUpload $component, TemporaryUploadedFile $file): ?string {
try {
if (!$file->exists()) {
return null;
}
} catch (UnableToCheckFileExistence $exception) {
return null;
}

// dispatch rest of logic in job
Job::dispatch($file, $component);

// Error: Serialization of 'Closure' is not allowed
Not a whizz kid with Livewire, so if anyone can help out that would be amazing. I imagine this is a problem a lot of people have run into, any answers appreciated.
6 replies
FFilament
Created by Josh777 on 7/27/2023 in #❓┊help
How to pass custom data to view from Custom Field?
I have a custom field called Checklist. In a loop, I am passing the $record to a custom method called device, and a checklist_id from a pivot table 'checklist_device' to a method called list.
Checklist::make('items')
->device($record)
->list($list->pivot->checklist_id)
Checklist::make('items')
->device($record)
->list($list->pivot->checklist_id)
This is to render specific json items from this pivot table in a field called 'items'. This is my custom field class:
class Checklist extends Field
{
protected string $view = 'forms.components.checklist';

protected int $list;
protected Model $device;

protected function setUp(): void
{
parent::setUp();
}

public function list(int $list): static
{
$this->list = $list;

return $this;
}

public function getList(): int
{
return $this->list;
}

public function device($device)
{
$this->device = $device;

return $this;
}

public function getDevice()
{
return $this->device;
}



public function render(): View
{
$checklistItems = $this->getDevice()
->checklists()
->where('checklist_id', $this->getList())
->first()
->pivot
->items;

return view(
$this->getView(),
array_merge(
['attributes' => new ComponentAttributeBag()],
$this->extractPublicProperties(),
$this->extractPublicMethods(),
isset($this->viewIdentifier) ? [$this->viewIdentifier => $this] : [],
$checklistItems
),
);
}
}
class Checklist extends Field
{
protected string $view = 'forms.components.checklist';

protected int $list;
protected Model $device;

protected function setUp(): void
{
parent::setUp();
}

public function list(int $list): static
{
$this->list = $list;

return $this;
}

public function getList(): int
{
return $this->list;
}

public function device($device)
{
$this->device = $device;

return $this;
}

public function getDevice()
{
return $this->device;
}



public function render(): View
{
$checklistItems = $this->getDevice()
->checklists()
->where('checklist_id', $this->getList())
->first()
->pivot
->items;

return view(
$this->getView(),
array_merge(
['attributes' => new ComponentAttributeBag()],
$this->extractPublicProperties(),
$this->extractPublicMethods(),
isset($this->viewIdentifier) ? [$this->viewIdentifier => $this] : [],
$checklistItems
),
);
}
}
I guess what I'm failing to understand is how to bypass that 'make' function and in my view, have custom data from the render method instead, as you can see $checklistItems is currently not doing anything.
4 replies
FFilament
Created by Josh777 on 7/11/2023 in #❓┊help
Hide all resources depending on user
Is there a quick way to revoke all access to resources if for example, the current logged in user does not have in_admin:1 on their model? I currently 'hide' them by doing the following in my AppServiceProvider, essentially rendering an empty nav: view()->composer('*', function ($view) { if (!auth()->user()->is_admin) { Filament::navigation(function (NavigationBuilder $builder): NavigationBuilder { return $builder; }); } }); However, if I navigate to /posts, I will still be able to access the resource anyway. I guess what I'm asking is how can I do this without creating a policy for every one of my models, and have some sort of global gate that wraps around resources somewhere to check the user state. Posted this on the Github Discussions, but haven't had a response. Cheers all https://github.com/filamentphp/filament/discussions/6983
12 replies