Arjen
Arjen
FFilament
Created by Arjen on 4/9/2025 in #❓┊help
Dynamic ExportColumns based on JSON field in Exporter, possible?
Hi, is it possible to define extra dynamic export columns based on a JSON array from a owner record in a relation manager? My use case: I've got a Course resource with a CourseRegistration (HasMany) relation manager. The Course resource contains a Builder field that is used to insert extra form fields for when people sign up for a course. For example:
[
{
"data": {"id": "dN268g", "label": "Question", "data_type": "string", "is_required": true},
"type": "text_input"
},
//...
]
[
{
"data": {"id": "dN268g", "label": "Question", "data_type": "string", "is_required": true},
"type": "text_input"
},
//...
]
When a person fills in the sign up form, the extra fields get saved in CourseRegistration in a DB column like so:
{"Question": "Answer", //...}
{"Question": "Answer", //...}
I've added an Exporter to the CourseRegistration relation manager, and I want to create extra columns for every extra form field, so that the csv/xlsx for all signups doesn't contain one column with above data. Is this possible? Is there a way to get a hold of the owner record inside the public static function getColumns() method inside an Exporter? Basically I need a way to pass the owner record to the exporter class.
6 replies
FFilament
Created by Arjen on 3/31/2025 in #❓┊help
GRecaptcha field disappears on livewire/update in a Livewire Component, but not in Panel Resource
I've implemented the Captcha field in a Livewire Component, but after doing the captcha or saving the form, the captcha disappears. It seems wire:ignore here is not respected. The weird thing here is when I place this Captcha field inside a panel resource form, it works correctly and does not disappear. I've tried moving the wire:ignore but it's not working. I could really use some assistence here.
<?php

namespace App\Livewire;

use AbanoubNassem\FilamentGRecaptchaField\Forms\Components\GRecaptcha;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
use Livewire\Component;

class SignUpForm extends Component implements HasForms
{
use InteractsWithForms;

public $captcha = '';

public function form(Form $form): Form
{
return $form
->schema([
'captcha' => GRecaptcha::make('captcha')
->label('Captcha')
->validationMessages([
'required' => 'De captcha is verplicht.',
]),
]);
}

public function create(): void
{
$data = $this->form->getState();
}

public function render()
{
return view('livewire.sign-up-form');
}
}
<?php

namespace App\Livewire;

use AbanoubNassem\FilamentGRecaptchaField\Forms\Components\GRecaptcha;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
use Livewire\Component;

class SignUpForm extends Component implements HasForms
{
use InteractsWithForms;

public $captcha = '';

public function form(Form $form): Form
{
return $form
->schema([
'captcha' => GRecaptcha::make('captcha')
->label('Captcha')
->validationMessages([
'required' => 'De captcha is verplicht.',
]),
]);
}

public function create(): void
{
$data = $this->form->getState();
}

public function render()
{
return view('livewire.sign-up-form');
}
}
<div>
<form wire:submit="create">
{{ $this->form }}

<button class="button" type="submit">
Versturen
</button>
</form>

<x-filament-actions::modals />
</div>
<div>
<form wire:submit="create">
{{ $this->form }}

<button class="button" type="submit">
Versturen
</button>
</form>

<x-filament-actions::modals />
</div>
6 replies
FFilament
Created by Arjen on 3/30/2025 in #❓┊help
How to get infolist in ViewAction modal in table widget?
I've created a table widget and I'd like to get the infolist I defined in the resource for this specific model to show up when I view the record (which opens in a modal on both the resource and this table widget). I've tried adding the infolist method, but there nothing appearing inside the model. What am I missing?
class ConversationReports extends \Filament\Widgets\TableWidget
{
public function table(Table $table): Table
{
return $table
->query(ConversationReport::query())
->columns([
// ...
])
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make()
->url(fn (ConversationReport $record) => ConversationReportResource::getUrl('edit', ['record' => $record])),
])
->recordAction(Tables\Actions\ViewAction::class)
->recordUrl(null);
}

public static function infolist(Infolist $infolist): Infolist
{
return ConversationReportResource::infolist($infolist);
}
}
class ConversationReports extends \Filament\Widgets\TableWidget
{
public function table(Table $table): Table
{
return $table
->query(ConversationReport::query())
->columns([
// ...
])
->actions([
Tables\Actions\ViewAction::make(),
Tables\Actions\EditAction::make()
->url(fn (ConversationReport $record) => ConversationReportResource::getUrl('edit', ['record' => $record])),
])
->recordAction(Tables\Actions\ViewAction::class)
->recordUrl(null);
}

public static function infolist(Infolist $infolist): Infolist
{
return ConversationReportResource::infolist($infolist);
}
}
6 replies
FFilament
Created by Arjen on 3/18/2025 in #❓┊help
Form with Wizard not saving relations with non-default statePaths
I've got the following code:
class PlaceServiceForm extends Component implements HasForms
{
use InteractsWithForms;

public ?array $data = [];

public function mount(): void
{
$this->form->fill();
}

public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Wizard::make([
Forms\Components\Wizard\Step::make('Aanbod plaatsen')
->schema([
// ...
Forms\Components\CheckboxList::make('categories')
->label('Categorieën (max. 3)')
->relationship(
titleAttribute: 'name',
),
// ...
])
->statePath('data.service')
->model(Models\Service::class),
Forms\Components\Wizard\Step::make('Organisatiegegevens')
->schema(OrganizationRegistration::getFormSchema())
->statePath('data.organization')
->model(Models\Organization::class),
Forms\Components\Wizard\Step::make('Logingegevens')
->schema(UserRegistration::getFormSchema())
->statePath('data.user')
->model(Models\User::class),
])
->submitAction(new HtmlString(Blade::render(<<<'BLADE'
<x-filament::button type="submit">
Plaatsen
</x-filament::button>
BLADE))),
])
->statePath('data');
}
class PlaceServiceForm extends Component implements HasForms
{
use InteractsWithForms;

public ?array $data = [];

public function mount(): void
{
$this->form->fill();
}

public function form(Form $form): Form
{
return $form
->schema([
Forms\Components\Wizard::make([
Forms\Components\Wizard\Step::make('Aanbod plaatsen')
->schema([
// ...
Forms\Components\CheckboxList::make('categories')
->label('Categorieën (max. 3)')
->relationship(
titleAttribute: 'name',
),
// ...
])
->statePath('data.service')
->model(Models\Service::class),
Forms\Components\Wizard\Step::make('Organisatiegegevens')
->schema(OrganizationRegistration::getFormSchema())
->statePath('data.organization')
->model(Models\Organization::class),
Forms\Components\Wizard\Step::make('Logingegevens')
->schema(UserRegistration::getFormSchema())
->statePath('data.user')
->model(Models\User::class),
])
->submitAction(new HtmlString(Blade::render(<<<'BLADE'
<x-filament::button type="submit">
Plaatsen
</x-filament::button>
BLADE))),
])
->statePath('data');
}
3 replies
FFilament
Created by Arjen on 3/10/2025 in #❓┊help
Different configuration for Actions inside ActionGroup possible?
Is it possible to change the configuration of an Action with configureUsing() if that action is inside an ActionGroup? My goal is to have all actions be shown as an ->iconButton(), but not if they're wrapped inside an ActionGroup.
4 replies
FFilament
Created by Arjen on 3/6/2025 in #❓┊help
$this->form->getState() empty
Hi, I've created a Filament page with the make command and I've placed a form inside the component. When I submit my form, $this->form->getState() returns an empty array and I'm not sure why. The $data property however is filled correctly, and my validation also runs fine. Any idea what's wrong with my code? Or shouldn't I use $this->form->getState() and just use $this->data? My file:
class VolunteerSettings extends Page implements HasForms
{
use InteractsWithFormActions;
use InteractsWithForms;

protected static ?string $navigationIcon = 'heroicon-o-document-text';

protected static string $view = 'filament.pages.volunteer-settings';

protected static ?string $slug = 'vrijwilligervoorkeuren';

protected static ?string $title = 'Vrijwilligervoorkeuren';

public ?array $data = [];

public function mount()
{
$this->form->fill();
}

public function form(Form $form): Form
{
return $form
->model(auth()->user())
->schema([
Forms\Components\Section::make()
->relationship('volunteerProfile')
->schema([
'is_active' => Forms\Components\Toggle::make('is_active')
->label('Actief profiel')
->default(false)
->live(),
// ...
]),
])
->statePath('data');
}

public function getFormActions(): array
{
return [
Actions\Action::make('submit')
->label('Opslaan')
->submit('submit'),
];
}

public function submit()
{
$data = $this->form->getState();
dd($data, $this->data);
}
}
class VolunteerSettings extends Page implements HasForms
{
use InteractsWithFormActions;
use InteractsWithForms;

protected static ?string $navigationIcon = 'heroicon-o-document-text';

protected static string $view = 'filament.pages.volunteer-settings';

protected static ?string $slug = 'vrijwilligervoorkeuren';

protected static ?string $title = 'Vrijwilligervoorkeuren';

public ?array $data = [];

public function mount()
{
$this->form->fill();
}

public function form(Form $form): Form
{
return $form
->model(auth()->user())
->schema([
Forms\Components\Section::make()
->relationship('volunteerProfile')
->schema([
'is_active' => Forms\Components\Toggle::make('is_active')
->label('Actief profiel')
->default(false)
->live(),
// ...
]),
])
->statePath('data');
}

public function getFormActions(): array
{
return [
Actions\Action::make('submit')
->label('Opslaan')
->submit('submit'),
];
}

public function submit()
{
$data = $this->form->getState();
dd($data, $this->data);
}
}
5 replies
FFilament
Created by Arjen on 2/20/2025 in #❓┊help
Get current row in castStateUsing ImportColumn
Is this possible inside the closure? I need to change the state of one column based on another column.
4 replies
FFilament
Created by Arjen on 2/12/2025 in #❓┊help
Change table columns/filters based on active tab?
Is it possible in panels to show or hide specific table columns or filters based on the active tab?
6 replies
FFilament
Created by Arjen on 1/29/2025 in #❓┊help
What form inputs to use?
No description
5 replies
FFilament
Created by Arjen on 1/27/2025 in #❓┊help
Wizard loses $_GET param after next step
<?php

namespace App\Filament\Pages\Auth;

use Filament\Actions\Action;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Pages\Auth\Register;

class Registration extends Register
{
protected string $type = 'inwoner';

public function mount(): void
{
$this->type = request()->get('type', 'inwoner'); // inwoner or organisatie

parent::mount();
}

public function form(Form $form): Form
{
return $form
->schema([
$this->type === 'inwoner' ?
$this->getUserFormComponent() :
$this->getOrganizationFormComponent(),
]);
}
//
<?php

namespace App\Filament\Pages\Auth;

use Filament\Actions\Action;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Pages\Auth\Register;

class Registration extends Register
{
protected string $type = 'inwoner';

public function mount(): void
{
$this->type = request()->get('type', 'inwoner'); // inwoner or organisatie

parent::mount();
}

public function form(Form $form): Form
{
return $form
->schema([
$this->type === 'inwoner' ?
$this->getUserFormComponent() :
$this->getOrganizationFormComponent(),
]);
}
//
$this->getOrganizationFormComponent() return Filament\Forms\Components\Wizard component. Without the ternary in the form method, clicking next works, but with the ternary and type 'organisatie' in the url, clicking next results in the default type and the form glitches because of it. How can I make sure it returns the next step correctly?
5 replies
FFilament
Created by Arjen on 1/27/2025 in #❓┊help
Add card next to login card on login page
No description
2 replies
FFilament
Created by Arjen on 1/25/2024 in #❓┊help
Table column loses data when sorting by relationship
I have the following relation Booking -> HasMany -> Dayparts where Dayparts has a field date. I want to sort courses by the first child in Dayparts and while the code for that sorts the items in the table correctly, the data in the sorted column in the table just disappears. When the table is not sorted, the date is showing correctly. Any idea what I'm doing wrong? This is the table column in the BookingResource:
Tables\Columns\TextColumn::make('dayparts.0.date')
->label('Datum')
->date('d-m-Y')
->sortable(
query: fn ($query, $direction) => $query
->join('dayparts', function ($join) {
$join->on('dayparts.booking_id', '=', 'bookings.id')
->on('dayparts.id', DB::raw("(SELECT min(id) FROM dayparts WHERE dayparts.booking_id = bookings.id)"));
})
->orderBy('date', $direction)
),
Tables\Columns\TextColumn::make('dayparts.0.date')
->label('Datum')
->date('d-m-Y')
->sortable(
query: fn ($query, $direction) => $query
->join('dayparts', function ($join) {
$join->on('dayparts.booking_id', '=', 'bookings.id')
->on('dayparts.id', DB::raw("(SELECT min(id) FROM dayparts WHERE dayparts.booking_id = bookings.id)"));
})
->orderBy('date', $direction)
),
I tried changing 'dayparts.0.date' to 'date' as well, but that changes nothing.
3 replies
FFilament
Created by Arjen on 12/1/2023 in #❓┊help
Convert Filament::registerScripts
Hi, how do I convert the following piece of code from v2 to v3 FilamentAsset? I want to use the compiled code at public/build/assets/app-fdfe8a8c.js (for example) instead of the source in resources/js/app.js
Filament::serving(function () {
Filament::registerScripts([
app(Vite::class)('resources/js/app.js')
], true);
});
Filament::serving(function () {
Filament::registerScripts([
app(Vite::class)('resources/js/app.js')
], true);
});
5 replies
FFilament
Created by Arjen on 10/11/2023 in #❓┊help
Setting searchable select field to null not working
No description
4 replies
FFilament
Created by Arjen on 9/30/2023 in #❓┊help
Best way to include script
Hi, I've registered a custom script like this:
FilamentAsset::register([
Js::make('google-maps')->html(new HtmlString('
<script>
(g => {
var h, a, k, p = "The Google Maps JavaScript API",
c = "google",
l = "importLibrary",
q = "__ib__",
m = document,
b = window;
b = b[c] || (b[c] = {});
var d = b.maps || (b.maps = {}),
r = new Set,
e = new URLSearchParams,
u = () => h || (h = new Promise(async (f, n) => {
await (a = m.createElement("script"));
e.set("libraries", [...r] + "");
for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]);
e.set("callback", c + ".maps." + q);
a.src = `https://maps.${c}apis.com/maps/api/js?` + e;
d[q] = f;
a.onerror = () => h = n(Error(p + " could not load."));
a.nonce = m.querySelector("script[nonce]")?.nonce || "";
m.head.append(a)
}));
d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n))
})({
key: "",
v: "weekly",
});
</script>
')),
]);
FilamentAsset::register([
Js::make('google-maps')->html(new HtmlString('
<script>
(g => {
var h, a, k, p = "The Google Maps JavaScript API",
c = "google",
l = "importLibrary",
q = "__ib__",
m = document,
b = window;
b = b[c] || (b[c] = {});
var d = b.maps || (b.maps = {}),
r = new Set,
e = new URLSearchParams,
u = () => h || (h = new Promise(async (f, n) => {
await (a = m.createElement("script"));
e.set("libraries", [...r] + "");
for (k in g) e.set(k.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), g[k]);
e.set("callback", c + ".maps." + q);
a.src = `https://maps.${c}apis.com/maps/api/js?` + e;
d[q] = f;
a.onerror = () => h = n(Error(p + " could not load."));
a.nonce = m.querySelector("script[nonce]")?.nonce || "";
m.head.append(a)
}));
d[l] ? console.warn(p + " only loads once. Ignoring:", g) : d[l] = (f, ...n) => r.add(f) && u().then(() => d[l](f, ...n))
})({
key: "",
v: "weekly",
});
</script>
')),
]);
This works, but running php artisan filament:assets produces the following type error Filament\Support\Assets\Asset::getPath(): Return value must be of type string, null returned...
5 replies
FFilament
Created by Arjen on 5/12/2023 in #❓┊help
Prevent beforeOrEqual field from comparing to empty field
See title. Is this possible without resorting to custom rules?
3 replies
FFilament
Created by Arjen on 3/26/2023 in #❓┊help
Programmatically select a tab
Is it possible to programmatically select a tab? I have two tabs but based on a radio field, the first tab may get hidden. If that tab is selected, the other one doesn't automatically get selected so you'll only see the second tab (inactive) without the tab content.
2 replies
FFilament
Created by Arjen on 3/9/2023 in #❓┊help
Error when prefilling from query string in resource with persistTabInQueryString enabled
Hi, I get the following error when persisting tabs in query string enabled when creating a form or uploading files inside the form: https://flareapp.io/share/xPQ3Xol5#F113 The query strings looks like this: ?event_start=2023-03-04&event_end=2023-03-04&tab=tabs-evenement-tab, and the code for filling like this (not sure if it is the correct way to handle it):
class CreatePost extends CreateRecord
{
protected static string $resource = PostResource::class;

protected function afterFill()
{
$validator = Validator::make(
Request::query(),
[
'event_start' => 'required|date:Y-m-d',
'event_end' => 'date:Y-m-d',
]
);
if ($validator->fails()) {
return;
}

$data = $validator->validated();
$this->form->fill([
'has_event' => true,
'event_start' => $data['event_start'] . ' 12:00',
'event_end' => isset($data['event_end']) ? $data['event_end'] . ' 12:00' : null,
]);
}
}
class CreatePost extends CreateRecord
{
protected static string $resource = PostResource::class;

protected function afterFill()
{
$validator = Validator::make(
Request::query(),
[
'event_start' => 'required|date:Y-m-d',
'event_end' => 'date:Y-m-d',
]
);
if ($validator->fails()) {
return;
}

$data = $validator->validated();
$this->form->fill([
'has_event' => true,
'event_start' => $data['event_start'] . ' 12:00',
'event_end' => isset($data['event_end']) ? $data['event_end'] . ' 12:00' : null,
]);
}
}
11 replies
FFilament
Created by Arjen on 3/8/2023 in #❓┊help
Page::$reportValidationErrorUsing dispatchBrowserEvent
Is it possible to do something like this?
Page::$reportValidationErrorUsing = function (ValidationException $exception) {
session()->flash('errors_exception', 'Oeps, het ingevulde formulier bevat één of meerdere problemen.');
session()->flash('errors', $exception->validator->errors());

// Not working because it isn't a static method
Page::dispatchBrowserEvent('scroll-to', [
'query' => "#alert-errors",
'offset' => 120,
]);
};
Page::$reportValidationErrorUsing = function (ValidationException $exception) {
session()->flash('errors_exception', 'Oeps, het ingevulde formulier bevat één of meerdere problemen.');
session()->flash('errors', $exception->validator->errors());

// Not working because it isn't a static method
Page::dispatchBrowserEvent('scroll-to', [
'query' => "#alert-errors",
'offset' => 120,
]);
};
3 replies