Optional modal in an action

Hello, I am wondering if it is possible to have an optional modal in an action of a form. I have a products database and all products have ingredients. I have some logic to connect all the ingredients to the product. Sometimes I need to present a form when it is not clear which ingrediënten needs to be connected. This should be an optional form. I am wondering if this is possible and looking for an approoach on how to do this. Thanks.
5 Replies
Povilas Korop
Povilas Korop3w ago
I'm not sure I understand the flow: so there should be a form WHERE exactly? Inside the form, as a button to open modal to add a few fields? And what is the DB relationship between ingredients and products, can you provide the data example?
JJSanders
JJSandersOP3w ago
So inside my form page I have an action. When I click on the action it wil run some code and based on the outcome of the code it could be that I need to present a form form more information.
<?php

class ConnectIngredientsAction extends Action
{
use InteractsWithRecord;

protected function setUp(): void
{
parent::setUp();

$this->label('Ingredienten Koppelen')
->icon('heroicon-o-link')
->requiresConfirmation()
->modalHeading('Ingredienten Koppelen')
->modalDescription('Deze actie zal de ingrediënten uit de tekst opsplitsen en proberen te koppelen aan de ingrediënten relatie.')
->modalSubmitActionLabel('Koppelen')
->action(function (Product $record) {
// For Simplicity I left some code out
// Process ingredients without duplicates
$this->processIngredients($product, $resultParameter);
})
->visible(fn (Product $record): bool => ! empty($record->ingredients_text));
}


private function showDuplicateIngredientsModal(): void
{
$duplicateNames = $this->duplicateIngredients->map(function ($group) {
return $group->pluck('name')->join(', ');
})->join(' | ');

// Show detailed information about duplicate ingredients
$duplicateDetails = $this->duplicateIngredients->map(function ($group, $index) {
$ingredients = $group->map(function ($ingredient) {
return "ID: {$ingredient->id} - {$ingredient->name}";
})->join(', ');

return 'Groep '.($index + 1).": {$ingredients}";
})->join('\n');

//HERE IS Where I want to show my form if $dubplicateDetails and $duplicateNames are not empty. The form content needs
// to be generated dyamically based on the $duplicateNames and $duplicateDtails
}

}
<?php

class ConnectIngredientsAction extends Action
{
use InteractsWithRecord;

protected function setUp(): void
{
parent::setUp();

$this->label('Ingredienten Koppelen')
->icon('heroicon-o-link')
->requiresConfirmation()
->modalHeading('Ingredienten Koppelen')
->modalDescription('Deze actie zal de ingrediënten uit de tekst opsplitsen en proberen te koppelen aan de ingrediënten relatie.')
->modalSubmitActionLabel('Koppelen')
->action(function (Product $record) {
// For Simplicity I left some code out
// Process ingredients without duplicates
$this->processIngredients($product, $resultParameter);
})
->visible(fn (Product $record): bool => ! empty($record->ingredients_text));
}


private function showDuplicateIngredientsModal(): void
{
$duplicateNames = $this->duplicateIngredients->map(function ($group) {
return $group->pluck('name')->join(', ');
})->join(' | ');

// Show detailed information about duplicate ingredients
$duplicateDetails = $this->duplicateIngredients->map(function ($group, $index) {
$ingredients = $group->map(function ($ingredient) {
return "ID: {$ingredient->id} - {$ingredient->name}";
})->join(', ');

return 'Groep '.($index + 1).": {$ingredients}";
})->join('\n');

//HERE IS Where I want to show my form if $dubplicateDetails and $duplicateNames are not empty. The form content needs
// to be generated dyamically based on the $duplicateNames and $duplicateDtails
}

}
Povilas Korop
Povilas Korop3w ago
mm, I see the point now - check something and open the modal almost as a warning that something is wrong. Yeah, I won't have the immediate answer, would need to experiment to be able to answer. Maybe will find time later, but can't promise sorry.
JJSanders
JJSandersOP3w ago
I will also try and experiment further. If I find a solution I will post it here.
LeandroFerreira
maybe replaceMountedAction ?
public function connectIngredientsAction(): Action
{
return Action::make('connectIngredients')
->requiresConfirmation()
->action(function () {

$ingredients = [
['id' => 1, 'name' => 'Sugar'],
['id' => 2, 'name' => 'Salt'],
['id' => 3, 'name' => 'Flour'],
];

if ($ingredients) {
$this->replaceMountedAction('showDuplicateIngredients', arguments: [
'ingredients' => $ingredients,
]);
}
});
}

public function showDuplicateIngredientsAction(): Action
{
return Action::make('showDuplicateIngredients')
->record(fn (array $arguments) => $arguments ?? [])
->schema([
RepeatableEntry::make('ingredients')
->columns(2)
->schema([
TextEntry::make('id'),
TextEntry::make('name'),
]),
])
->action(function () {});
}
public function connectIngredientsAction(): Action
{
return Action::make('connectIngredients')
->requiresConfirmation()
->action(function () {

$ingredients = [
['id' => 1, 'name' => 'Sugar'],
['id' => 2, 'name' => 'Salt'],
['id' => 3, 'name' => 'Flour'],
];

if ($ingredients) {
$this->replaceMountedAction('showDuplicateIngredients', arguments: [
'ingredients' => $ingredients,
]);
}
});
}

public function showDuplicateIngredientsAction(): Action
{
return Action::make('showDuplicateIngredients')
->record(fn (array $arguments) => $arguments ?? [])
->schema([
RepeatableEntry::make('ingredients')
->columns(2)
->schema([
TextEntry::make('id'),
TextEntry::make('name'),
]),
])
->action(function () {});
}

Did you find this page helpful?