Score:0

Creating a form in a custom views field

cn flag

I am working on a bit of functionality that allows a 'form' to be embedded in a custom views field on a view I am working on.

The view is a table list of 'request' entities. The very last column in the table for each row is a 'quick edit' form, that has a custom form with a few fields on it (depending on the entity displayed in the current row). I am trying to figure out how to build a custom views plugin/field that will let me render a working form. I know how to do the logic to show the needed fields conditionally, and know how to build a normal form, but I am not sure how to build one into a views field.

I used `drush generate plugin-views-field' and I can render form elements in the render() method, but they don't actually do anything as a form isn't actually generated.

Would it be easier/possible to create a form inside module/src/Form (that accepts additional arguments), and render that form using formBuilder->getForm() or is there a way I can build and render the form inside of a views plugin?

The form needs to work via ajax, so that you can make the quick-edit without reloading the page.

Any help would be greatly appreciated.

According to the comments below, it looks like I can do something like:

$form = \Drupal::formBuilder()->getForm('Drupal\resume\Form\WorkForm');
$form->sub_id = id;
return $form;

To render the form, and then inside the formbuilder use the sub_id variable to attach it to the ajax callback and wrapper element.

Score:1
cn flag

Yes, for a Drupal form you need a form class processed by FormBuilder. You can place the resulting form build anywhere on the page, views fields are not different from other page elements like for example blocks. Tricky in your case is to have multiple instances of the same form on the page. Then you need unique form IDs, ajax wrappers and submit elements. See Using the same form more than once per page with AJAX callbacks

Also be aware that Views Ajax and Form API Ajax have different endpoints and using both together adds more to the complexitiy. See Enabling AJAX in Views breaks Form API AJAX button (Drupal 8)

Ex0r avatar
cn flag
Yes, my plan was to allow the formbuilder to accept additional arguments that would be passed into the form at the views field level, which would be passing the unique entity id (one per row) to the form so I could build the form id as #form-<id> and set the wrapper element scorrectly based on the passed in parameters. The views ajax and form ajax are something I haven't considered yet. I was thinking the form ajax would just just run behind the scenes like normal and trigger/rebuild the form when it needed to.
4uk4 avatar
cn flag
This sounds like a good plan. BTW in this case you can't pass form parameters via the build method. For the form ID you need to inject the parameter before invoking the form builder as shown in the linked topic. As long as you don't enable Ajax in Views you can ignore the second part.
Ex0r avatar
cn flag
Updated the question to reflect your changes. Does that seem right? Additionally, there is views ajax on the page, but it's using the views_expandable_table module to expand/collapse the last column of each table row into an additional row. I am not sure if it will interfere with the form ajax or not but I will try it out. Additionally additionally, I do not know how to update the table row once the form is actually submitted (the form is capable of updating a few values listed in the appropriate table row as a column).
4uk4 avatar
cn flag
In the ajax callback you can update any part of the page, also outside of the form. - In your edited question you didn't use the correct code example from the linked topic by the way, you have to inject the parameter before invoking FormBuilder. [FormBuilder::getForm()](https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Form%21FormBuilder.php/function/FormBuilder%3A%3AgetForm) accepts both, a form class name or an already instantiated form object.
Ex0r avatar
cn flag
That seems counter-productive. Doesn't formBuilder->getForm() create an instantiated class of the form? I guess I don't understand why you first have to instantiate a class via another method when the formbuilder is already creating an instantiated object. I'll give it a try though.
Ex0r avatar
cn flag
I ended up doing some testing, and what you linked ended up working. I still need to figure out how to re-trigger the views query to run again on ajax callback for the specified row, but I can work on that after the form is working. Thank you!
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.