Default options of checkbox list

I have this section :
Section::make()
->schema([
Forms\Components\Repeater::make('academies')
->label('academies')
->relationship('academies')
->schema([
Forms\Components\TextInput::make('title')
->label('title')
->disabled(),

Forms\Components\CheckboxList::make('roles')
->label('roles')
->options(function ($record) {
return $record->roles->pluck('name', 'id')->toArray();
})
->formatStateUsing(function ($record) use ($form) {
$userRoleIds = $form->model->roles->pluck('id')->toArray();

$currentCheckBoxId = //ID
return in_array($currentCheckBoxId,$userRoleIds);
})
])
->addable(false)
->columns(1),
])
->columnSpan([
'sm' => 2,
]),
Section::make()
->schema([
Forms\Components\Repeater::make('academies')
->label('academies')
->relationship('academies')
->schema([
Forms\Components\TextInput::make('title')
->label('title')
->disabled(),

Forms\Components\CheckboxList::make('roles')
->label('roles')
->options(function ($record) {
return $record->roles->pluck('name', 'id')->toArray();
})
->formatStateUsing(function ($record) use ($form) {
$userRoleIds = $form->model->roles->pluck('id')->toArray();

$currentCheckBoxId = //ID
return in_array($currentCheckBoxId,$userRoleIds);
})
])
->addable(false)
->columns(1),
])
->columnSpan([
'sm' => 2,
]),
How can I compare the current checkbox id with the User resource role id to make it checked ?
34 Replies
toeknee
toeknee4mo ago
Why do you need too? Your relationship should be pre-checked from the data that's being loaded?
sezohussien
sezohussienOP4mo ago
can not use relationship hasMany on checkbox list
toeknee
toeknee4mo ago
so you probably want getStateUsing opposed to formatStateUsing
sezohussien
sezohussienOP4mo ago
I am in User resource, and use has Many roles and belongsToMany academies , I just want to display all roles of the academy and default select the user roles that he have I solved it now by using
CheckboxList::make('roles')
->label('roles')
->options(function ($record) {
return $record->roles->pluck('name', 'id')->toArray();
})
->afterStateHydrated(function (CheckboxList $component, $record) use ($form) {
$roleIds = $form->model->roles->pluck('id')->toArray();

$component->state($roleIds);
})
CheckboxList::make('roles')
->label('roles')
->options(function ($record) {
return $record->roles->pluck('name', 'id')->toArray();
})
->afterStateHydrated(function (CheckboxList $component, $record) use ($form) {
$roleIds = $form->model->roles->pluck('id')->toArray();

$component->state($roleIds);
})
but IDK why the data is not sending to method mutateFormDataBeforeSave ?
toeknee
toeknee4mo ago
Because your are not hydrating it You set it but it's not be hydrated which is why I suggested getStateUsing You could try using $set in afterStateHydrated?
sezohussien
sezohussienOP4mo ago
Method Filament\Forms\Components\CheckboxList::getStateUsing does not exist. @toeknee still can not sending data
toeknee
toeknee4mo ago
What code are you using Are you sure it is not sending the data? Have you got the model fillable filled for the column
sezohussien
sezohussienOP4mo ago
this is not column , I just need to send the Ids of the rols then sync the Ids for thre User roles (Spaite roles)
protected function mutateFormDataBeforeSave($data):array {
dd($data);
return $data;
}
protected function mutateFormDataBeforeSave($data):array {
dd($data);
return $data;
}
roles not sending to the $data @toeknee
LeandroFerreira
LeandroFerreira4mo ago
are you using relationship() in roles?
sezohussien
sezohussienOP4mo ago
no The idea that : Academy has many roles, And User belongs to many academies , Also user has many roles I need to group be academy and for each academy display the roles of it . when in the edit page of user I can edit the roles of users for each academy that he belongs to.
sezohussien
sezohussienOP4mo ago
No description
No description
sezohussien
sezohussienOP4mo ago
got it ? @Leandro Ferreira @toeknee
LeandroFerreira
LeandroFerreira4mo ago
please read #✅┊rules
No description
sezohussien
sezohussienOP4mo ago
sorry
LeandroFerreira
LeandroFerreira4mo ago
use dehydrated() in the academies repeater if you want to access the data in $data array
sezohussien
sezohussienOP4mo ago
Thank you ❤️ is there other simple idea to make this approach ?
sezohussien
sezohussienOP4mo ago
every thins is working now but data is not refreshed after save (its saved in DB):
protected function handleRecordUpdate(Model $record, array $data): Model
{
$record->update($data);

$this->syncRoles($data);

return $record;
}

