Variable inside forms Action->action are stuck to first iteration, when I'm creating it in foreach
I'm trying to make dynamic action button generation for multiple situation (based on type). But for some reason all buttons generated by this snippet are leading to a "One Image" case. What interesting - all image have their heroicon and label, so foreach actually generates multiple buttons, but with absolutely same action. How can I parse necessary type ($key) inside ->action()? ''' // 1) Combine labels & icons in one array:
$elementTypes = [
'oneimage' => ['label' => 'One Image', 'icon' => 'heroicon-m-photo'],
'text' => ['label' => 'Text', 'icon' => 'heroicon-m-document-text'],
'quote' => ['label' => 'Quote', 'icon' => 'heroicon-m-chat-bubble-bottom-center-text'],
'h2' => ['label' => 'Heading 2', 'icon' => 'heroicon-m-hashtag'],// and others...
];
$actions = [];
foreach($elementTypes as $key => $type)
{
$actions[] = Action::make('addElement{$key}')
->label($elementTypes[$key]['label'])
->icon(fn (Get $get) => $elementTypes[$key]['icon'] ?? 'heroicon-m-plus')
->action(function (Set $set, Get $get) use ($elementTypes, $key) {
$items = $get('elements') ?? [];
$type = $key;
$items[] = [
'type' => $type,
'value' => null,
'sort' => count($items),
];
$set('elements', $items);
$set('newElementType', null);
$key = null;
});
}
'''

Solution:Jump to solution
It's likely because your action name is enclosed in single quotes so the $key is not being treated as a variable. Try:
...
5 Replies

Solution
It's likely because your action name is enclosed in single quotes so the $key is not being treated as a variable. Try:
But wouldn't actually the ToggleButtons component be a better fit for what you're trying to do?
https://filamentphp.com/docs/3.x/forms/fields/toggle-buttons
Yes, quotes helped! Why it's always some small peace you can't notice after 9h coding π . Thank You! Nope, Toggle buttons not really what i need. I'm making Page constructor, so when button is pressed new element appears and you can press as much those elements as you wish.
