Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The dependsOn is not working in the field inside Flexible #524

Open
kennethtomagan opened this issue Sep 2, 2024 · 9 comments
Open

The dependsOn is not working in the field inside Flexible #524

kennethtomagan opened this issue Sep 2, 2024 · 9 comments

Comments

@kennethtomagan
Copy link

I want to change the Price field value depends on Product field, sane field is inside Flexible
but dependsOn is not working.

Flexible::make('Order items')
    ->addLayout('Select Products', 'product', [
        Select::make('Product')
            ->options(Product::all()->pluck('name', 'id'))
            ->displayUsingLabels()
            ->searchable(),
        Text::make('Price')
        ->dependsOn(["product"], function (Text $field, NovaRequest $request, FormData $formData) {
                if ($formData->product) {
                    $productId = $formData->product;
                    $product = Product::find($productId);
                    $field->withMeta(['value' => $product->price]);
                }
        }),
    ])
    ->button('Add Product')
    ->fullWidth()
    ->limit(10),

anyone encounters this error? how do you guys solve it?

@daanadriaan
Copy link

Anyone found a solution?

@nzmattman
Copy link

i have the same issue
i wonder if it may have to do with the nested json when selecting the fields it depends on

@lucasff
Copy link

lucasff commented Oct 16, 2024

this is the same issue the parent dependsOn and official Nova Repeatable item is suffering.

@kennethtomagan kennethtomagan changed the title THe dependsOn is not working in the field inside Flexible The dependsOn is not working in the field inside Flexible Oct 17, 2024
@matthbon
Copy link

I also have this issue. Want to have dependant fields inside the Flexible. But it isn't working.

@kennethtomagan
Copy link
Author

I also have this issue. Want to have dependant fields inside the Flexible. But it isn't working.

Right now, I do it by creating a custom field and put it inside Flexible.
In my custom field I create a JS functionality to get the value of dependents field.

It's a bit complicated so I hope it will be fixed sooner.

@daanadriaan
Copy link

Right now, I do it by creating a custom field and put it inside Flexible. In my custom field I create a JS functionality to get the value of dependents field.

@kennethtomagan Snippet?

@matthbon
Copy link

I also have this issue. Want to have dependant fields inside the Flexible. But it isn't working.

Right now, I do it by creating a custom field and put it inside Flexible. In my custom field I create a JS functionality to get the value of dependents field.

It's a bit complicated so I hope it will be fixed sooner.

@kennethtomagan a snippet would be nice?

@editho512
Copy link

editho512 commented Nov 12, 2024

I had the same problèm, it was due to fields names that automatically crypted by flexible content in order to always have differente names per content. it was something like ckOi67sYIRR0L6kh__entityId.
My temporary solution is to create middleware that remove the crypted part of the fields names 'ckOi67sYIRR0L6kh__entityId for 'creation-fields and update-fields nova api routes . and create hidden fields same as the fields that dependent of another one in the Nova resource that call my flexible content that really handle the dependency callbacks.
that workes perfectly for me .

`class TransformFlexibleNovaFieldNames
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
// Liste des modèles d'URL avec préfixes et suffixes
$urlPatterns = [
['prefix' => 'nova-api/pages', 'suffix' => 'creation-fields'],
['prefix' => 'nova-api/pages', 'suffix' => 'update-fields'],
];

    // Construire des expressions régulières basées sur les modèles d'URL
    $regexPatterns = array_map(function ($pattern) {
        $prefix = preg_quote($pattern['prefix'], '/');
        $suffix = preg_quote($pattern['suffix'], '/');
        // Rendre la partie "/\d+" optionnelle
        return "/^{$prefix}(\/\d+)?\/{$suffix}$/";
    }, $urlPatterns);

    // Vérifier si l'URL correspond à l'un des modèles
    $isMatchingUrl = false;
    foreach ($regexPatterns as $regex) {
        if (preg_match($regex, $request->path())) {
            $isMatchingUrl = true;
            break;
        }
    }


    // Si l'URL correspond à l'un des patterns
    if ($isMatchingUrl && $request->has('field')) {
        $sanitizeFields = function ($fields) {
            $sanitized = [];
            foreach ($fields as $key => $value) {
                if (strpos($key, '__') !== false) {
                    $newKey = substr($key, strpos($key, '__') + 2);
                    $sanitized[$newKey] = $value;
                } else {
                    $sanitized[$key] = $value;
                }
            }
            return $sanitized;
        };

        $field = $request->get('field');

        if (strpos($field, '__') !== false) {
            $newField = substr($field, strpos($field, '__') + 2);
            $request->query->set('field', $newField);
        }

        if ($request->post()) {
            $sanitizedPost = $sanitizeFields($request->post());
            $request->replace($sanitizedPost);
        }
    }
    
    return $next($request);
}

}`

