Improve the Views Form API

Created on 29 June 2013, over 11 years ago
Updated 6 February 2025, 17 days ago

Views Form is an odd and ugly API.

Its basic purpose is to allow field handlers to output form elements, and then validate / process the submission.
An example of this is a quantity textfield or delete button on each row of the Commerce cart view.

Some handlers also add form elements above or below the view, with VBO being the primary example (with its operation selector). This is either done through a form_alter() or through the views_form() method on the handler (BulkForm handlers currently in core).

VBO is also unique in the sense that it adds additional steps to the forms, so after items are selected, the form is rebuilt and a configuration form or confirmation form are shown, with the original view completely hidden.
Even though the original view is not shown in that case, it is still executed and rendered, because of the way Views Form works.
Basically, every field handler outputs a placeholder, and then when the View is being rendered, a form is rendered from the collected views_form() methods, and pieces of that form are then inserted instead of the placeholders (str_replace).

Here's what I think needs to be done to make the API better:
1) Views Form needs to stop explicitly adding action buttons to the form.
This should be the job of the field handler.
Most handlers, including the BulkForm ones unset those buttons in many / all cases, I think about 90% of the implementations go against that.

2) The API still supports setting a "views_form_callback" on the handler, this was added explicitly for editablefields, and should be dropped.

3) The Views Form handlers should implement an interface with getFormPlaceholder() and form() methods. There should also be a base class that provides default getFormPlaceholder() and render() methods, so that field handlers don't need to.
Then views_view_has_form_elements() can check if a field implements that interface, instead of checking for the existence of a method, which is super-ugly and not core worthy.

4) The placeholder format needs to change, it is currently an html comment:

<!--form-item-' . $this->options['id'] . '--' . $this->view->row_index . '-->

This creates numerous problems with sanitization and filtering, and the decision even in D7 views has been to change it to resemble a real token.
[form-element:handler_id:10] would correspond to $form['handler_id'][10], for instance.
This would also allow us to drop the ugly form_element_row_id() and form_element_name() methods, since the placeholder would be enough to map itself to a form structure.

5) Area handlers can be views form handlers, but they don't have placeholders, making them pretty useless. They are also not used by any known public implementation. They should either be removed, or preferably just extended to support placeholders (possible due to changes in #4)

6) views_form, views_form_views_form, views_form_validate, views_form_submit need to be converted to a form controller, matching the rest of core.

7) The instantiation of the form controller should be done by ViewsExecutable. The name of the form controller should stored in a property, and changeable by a method. This means that a field handler could override the form controller to use with its own one.

This means that a BulkForm / VBO handler could provide its own controller (that extends the default one), with an additional method that outputs the "configure action" form step.
The current architecture would mean that all additional form steps would be in procedural form callbacks while the main form step and the validation / submission would be in the views form handler, so that split is not pretty.

The only imposed limitation here is that only one field handler could override the main form controller and have additional steps. I think this makes sense and represents the current situation correctly (nobody has done multiple handlers all providing their own form steps, the multistep functionality is only used by VBO and Views Send at the moment)

8) It would be great to try and move the form controller calling / views form building from the theme function to ViewsExecutable::render(), allowing additional form steps to bypass views execution and rendering altogether, instead of just hiding what was already built.

I am going to be rolling a patch tomorrow morning, and we can split things into individual issues as needed (since we have all kinds of issues here: bug reports, removal of undocumented and unused parts of the API, form controller conversions, performance improvements..)

πŸ“Œ Task
Status

Postponed: needs info

Version

11.0 πŸ”₯

Component

views.module

Created by

πŸ‡·πŸ‡ΈSerbia bojanz

Live updates comments and jobs are added and updated live.
  • VDC

    Related to the Views in Drupal Core initiative.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Thank you for creating this issue to improve Drupal.

    We are working to decide if this task is still relevant to a currently supported version of Drupal. There hasn't been any discussion here for over 8 years which suggests that this has either been implemented or is no longer relevant. Your thoughts on this will allow a decision to be made.

    Since we need more information to move forward with this issue, the status is now Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.

    Thanks!

Production build 0.71.5 2024