Certainly! Let's break down your issue and clarify what's happening with $get('module') vs $get('../../module') in your Filament form.
Why is $get('module') returning null?
In Filament forms, the $get() helper retrieves the value of a field relative to the current field's state path. The state path is like a "dot notation" path to the field's value in the form's data array.
Example Structure
Suppose your form schema looks like this:
Wizard\Step::make('Module')
->schema([
ModuleSelector::make('module'),
Select::make('field')
->options(function ($get) {
// ...
}),
])
If you do not wrap your fields in a Group, Repeater, or any other container, then both module and field exist at the same level in the state array. In this case, $get('module') should work.
When does $get('../../module') become necessary?
If your fields are nested inside another component (like a Repeater, Group, or a custom component that changes the state path), then the current field's state path is deeper, and you need to use ../ to go up a level.
$get('module')looks formoduleinside the current state path.$get('../../module')goes up two levels and then looks formodule.
For example:
If your Select::make('field') is inside a Repeater, its state path might be items.0.field, so $get('module') would look for items.0.field.module (which doesn't exist), while $get('../../module') would go up to items.module.
How to make $get('module') work
Ensure that both fields are at the same level in your schema.
If you want $get('module') to work, make sure that ModuleSelector::make('module') and Select::make('field') are siblings in the schema array, not nested inside different containers.
Example (should work):
Wizard\Step::make('Module')
->schema([
ModuleSelector::make('module'),
Select::make('field')
->options(function ($get) {
$moduleName = $get('module');
if (!$moduleName) return [];
return ModuleEnum::fromName($moduleName)->getDisplayFields();
}),
])
Example (will NOT work with $get('module')):
Wizard\Step::make('Module')
->schema([
Group::make([
ModuleSelector::make('module'),
]),
Select::make('field')
->options(function ($get) {
$moduleName = $get('module'); // This will be null
}),
])
Here, module is inside a Group, so its state path is group.module, but field is at the root. You'd need to use $get('group.module') or adjust your structure.
How does $get('../../module') work?
The ../ notation moves up one level in the state path. So $get('../../module') moves up two levels and then looks for module. This is useful when your field is deeply nested.
Summary Table
| Field Structure | How to Access module from field |
|---|---|
| Both at root | $get('module') |
| Both inside same Group | $get('module') |
field nested, module root |
$get('../../module') (or more ../ as needed) |
In Short
- Use
$get('module')when both fields are at the same level. - Use
$get('../../module')when your field is nested and you need to go up to access the value. - Check your schema structure to determine the correct path.
Debugging Tip
You can always dd($getStatePath()) inside your options closure to see the current field's state path and figure out how many ../ you need.
->options(function ($get, $set, $state, $getStatePath) {
dd($getStatePath());
// ...
})
If you want $get('module') to work, make sure both fields are at the same level in your schema. Otherwise, use ../ to go up as needed.
Let me know if you need a more specific example based on your actual schema!