Spatie Settings Checkboxlist
Hello all. As part of my steep learning curve, I've decided to build a new Filament Startup Kit adding some interesting features which might be useful for any DEV to use as a starter.
So after setting up Filament Admin Panel with Jetstream to allow 2FA, it was time for Spatie Settings which would allow any project to have an easy to implement/edit/adapt Settings page. To mimic the appearance of other settings pages we are used to (e.g. Wordpress etc). I've decided to use a single group, so added a few input variables in /app/Settings/GeneralSettings.php and then added the GeneralSettingsPage.php which would hold the input forms to store the data. Also added a migration to supply the required columns.
To separate/group some settings logically I decided to use tabs which are easy to implement and allow the required functionality. So with that I decided that it will be great to add an example for every Form input there is with Filament and it all worked perfectly fine to store and show the stored data on the Settings page utntil I reached the CheckboxList input.
So I am presently able to show the form as it should using the following code:
However when I define the variable in the GeneralSettings.php file as: public ?string $site_checkboxlist I get an error while trying to store the data:
`
Cannot assign array to property App\Settings\GeneralSettings::$site_checkboxlist of type ?string
21 Replies
If I try to define the variable as an array, I get a reverse error:
My question is, how does it work with Filment Settings to store an array as CheckboxList definitely would allow more than one checkbox to be stored and read back?
I've read in plugin documentation that I should do a cast but it was mentioning to do so in the model and I am not sure which model should I add the cast and what exactly should I add there so that my input field of type CheckboxList is allowing proper data storage...
As usual, any help or shared opinion is more than perfect, here is what I am trying to store presently:
Btw, Here is my /app/Filament/Pages/GeneralSettingsPage.php code:
And here is my /app/Settings/GeneralSettings.php page code:
‘public array $site_checxboxlist’ in should cast it correctly if added to GeneralSettings class, according to the spatie docs.
So, not the model, in this use case but the class that extends Settings. Spatie will infer the cast from the property.
But you can define explicit casts too. https://github.com/spatie/laravel-settings?tab=readme-ov-file#local-casts
GitHub
GitHub - spatie/laravel-settings: Store strongly typed application ...
Store strongly typed application settings. Contribute to spatie/laravel-settings development by creating an account on GitHub.
@awcodes
Ive read it inside out but I am not really finding any clue as to what type of cast to use for storing an array of data to a single column...
The only close example to my need was:
However in this example it is using the encrypted() method to encrypt the 'site_name' data
Based on the code you provided
public array $site_checkboxlist
should cast appropriately.One type of cast I've found that can be suitable is ArraySerttingsCast but it requires some parameters and I am having hard time finding those
Maybe I just need to see more of the rest of the code.
There aren't any other modifications to official Filament but the migration, GeneralSettings..php and GeneralSettingsPage.php which I've shared.
Here is the migration too in case it helps:
Steps to reproduce my "issue":
1. Install filament (I used latest from few days ago)
2. Install Spatie-Settings for filament.
3. Create a migration
4. Create a GeneralSettings settings page that extends the Settings class
5. Create the GeneralSettingsPage in filament/pages to show it to the navigation and inside of this page, try to use CheckboxList with the following code (or similar)
6. Try to store a few checkboxes
`php
// All CheckboxList options: https://filamentphp.com/docs/3.x/forms/fields/checkbox-list
CheckboxList::make('site_checkboxlist') // checkbox list with supplied options
->options([
'1' => '== A ==',
'2' => '== B ==',
'3' => '== C =='
])
// set the number of columns to order the list options (equal number of coluns and choices makes them horizonta)
->columns(3),
// ->label('') // set an empty label value to hide it
Can you share a repo. The code you’ve shared seems to cover different things and I’m not sure at this point what you are doing.
Sure thing, let me just commit it and will share the link here. It is not much as I said but I agree sometimes looking at pieces of code does not give the full picture.. Thanks anyway 😉
@awcodes
Here it is the repo with all it's perks.
FYI, so far i only have installed a fresh Filament Admin panel with Laravel 11.x and added Larael Jetstream to improve the user logging experience adding 2FA.
On top of that I've installed Filament Spatie Settings plugin and created the shared GeneralSettings.php extending Settings and GeneralSettingsPage.php responsible for the Settings form.
Here is the github repo URL;
https://github.com/mikemastercorp/filament-starter-kit
GitHub
GitHub - mikemastercorp/filament-starter-kit
Contribute to mikemastercorp/filament-starter-kit development by creating an account on GitHub.
The idea is to add an example for all Form inputs so that if anybody needs to combine settings, can simply repurpose the template as they see fit without wondering like me how to add this or that or have the error I am facing with array<>string store.
Tried to add this cast, but it was able to show the Settings page, but blew an error on storing the data:
`php
public static function casts(): array
{
return [
'site_checkboxlist' => \Spatie\LaravelSettings\SettingsCasts\CollectionCast::class,
];
}
I would expect this to work.
I don’t think CollectionCast is right here either as it should just be a flat array of values.
@awcodes
Well, i would expect it to work as well, however there is an error the minute I switch to array type as it tries to store a string as an array and it does not allow it. I've posted it in the initial comment that switching string to array did not do the work.
Here is the error from my previous message:
I've tried also to switch the type of the checkbox as a collection, however it seems like a method like ->collection() does not exist on the form inputs...
Seems like the data passed is a JSON object of type:
[
'1' => 'true',
'2' => 'false'
]
Or some other data sorting, but this should have been considered as a string, but it is actually considered as something strange to me, as I cannot define $site_checkboxlist as array, nor as string...
Maybe I should try defining it as a JSON object somehow to test, but I don't find any useful information so far about that in the casts, and i've looked into many LaravelSettings casts to figure out which one should i use and how...
This is working for me:
Make sure the initial payload in the DB is an empty array.
The initial DB payload is empty, just in the DB it was '' but in your example was [] So I've switched to [] and it allowed to pass the POST, however the payload in DB and the view still remains [] and not populated with the options....
Same '' payload for other inputs worked to populate the proper choice/value, just the array was not populated as you can see on the image.
Tried to correct the migration and pushed a fresh DB to test, using my migration code as:
After which I can see the payload matching yours ([]) however I am still unable to store the data in the DB and show it on...
It saves the page correctly with the $site_checkboxlist defined as an array, however no data is stored in the DB during save and no errors shown in the log either to indicate an issue...
Wholly guaccamole... It was my silly mistake of trying to define the input form field as an array, e.g.
Must be one of all my attempts to please the array data storing... Once I removed it, I CONFIRM YOUR CODE WORKS !!!
Thank you @awcodes you saved me a few more weeks of scratching my head...