in my flexbile content layout

Boolean::make(__("Sélectionner tous les badges de l'émetteur"), 'is_all_badges') ->hide() ->dependsOn( ['entityId'], function (Select $field, NovaRequest $request, FormData $formData){} ),

In my Nova resource that class my flexbile content

Boolean::make(__("Sélectionner tous les badges de l'émetteur"), 'is_all_badges') ->hideFromIndex() ->hide() ->dependsOn( ['entityId'], function (Boolean $field, NovaRequest $request, FormData $formData){ if($formData->entityId){ $field->hide(); } else { $field->show(); } } ),

@daanadriaan
Copy link

@editho512 Works like a charm! Exactly what i was looking for! 🤩🥳

I was looking for a MorphTo solution. Solved it based on your middleware:

Resource:

class BlogResource extends Resource {
  
  public function fields(Request $request): array {
    return [
      Flexible::make('Content', 'content')
        ->addLayout(Content::class)
        ->addLayout(ReadMore::class),
      // This is the placeholder for showing blogs list
      Select::make('Blog', 'blog_id')
        ->hide()
        ->hideFromIndex()
        ->options(fn() => Blog::pluck('title', 'id')->toArray())
        ->searchable()
        ->dependsOn( ['model_type'], function (Select $field, NovaRequest $request, FormData $formData) use ($class){
            if($formData->model_type && $formData->model_type === $class){ $field->show(); } else { $field->hide(); }
        }),
      // This is the placeholder for showing pages list
      Select::make('Page', 'page_id')
        ->hide()
        ->hideFromIndex()
        ->options(fn() => Page::pluck('title', 'id')->toArray())
        ->searchable()
        ->dependsOn( ['model_type'], function (Select $field, NovaRequest $request, FormData $formData) use ($class){
            if($formData->model_type && $formData->model_type === $class){ $field->show(); } else { $field->hide(); }
        });
    ];
  }
}

And then my ReadMore flexible block:

class ReadMore extends Layout {
  public function fields(): array {
    Select::make('Type', 'model_type')
                    ->options([
                        Blog::class       => 'Blog',
                        Page::class        => 'Page'
                    ])
                    ->required(),
    Select::make('Blog', 'blog_id')
                ->hide()
                ->resolveUsing(fn ($resource, $model) => $model->model_id)
                ->fillUsing(function ($request, $model) {
                    if($request->blog_id) {
                        $model->model_id = $request->blog_id;
                    }
                })
                ->dependsOn( ['model_type'], function (Select $field, NovaRequest $request, FormData $formData){}),
    Select::make('Page', 'page_id')
                ->hide()
                ->resolveUsing(fn ($resource, $model) => $model->model_id)
                ->fillUsing(function ($request, $model) {
                    if($request->page_id) {
                        $model->model_id = $request->page_id;
                    }
                })
                ->dependsOn( ['model_type'], function (Select $field, NovaRequest $request, FormData $formData){});
  }
}

It took me a few minutes to understand that pages was the resource, so make sure to replace 'pages' for 'your-own-resources':

  ['prefix' => 'nova-api/your-own-resources', 'suffix' => 'creation-fields'],
  ['prefix' => 'nova-api/your-own-resources', 'suffix' => 'update-fields'],
];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants