0

I have a pretty complex process that combines two Drupal forms--1 widget form and 1 normal form.

The first form (WidgetForm that extends the ImageWidget form) will allow the user to open a modal to view some images, like Entity Browser but populated via 3rd party API. I render the form using the following snippet:

$modal_form = \Drupal::formBuilder()->getForm('Drupal\my_module\Form\ModalForm');

Simple enough, our extended WidgetForm adds a button to 'Browse' images and if clicked, we get a render array and I shove that into an OpenModalDialogCommand and return that so it opens a modal with my form inside. This works no problem.

The ModalForm form allows the user to browse through images, paginate them, search, etc. However, when I want to update my WidgetForm, i'm having difficulty rebuilding the $form_state. Thus, when I submit the form, it is using an outdated $form_state and doesn't recognize that I've tried to manually insert values into the $form array. I know the following is sufficient data b/c I can populate it on the initial form build with session variables (but the UX is completely messed up if I rely on this process). But since I want this to be all within the same page request, I don't want to rely on refreshing the page.

$element['#value']['fids'][] = $fid;
$element['#value']['target_id'] = $fid;
$element['#display_default'] = TRUE;
$element['fids']['#value'] = [
  $fid,
];

Above, we insert the $fid into some form fields. If we do this on the initial page load, it works fine (as I mentioned above). When I try to do this in my ajax callbacks, it doesn't update the $form_state. So I've tried to save it as session variables and set $form_state->setRebuild(TRUE) in the validate/submit callbacks so that it will call my build step again which has logic to check for session variables. If I set $form_state->setRebuild(TRUE) anywhere in my ModalForm, it will only rebuild the $form_state for my ModalForm, not my WidgetForm. So we arrive at my problem--I cannot seem to find a way to update the $form_state of my WidgetForm.

I've also tried to save the pure $form_state object as a session variable and then update it when necessary but this is not working.

// At the end of my formElement() function on my field widget form
$session = new Session(); // Symfony session
$session->set('my_module.image_widget_form_state', $form_state); // save the $form_state object

// Later in my other form...
$image_widget_form_state = $session->get('my_module.image_widget_form_state');
$image_widget_form_state->setValue('fids', [$fid]); // attempt to update $form_state at a later stage from within a different form

So it seems my problem is that I'm trying to update the $form_state of an active form within an ajax callback propagated by a completely different form. In other words, I need to update the $form_state of my WidgetForm from within my ModalForm. Both forms can be 'active' at the same time but ultimately, the WidgetForm needs to be dynamically updated based on actions taken from within the ModalForm.

Also related but not necessarily the main point of this question--despite my best efforts to rebuild the form on pertinent steps, it seems that I'm running into the bug where the #name property disappears and then the Form thinks that every single button is a submit button (when most of the buttons are simply a means to trigger an ajax callback). Would anyone know how to prevent this from happening?

  • 1
    I don't think the session approach is a good idea, but then use the session from the request, don't create a new session object. Using subforms you could have different forms in one $form_state by the way. But I'm not sure about what you are trying to do, because a field widget needs an entity and nested entity forms build out of referenced entities. You didn't mention anything of that. – 4k4 Jul 23 at 21:30
  • Yes the field widget is for a media entity. The ModalForm will import an image from a 3rd party API as a new media item. I forgot that subforms were a thing, I might look into that and try to combine the forms together. Session approach was mostly to try and reach a proof of concept, but the barrier seems to be updating $form_state. I know the data I'm inserting is sufficient b/c I tested it via sessions but the problem is that I'm not updating $form_state so it doesn't persist on save. – cchoe1 Jul 23 at 23:53
  • Essentially, my field widget is the same as the ImageWidget except I've added a button that opens up a modal (my 2nd form) which allows a user to import images from a service like dropbox. I extend the image widget so I have access to the preview that it provides, the field settings like max resolution, max file size, etc. – cchoe1 Jul 23 at 23:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.