protected function syncRoles($data): void
{
$roles = Arr::get($data, 'roles', []);

// Synchronize roles with the resource
$this->record->roles()->sync($roles);
}

protected function collectUniqueRoleIds(array $academies): array
{
return Collection::make($academies)
->pluck('roles')
->flatten()
->unique()
->values()
->toArray();
}

protected function mutateFormDataBeforeSave($data): array
{
$academies = Arr::get($data, 'academies', []);
$data['roles'] = $this->collectUniqueRoleIds($academies);
return $data;
}
protected function handleRecordUpdate(Model $record, array $data): Model
{
$record->update($data);

$this->syncRoles($data);

return $record;
}

protected function syncRoles($data): void
{
$roles = Arr::get($data, 'roles', []);

// Synchronize roles with the resource
$this->record->roles()->sync($roles);
}

protected function collectUniqueRoleIds(array $academies): array
{
return Collection::make($academies)
->pluck('roles')
->flatten()
->unique()
->values()
->toArray();
}

protected function mutateFormDataBeforeSave($data): array
{
$academies = Arr::get($data, 'academies', []);
$data['roles'] = $this->collectUniqueRoleIds($academies);
return $data;
}
LeandroFerreira
LeandroFerreira4mo ago
try $this->refreshFormData(['field']) after saving
sezohussien
sezohussienOP4mo ago
ok thanks but afterStateHydrated still have problem on it, I need to set the default checkboxes checked IIF ID of the checkbox in the $roleIds = $form->model->roles->pluck('id')->toArray(); ->default() is not working with CheckboxList
toeknee
toeknee4mo ago
default only works in creation not edit
sezohussien
sezohussienOP4mo ago
so, how to auto select ?
toeknee
toeknee4mo ago
you pass them in on mount, you shouldn't be maniplating data in and edit form really
sezohussien
sezohussienOP4mo ago
I just need edit form only how can I fill the data in mounted ?
toeknee
toeknee4mo ago
Is this on a resource or a custom form
sezohussien
sezohussienOP4mo ago
in resource
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Group::make()
->schema([
Forms\Components\Card::make()
->schema([
Forms\Components\Repeater::make('academies')
->label('academies')
->relationship('academies')
->schema([
Forms\Components\TextInput::make('title')
->label('title')
->disabled(),

CheckboxList::make('roles')
->label('roles')
->options(function ($record) {
return $record->roles->pluck('name', 'id')->toArray();
})
])
->dehydrated()
->addable(false)
->columns(1),
public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Group::make()
->schema([
Forms\Components\Card::make()
->schema([
Forms\Components\Repeater::make('academies')
->label('academies')
->relationship('academies')
->schema([
Forms\Components\TextInput::make('title')
->label('title')
->disabled(),

CheckboxList::make('roles')
->label('roles')
->options(function ($record) {
return $record->roles->pluck('name', 'id')->toArray();
})
])
->dehydrated()
->addable(false)
->columns(1),
toeknee
toeknee4mo ago
->dehydrated() it will never save with this on it.
sezohussien
sezohussienOP4mo ago
but the data(Roles) is not sending when saving
toeknee
toeknee4mo ago
It won't because you have set: ->dehydrated() which means it will send nothing.
sezohussien
sezohussienOP4mo ago
So what should I do ? any recommendation
toeknee
toeknee4mo ago
remove ->dehydrated() and it should be set
sezohussien
sezohussienOP4mo ago
set in which method ? also I need the adding the default values which is ($form->model->roles->pluck('id')->toArray();)
sezohussien
sezohussienOP4mo ago
to clarify the idea
No description
sezohussien
sezohussienOP4mo ago
I need to use dehydrated here
Want results from more Discord servers?
Add your server