Nuekrato
Nuekrato
FFilament
Created by Nuekrato on 5/28/2024 in #❓┊help
CheckboxList: modifyOptionsQueryUsing does not exist
The docs say there should be this method to modify the options but this method does not exist: https://filamentphp.com/docs/3.x/forms/fields/checkbox-list#customizing-the-relationship-query I currently need to accomplish exactly that: Set the relationship based on a different table than the options. Example code:
private function getPermissionsForm()
{
$checkboxLists = [];
foreach ($this->template->allowedTargets as $target) {
$checkboxLists[] = CheckboxList::make('templatePermissions')
->label($target->name)
->relationship(
name: 'templatePermissions',
titleAttribute: 'name',
modifyQueryUsing: fn (Builder $query) => $query->where('template_id', $this->template->id),
)
->options(function () use ($target) {
$permissions = [];
$templatePermissions = Permission::whereNull('model_id')->where('model_type', Project::class)
->where('destination_id', $target->id)->whereIn('name', ['download', 'upload'])->get();
foreach ($templatePermissions as $permission) {
$permissions[$permission->id] = $permission->name;
}
return $permissions;
})
->pivotData([
'template_id' => $this->template->id,
]);
}
return $checkboxLists;
}
private function getPermissionsForm()
{
$checkboxLists = [];
foreach ($this->template->allowedTargets as $target) {
$checkboxLists[] = CheckboxList::make('templatePermissions')
->label($target->name)
->relationship(
name: 'templatePermissions',
titleAttribute: 'name',
modifyQueryUsing: fn (Builder $query) => $query->where('template_id', $this->template->id),
)
->options(function () use ($target) {
$permissions = [];
$templatePermissions = Permission::whereNull('model_id')->where('model_type', Project::class)
->where('destination_id', $target->id)->whereIn('name', ['download', 'upload'])->get();
foreach ($templatePermissions as $permission) {
$permissions[$permission->id] = $permission->name;
}
return $permissions;
})
->pivotData([
'template_id' => $this->template->id,
]);
}
return $checkboxLists;
}
This code is inside a GroupRelationManager of a Template. A Group can belong to templatePermissions (which is the name of the relationship of the group) - but the options are coming from another table. Using the CheckboxList like this gives a wrong result. Also the modifyQueryUsing-method is not called as long as options is set. If I comment out ->options(...) the modifyQueryUsing is called.
5 replies
FFilament
Created by Nuekrato on 5/15/2024 in #❓┊help
Form: Adding user-defined pivot data to belongsToMany relationship
I have a form like this:
public static function form(Form $form): Form
{
return $form
->schema([
CheckboxList::make('allowedTargets')
->disabledOn('edit')
->relationship(name: 'allowedTargets', titleAttribute: 'name')
->pivotData([
TextInput::make('allowed_file_extensions')
->label('Allowed File Extensions')
->required(),
])
]);
}
public static function form(Form $form): Form
{
return $form
->schema([
CheckboxList::make('allowedTargets')
->disabledOn('edit')
->relationship(name: 'allowedTargets', titleAttribute: 'name')
->pivotData([
TextInput::make('allowed_file_extensions')
->label('Allowed File Extensions')
->required(),
])
]);
}
allowedTargets is a many-to-many-relationship of my Model. Each target has a pivot column allowed_file_extensions which accepts an array of file extensions as strings. Using a TextInput inside the pivotData()-method is not doing anything. But it is also not documented and was just an example what I already tried. I want the user be able to add allowed_file_extensions as pivot data on the create page of my Model. So he is able to create the parent model directly with the relationship and the specific pivot data. Is that possible? I also tried it using a RelationManager but it seems like RelationManagers don't show up on the resource create page.
5 replies
FFilament
Created by Nuekrato on 5/14/2024 in #❓┊help
Form: Nested JSON values are stored as string instead of integers
I have a form like:
public static function form(Form $form): Form
{
return $form
->schema([
TextInput::make('config.file_expire_days')
->integer()
->default(30)
->required(),
]);
}
public static function form(Form $form): Form
{
return $form
->schema([
TextInput::make('config.file_expire_days')
->integer()
->default(30)
->required(),
]);
}
And my model even casts the json values:
protected $casts = [
'config' => 'array',
'config->notify_project_expire_days' => 'array',
'config->project_expire_days' => 'integer',
'config->file_expire_days' => 'integer',
];
protected $casts = [
'config' => 'array',
'config->notify_project_expire_days' => 'array',
'config->project_expire_days' => 'integer',
'config->file_expire_days' => 'integer',
];
But if I save my form the model is created in the databse with string values in the JSON column (see the file_expire_days): {"base_path": "test", "file_expire_days": "15", "auto_delete_files": true, "project_expire_days": 30, "notify_project_expire_days": [14, "7", "1"]} If I leave the default value it is saved correctly as an integer. How can I tell filament that the values should be stored according to the model cast?
4 replies
FFilament
Created by Nuekrato on 5/8/2024 in #❓┊help
How to get $data from table form action?
I built a rather complex action in my table which looks like this:
->actions([
Action::make('permissions')
->form(function (User $record) {
$checkboxLists = [];
foreach ($this->project->targets as $target) {
$checkboxLists[] = CheckboxList::make('directPermissions')
->label($target->name)
->relationship(
titleAttribute: 'name'
)
->options(function () use ($target) {
$permissions = [];
foreach ($this->project->directPermissions()->where('destination_id', $target->id)->get() as $permission) {
$permissions[$permission->id] = $permission->name;
}
return $permissions;
});
}
return $checkboxLists;
})
->fillForm(function ($record) {
return $record->toArray();
})
->model(function ($record) {
return $record;
})
->action(function (array $data, $record, RelationManager $livewire) {
logger()->debug('Permissions data', $data);
})
])
->actions([
Action::make('permissions')
->form(function (User $record) {
$checkboxLists = [];
foreach ($this->project->targets as $target) {
$checkboxLists[] = CheckboxList::make('directPermissions')
->label($target->name)
->relationship(
titleAttribute: 'name'
)
->options(function () use ($target) {
$permissions = [];
foreach ($this->project->directPermissions()->where('destination_id', $target->id)->get() as $permission) {
$permissions[$permission->id] = $permission->name;
}
return $permissions;
});
}
return $checkboxLists;
})
->fillForm(function ($record) {
return $record->toArray();
})
->model(function ($record) {
return $record;
})
->action(function (array $data, $record, RelationManager $livewire) {
logger()->debug('Permissions data', $data);
})
])
This works perfectly fine and correctly sets the user's permissions in their project. The problem is that I am just not able to get the $data in the ->action -method. After submitting the form the $data seems to be empty: [2024-05-08 08:31:58] production.DEBUG: Permissions data So the ->action-method is triggered correctly but is not getting any data back from the form?
9 replies
FFilament
Created by Nuekrato on 5/7/2024 in #❓┊help
Custom field: bind array data
I created a custom field and this custom field renders mutliple Filament Checkboxes:
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
<div x-data="{ state: $wire.$entangle('{{ $getStatePath() }}') }">
<!-- Interact with the `state` property in Alpine.js -->
<h1>Changing permissions for {{ $user()?->username}}</h1>
@foreach ($projectPermissions() as $permission)
<label>
<x-filament::input.checkbox x-model="state" />

<span>
{{ $permission->name }}
{{ $permission->destination->name }}
</span>
</label>
@endforeach
</div>

</x-dynamic-component>
<x-dynamic-component :component="$getFieldWrapperView()" :field="$field">
<div x-data="{ state: $wire.$entangle('{{ $getStatePath() }}') }">
<!-- Interact with the `state` property in Alpine.js -->
<h1>Changing permissions for {{ $user()?->username}}</h1>
@foreach ($projectPermissions() as $permission)
<label>
<x-filament::input.checkbox x-model="state" />

<span>
{{ $permission->name }}
{{ $permission->destination->name }}
</span>
</label>
@endforeach
</div>

</x-dynamic-component>
As you can see I bind the input to the state. The problem is that this binds every Checkbox to the state and this results in every checkbox using the same state (so only one true/false value for all checkboxes). How can I bind each checkbox to an array in the state?
55 replies