Problem/Motivation

For certain usecases, especially embeddded forms inside forms, you want to fire submit handlers similar to the way validation can be done on every element.

Proposed resolution

A typical usecase if inline entity forms. You have a form with multiple subentity forms in there. For each, you want to be able to have an easy way to just submit one of the entities inside. #element_submit allows you to do that.

On top of that, once you have more than one subform for example, you also want to be able to limit the possible elements you want to submit. Just think of a form with two embedded entity forms, each with its own submit button. On every Submit button, you want to just validate and submit their corresponding form elements. Therefore this patch introduces #limit_element_submit, similar to #limit_validation_errors.

Remaining tasks

User interface changes

None

API changes

Two new FAPI Element properties
#element_submit
#limit_element_submit

Data model changes

None

CommentFileSizeAuthor
#120 2820359-120.patch11.51 KB_utsavsharma
#117 interdiff_110-117.txt1.83 KBberliner
#117 2820359-117.patch16.92 KBberliner
#117 2820359-117-test-only.patch10.02 KBberliner
#110 interdiff_108-110.txt2.16 KBMeenakshi_j
#110 2820359-110.patch17.17 KBMeenakshi_j
#108 2820359-element_submit-108.patch17.17 KBberliner
#102 interdiff-100-102.txt724 bytesczigor
#102 2820359-element_submit-102.patch17.65 KBczigor
#100 2820359-element_submit-100.patch17.61 KBczigor
#2 2820359-2.patch3.63 KBdawehner
#5 introduce-2820359-5.patch1.02 KBjibran
#9 introduce-2820359-9.patch4.65 KBjibran
#11 interdiff.txt6.94 KBjibran
#11 introduce-2820359-11.patch7.19 KBjibran
#23 interdiff.txt7.98 KBjibran
#23 introduce-2820359-23.patch12.97 KBjibran
#30 2820359-30.patch11.61 KBdawehner
#31 interdiff-30-31.txt3.15 KBjofitz
#31 2820359-31.patch11.6 KBjofitz
#33 interdiff-31-33.txt1.27 KBjofitz
#33 2820359-33.patch11.59 KBjofitz
#36 2820359-36.patch16.37 KBdawehner
#36 interdiff-2820359.txt9.65 KBdawehner
#37 2820359-37.patch18.75 KBdawehner
#37 interdiff-2820359.txt6.08 KBdawehner
#40 interdiff-2820359.txt1.89 KBdawehner
#40 2820359-40.patch17.75 KBdawehner
#46 2820359-46.patch15.12 KBdawehner
#46 interdiff-2820359.txt4.89 KBdawehner
#52 2820359-52.patch18.55 KBdawehner
#52 interdiff-2820359.txt5.05 KBdawehner
#54 2820359-54.patch18.67 KBdawehner
#54 interdiff-2820359.txt2.04 KBdawehner
#57 interdiff-2820359.txt3.48 KBdawehner
#57 2820359-57.patch18.71 KBdawehner
#61 2820359-61.patch19.44 KBphenaproxima
#61 interdiff-2820359-57-61.txt6.06 KBphenaproxima
#66 form-element-submit-2820359-66.patch19.38 KBvasi1186
#66 interdiff-2820359-61-66.txt2.04 KBvasi1186
#70 2820359-70.patch19.37 KBjofitz
#70 2820359-66-70.txt781 bytesjofitz
#73 2820359-73.patch19.33 KBamateescu
#73 interdiff-73.txt1.15 KBamateescu
#81 2820359-81.patch19.78 KBmichaellander
#81 interdiff-73-81.txt2.16 KBmichaellander
#83 interdiff-81-83.txt10.94 KBczigor
#83 2820359-element_submit-83.patch17.5 KBczigor
#86 2820359-element_submit-86.patch17.54 KBczigor
#86 interdiff-83-86.txt1.94 KBczigor
#88 interdiff-86-88.txt660 bytesczigor
#88 2820359-element_submit-88.patch17.55 KBczigor
#91 2820359-element_submit-91.patch17.6 KBczigor
#93 2820359-element_submit-93.patch20.44 KBczigor
#95 2820359-element_submit-95.patch17.64 KBczigor
#99 interdiff.txt800 byteskpv
#97 2820359-element_submit-97.patch17.63 KBczigor
#99 2820359-element_submit-99.patch17.61 KBkpv
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dawehner created an issue. See original summary.

dawehner’s picture

jibran’s picture

Status: Active » Needs review
+++ b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php
@@ -44,6 +44,33 @@ protected function setUp() {
+      '#element_submit' => [[$mock, 'element_validate']],

Shouldn't it be 'element_submit'?

Status: Needs review » Needs work

The last submitted patch, 2: 2820359-2.patch, failed testing.

jibran’s picture

Status: Needs work » Needs review
FileSize
1.02 KB

Here is a first stab.

jibran’s picture

+++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
@@ -47,6 +48,14 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
+      if (isset($form[$key]) && $form[$key] && isset($form[$key]['#element_submitter'])) {

s/element_submitter/element_submit :/

Fabianx’s picture

Issue tags: +Needs backport to D7

I think we might be able to backport this to Drupal 7. Tentatively adding the tag for that.

dawehner’s picture

@jibran
Do you want to give it a try and combine the actual patch and the test one together?

jibran’s picture

Status: Needs review » Needs work

The last submitted patch, 9: introduce-2820359-9.patch, failed testing.

jibran’s picture

Status: Needs work » Needs review
FileSize
6.94 KB
7.19 KB

I hope this will be green.

larowlan’s picture

looks good to me

phenaproxima’s picture

+++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
@@ -47,6 +48,18 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
+            &$form_state,

Why does $form_state need to be passed by reference? It's an object, so won't it be passed by reference anyway?

jibran’s picture

One of the key-points of PHP 5 OOP that is often mentioned is that "objects are passed by references by default". This is not completely true.

Source: http://php.net/manual/en/language.oop5.references.php

phenaproxima’s picture

Fair enough. Seems harmless to pass it by reference, but based on what I'm reading in the documentation, it looks like passing it as a normal value will have the same effect. So it comes down, apparently, to style.

I'm trying to find things wrong with this patch, but I can't. It looks as elegant and well-tested as it is simple. I'm not sure I'm qualified to mark this RTBC, but I can't wait for it to land!

One tiny question:

+++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
@@ -47,6 +48,18 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
+      if (isset($form[$key]) && $form[$key] && isset($form[$key]['#element_submit'])) {

Not a big deal at all, but wouldn't just isset($form[$key]['#element_submit']) suffice here?

tim.plunkett’s picture

No, objects are not passed by reference, they are passed as an object identifier. This allows you to manipulate it as though it were a reference, except in one case: you cannot replace the object with a new one.

Internals of FormBuilder/FormValidator/FormSubmitter still explicitly pass &$form_state, including #element_validate. But they shouldn't need to, and we shouldn't add that here without good reason.

So let's please remove the & from $form_state.

Also it doesn't need to be split over so many lines.

jibran’s picture

Internals of FormBuilder/FormValidator/FormSubmitter still explicitly pass &$form_state, including #element_validate. But they shouldn't need to, and we shouldn't add that here without good reason.

I was just following the prior practice.

So let's please remove the & from $form_state.

I disagree, either we remove it from everywhere or just go with the old convention. It is easier to remember this way. I don't want to end up like array_map array_filter scenario.

Also it doesn't need to be split over so many lines.

It is split because I was trying to avoid 'If the line declaring an array spans longer than 80 characters, each element should be broken into its own line' PHPCS error.

jibran’s picture

Not a big deal at all, but wouldn't just isset($form[$key]['#element_submit']) suffice here?

This is copied from \Drupal\Core\Form\FormValidator::doValidateForm()

tstoeckler’s picture

+++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
@@ -2,6 +2,7 @@
@@ -47,6 +48,18 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {

@@ -47,6 +48,18 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
+    foreach (Element::children($form) as $key) {

doSubmitForm() is not called recursively so this will only call #element_submit callbacks on top-level elements. This is very non-standard and makes it fairly useless for complex forms.

Am I missing something?

dawehner’s picture

@tstoeckler Great point! I also thin conceptually code which executes submit handlers should be inside \Drupal\Core\Form\FormSubmitter::executeSubmitHandlers somehow, as well, this is what the method name says.

tim.plunkett’s picture

#17, I do NOT think we should block this on another issue, and I don't think we should introduce a new API in a known-broken way just because other parts of core are wrong.

I did open #2831312: Remove obsolete pass-by-reference of $form_state though :)

jibran’s picture

Status: Needs review » Needs work

Thanks for creating the issue. I'll address #21 and #19 later today.

jibran’s picture

Status: Needs work » Needs review
FileSize
7.98 KB
12.97 KB

Addressed #21 and #19.

dawehner’s picture

Status: Needs review » Needs work

The test we have should have a ['#element_submit'] deep down the tree, so we ensure it actually works.

phenaproxima’s picture

Found a few nitpicks, as is my wont:

  1. +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
    @@ -98,6 +85,47 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
    +   * @param $elements
    

    Missing type hint.

  2. +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
    @@ -98,6 +85,47 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
    +  protected function submitFormElement(&$elements, FormStateInterface &$form_state, $form_id = NULL) {
    

    $elements is also missing a type hint.

  3. +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
    @@ -98,6 +85,47 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
    +
    +    // Recurse through all children.
    

    Small nit -- unnecessary blank line.

  4. +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
    @@ -98,6 +85,47 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
    +      if (isset($elements[$key]) && $elements[$key]) {
    

    If $elements[$key] is a truthy scalar, this will pass. The second check should maybe be is_array($elements[$key])?

  5. +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
    @@ -98,6 +85,47 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
    +        call_user_func_array($form_state->prepareCallback($callback), array(&$elements, $form_state, &$complete_form));
    

    Nit: Can this use [] syntax instead?

The last submitted patch, 23: introduce-2820359-23.patch, failed testing.

jibran’s picture

Feel free to address #25 and #24. I'm not activily working on this anymore.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

dawehner’s picture

FileSize
11.61 KB

Here is a quick reroll.

jofitz’s picture

Status: Needs work » Needs review
FileSize
3.15 KB
11.6 KB

Addressed @phenaproxima's nitpicks from #25.

Still need to respond to @dawehner's comment in #24 - can you explain what you mean, please?

Status: Needs review » Needs work

The last submitted patch, 31: 2820359-31.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

jofitz’s picture

Status: Needs work » Needs review
FileSize
1.27 KB
11.59 KB

Introduced some fundamental errors there, this looks more promising - not changing the method parameters.

bojanz’s picture

One thing we'll need to add is introduce some kind of #limit_element_submit array that does for submit what #limit_validation_errors does for validation.

Imagine a form with two inline forms A and B. We might want to submit form B without running #element_submit for form A.

dawehner’s picture

I agree once you have more than one submit button on the page you need to be able to limit the element to submit, just like its really common to limit the validation once you have multiple submit buttons. A typical example is inline entity form, you want to be able to just validate and submit the inner entity.

The other question though is: Should this be done here, or is this rather a followup question. For consistency I think it belongs here.

I'm currently reworking the test coverage to be more in line with other parts of the modern form tests ...

dawehner’s picture

This moves the test into its own dedicated class, outside of validation.

dawehner’s picture

This adds now limitation of the submitting.

The last submitted patch, 36: 2820359-36.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Status: Needs review » Needs work

The last submitted patch, 37: 2820359-37.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

dawehner’s picture

Status: Needs work » Needs review
FileSize
1.89 KB
17.75 KB

I don't understand the second test failure. This

jibran’s picture

Status: Needs review » Needs work

The last submitted patch, 40: 2820359-40.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

tim.plunkett’s picture

validate => submit
#limit_validation_errors => #limit_submission_errors

Ignore this!
With #limit_validation_errors, validation still runs, and some errors are ignored.

With #limit_element_submit, we are actually preventing the submit code from running. So the name makes sense!

dawehner’s picture

@jibran
Can you explain why you added the $form_id parameter in #23? If you think about it, we could call the element level submit handlers all the time and then get rid of the parameter in total.

jibran’s picture

I just copied it from \Drupal\Core\Form\FormValidator::doValidateForm other than that there is no reason for this.

dawehner’s picture

Title: Introduce #element_submit similar to #element_validate » Introduce #element_submit similar to #element_validate; Add #limit_element_submit
Issue summary: View changes
Status: Needs work » Needs review
Issue tags: -Needs issue summary update, -Needs title update
FileSize
15.12 KB
4.89 KB

This gets rid of the $form_id parameter as its entirely useless here :)
I still don't really know why this fails, given it works quite fine on my local system.

Status: Needs review » Needs work

The last submitted patch, 46: 2820359-46.patch, failed testing. View results

jibran’s picture

Title: Introduce #element_submit similar to #element_validate; Add #limit_element_submit » Add #element_submit and #limit_element_submit just like #element_validate and #limit_validation_errors
Issue tags: +Needs documentation updates

Thanks for updating the summary. We have to update FAPI doc pages on d.o also ElementInfoManagerInterface::getInfo, Button, and FormElement need docs update.

jibran’s picture

Issue summary: View changes
tim.plunkett’s picture

+++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
@@ -85,6 +86,64 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
+  protected function submitFormElement(array &$elements, FormStateInterface &$form_state, $limit_element_submit = []) {
...
+        $this->submitFormElement($elements[$key], $form_state, NULL, $limit_element_submit);
...
+    $this->executeSubmitHandlers($elements, $form_state);

Oh, duh. I looked at ::doValidateForm() and realized why we need $form_id (or any optional param):

::validateForm() calls ::doValidateForm() and passes the $form_id. This triggers a call to ::executeValidateHandlers().

Then ::doValidateForm() itself calls ::doValidateForm(), recursing through the form. But without passing the $form_id through.

This ensures that the form-level handlers only run once per form, not once per element.

This raises the larger question: why differentiate between #validate and #element_validate, or #submit and #element_submit?

dawehner’s picture

Oh, duh. I looked at ::doValidateForm() and realized why we need $form_id (or any optional param):

::validateForm() calls ::doValidateForm() and passes the $form_id. This triggers a call to ::executeValidateHandlers().

Then ::doValidateForm() itself calls ::doValidateForm(), recursing through the form. But without passing the $form_id through.

For now we have extracted the recursive aspect in its own function: submitFormElement. It feels like this is the better pattern. One less condition, a clearer path of execution ...

This raises the larger question: why differentiate between #validate and #element_validate, or #submit and #element_submit?

I tried to trace back when #element_validate was introduced. It was introduced back in 2007 #138706: FormAPI 3: Ready to rock.

Apparently the reasoning was:

#validate (with two wildly different use cases) is now #validate and #element_validate

4. "#validate (with two wildly different use cases) is now #validate and #element_validate" -- care to explain this a bit more? Maybe with an example? When you say #element_validate, do you mean a form element definition rather than a form element value? The word 'element' is particularly vague and I'd prefer to use something more self-explanatory (widget?) if we can't think of something. (The code comment for both are identical and do not properly explain the difference.)

In the current formAPI, top-level #validate functions placed at the top level of the form receive $form_values, as one would expect. #validate functions placed below there, on specific sub-elements, DO NOT receive $form_values, but a full copy of the $form. The reason? form elements (like password_confirm) need to be able to check their own fields, but if they're deeply nested in a form structure, they may not even appear in a consistent location because of how #tree operates. One solution would be to make every #validate function receive both $form_values and $form, and leave it up to the developer to figure out when #tree has messed up the values collection for them. Instead, we felt it would be better to make the separation in use cases explicit, reserving #validate for the entire form, and #element_validate (with its special needs) for individual form elements. That also makes #validate consistent with #submit, which can also only be set at the top level of the form.

Explaining that #validate and #submit can be set for an entire form in 'normal' form-building situations, and that programmers implementing custom form elements can specify element-specific validation code with #element_validate, is easier IMO than trying to explain why a validate function receives totally different arguments depending on where it's placed in the form.

I think the receiving different arguments points is a good one. Its actually the same for this #element_submit case.

dawehner’s picture

Status: Needs work » Needs review
Issue tags: -Needs documentation updates
FileSize
18.55 KB
5.05 KB

I think I adapted the necessary bits of documentation now.

Status: Needs review » Needs work

The last submitted patch, 52: 2820359-52.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

dawehner’s picture

Status: Needs work » Needs review
FileSize
18.67 KB
2.04 KB

Ha, I forgot something specific ... the $form_id bit was all over not calling the submit handlers multiple times.

Status: Needs review » Needs work

The last submitted patch, 54: 2820359-54.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

tim.plunkett’s picture

  1. +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
    @@ -46,9 +47,10 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
    -    $this->executeSubmitHandlers($form, $form_state);
    ...
    +    $this->executeSubmitHandlers($elements, $form_state);
    

    What is $elements?

  2. +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
    @@ -46,9 +47,10 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
    +    $this->submitFormElement($form, $form_state, isset($triggering_element['#limit_element_submit']) && $triggering_element['#limit_element_submit'] !== FALSE ? $triggering_element['#limit_element_submit'] : []);
    

    Please please move that ternary onto it's own line

  3. +++ b/core/modules/system/tests/src/Functional/Form/ElementSubmitTest.php
    @@ -0,0 +1,59 @@
    +
    +  ¶
    +
    

    Bunch of new lines/whitespace

  4. +++ b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php
    @@ -44,6 +44,39 @@ protected function setUp() {
    +    $form_submitter = $this->getMockBuilder('Drupal\Core\Form\FormSubmitter')
    ...
    +      ->with($this->isType('array'), $this->isInstanceOf('Drupal\Core\Form\FormStateInterface'), $this->isType('array'));
    

    Nit: use ClassName::class

dawehner’s picture

#56
Thank you for reviewing this patch quickly!

1. Seriously PHP, this reference of a potential undefined variable is kinda crazy
2. Sure
3. Clean it thank you!
4. Fair :)

dawehner’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 57: 2820359-57.patch, failed testing. View results

dawehner’s picture

  1. +++ b/core/lib/Drupal/Core/Form/FormState.php
    @@ -23,7 +23,7 @@ class FormState implements FormStateInterface {
    -   * #process, #after_build, #element_validate, and other handlers being invoked
    +   * #process, #after_build, #element_validate, #element_submit and other handlers being invoked
        * on a form element may use this reference to access other information in the
    

    > 80 chars

  2. +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
    @@ -85,6 +88,62 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
    +   */
    +  protected function submitFormElement(array &$elements, FormStateInterface &$form_state, $limit_element_submit = []) {
    +    // Recurse through all children.
    +    foreach (Element::children($elements) as $key) {
    +      if (isset($elements[$key]) && is_array($elements[$key])) {
    +        $this->submitFormElement($elements[$key], $form_state, NULL, $limit_element_submit);
    +      }
    

    We need to document the order of execution for these calls, inside out or outside in ...

phenaproxima’s picture

Status: Needs work » Needs review
FileSize
19.44 KB
6.06 KB

Okay -- this makes the test pass on my localhost. Hopefully Drupal CI will agree.

Also fixed #60.1.

Status: Needs review » Needs work

The last submitted patch, 61: 2820359-61.patch, failed testing. View results

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

vasi1186’s picture

The patch looks pretty good, I also gave it a try and it worked good for me, also the tests pass locally.
I only have some very small things to report, all of them related to coding style (and actually some of them appear also in the other parts of the Drupal core itself).

  1. +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
    @@ -85,6 +88,62 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
    +   *   handlers can also $form_state to pass information on to submit handlers.
    

    Nit pick: seems like a type in the comment, it should be 'can also use $form_state'

  2. +++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
    @@ -85,6 +88,62 @@ public function doSubmitForm(&$form, FormStateInterface &$form_state) {
    +   *   This technique is useful when validation requires file parsing,
    

    This line seems to be way bellow 80 characters. The same for the next one.

  3. +++ b/core/lib/Drupal/Core/Render/Element/Button.php
    @@ -15,6 +15,9 @@
    + *   #element_submit executions. A typical usecase could be a an form with
    

    Another nit pick: seems like a typo: "could be a an form".

vasi1186’s picture

I fixed the small issues from 66, but do not really understand what is needed for 60.2.

vasi1186’s picture

Status: Needs work » Needs review
phenaproxima’s picture

Status: Needs review » Needs work

Tests are still failing, so this still needs work :)

vasi1186’s picture

@phenaproxima that's quite strange, don't know why they are failing. I've run the same tests locally and they work just fine... Any ideas?

jofitz’s picture

Status: Needs work » Needs review
FileSize
19.37 KB
781 bytes

I too am unable to obtain the error messages (but I've corrected the coding standards error).

I have gone down the rabbit hole and found that in this case Tests/WebAssert.php:77 calls ElementNotFoundException($this->session,... when it should be passing $this->session->getDriver(). In this file there are multiple examples of both, some were corrected as part of #2961691: Change SYMFONY_DEPRECATIONS_HELPER back to strict, but I'm not sure why all of them weren't. I suspect this bug needs it's own ticket, but I'm not sure I understand it enough to create the ticket!

The last submitted patch, 66: form-element-submit-2820359-66.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

Status: Needs review » Needs work

The last submitted patch, 70: 2820359-70.patch, failed testing. View results

amateescu’s picture

Status: Needs work » Needs review
FileSize
19.33 KB
1.15 KB

Fixed the failing test and the group name of that test class.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

michaellander’s picture

Status: Needs review » Reviewed & tested by the community

I've tested this patch using '#element_submit' on this issue #3037221: Block forms are submitted prematurely. It is glorious. Looking at recent comments here, I think it's good to RTBC.

tstoeckler’s picture

Status: Reviewed & tested by the community » Needs review

Something I don't see being covered in the tests is an element with an #element_submit property that also has a child which itself has an #element_submit property.

As far as I can tell it should work in the way that the form will be submitted inside out - which makes sense, I think - but it would be good to have explicit test coverage of that.

Pancho’s picture

Also, I think we should reconsider the naming, to make sure it is consistent, at least logically.

In #43, @tim.plunkett raised the question of consistency, however figured out that:

With #limit_validation_errors, validation still runs, and some errors are ignored.
With #limit_element_submit, we are actually preventing the submit code from running.

Still, if the counterpart to #element_validate is #element_submit,
the counterpart to #limit_validation_errors should be #limit_submission, not #limit_element_submit.

rgpublic’s picture

Still, if the counterpart to #element_validate is #element_submit,
the counterpart to #limit_validation_errors should be #limit_submission, not #limit_element_submit.

You meant "#limit_submission_errors", I suppose? I'd agree with that...

michaellander’s picture

I think they meant #limit_submission as they said because to @tim.plunkett's point earlier, we are limiting submission, instead of limiting some errors from showing. Personally, I think #limit_element_submit is actually the best name for it, though I don't think #limit_submission is bad either, especially as I don't see us renaming #limit_validation_errors anytime soon.

@tstoeckler I think that's a good idea. From what I can tell, it's submitting as expected through children, but adding test coverage wouldn't hurt.

Pancho’s picture

Indeed, I suggested #limit_submission.

Unfortunately, I currently don’t have time to dig into #370537: Allow suppress of form errors (hack to make "more" buttons work properly) (name decision in #171 there), nor into #763376: Not validated form values appear in $form_state, but it seems the latter is a bug and it was originally intended not to submit unvalidated values anyway.

So instead of introducing more properties, we could possibly just fix that bug? On the other hand, the bug could have become a feature over all the years.

Not sure though if the better solution would be this or a toggle/modification of #limit_validation_errors, though.

michaellander’s picture

Here is a version that tests a parent #element_submit with a child #element_submit. It does not however test the order in which they are executed.

@tstoeckler is this what you had in mind?

dawehner’s picture

I'm not sure where, but it would be quite nice to expand some existing documentation, like /Users/dawehner/www/d8/core/lib/Drupal/Core/Form/FormBuilderInterface.php to include this additional functionality in the overviewing documentation.
There it would be nice to describe when do which function run (inside out or outside in for example).

czigor’s picture

FileSize
10.94 KB
17.5 KB

1. I think the documentation is in its right place in Button, FormElement and ElementInfoManagerInterface. This follows the #element_validation and #limit_validation_errors practice. Added some fixes there.
2. Removed the excessive NULL argument from the recursive submitFormElement() call. (Not sure how the tests passed before though.)
3. Changed text matches to regexp matches in tests so that we test the execution order too.
4. Made the tests a bit more compact by using a universal submit callback for all elements.

czigor’s picture

Status: Needs review » Reviewed & tested by the community

5. Also removed some &s from before $form_states.
6. #element_submit docs now say "The execution order in the form array is bottom to top."

I think all raised concerns have been addressed. Let's RTBC this.

bojanz’s picture

Status: Reviewed & tested by the community » Needs review

Was 60.2 ("document the order of execution for these calls, inside out or outside in") addressed? Doesn't look like it at a glance.

+    // Call any element-specific submit handlers. These must act on the element
+    // #value data.

The second sentence that was used for #element_validate, copied here, but is it equally correct? At this point we have form state values that we can use too.

+ * - #element_submit: (array) Array of callables or function names, which
+ *   are called to submit the input. Arguments: $element, $form_state, $form.
+ *   The execution order in the form array is bottom to top.

"submit the input" sounds a bit odd, perhaps "submit the element"?

I'd love to get a final +1 from dawehner before RTBC.

czigor’s picture

  1. Was 60.2 ("document the order of execution for these calls, inside out or outside in") addressed?

    This is meant to be that part:
    + * The execution order is bottom to top in the form array.

  2. The second sentence that was used for #element_validate, copied here, but is it equally correct?

    We pass $element, $form_state, $form to the #element_submit callbacks, yes. (Don't know why $form is needed, since it's available in $form_state, if that's the question.)

  3. "submit the input" sounds a bit odd, perhaps "submit the element"?

    Agreed, fixed.

bojanz’s picture

One additional tricky thing to consider: #limit_validation_errors is an array of #parents, but #limit_element_submit is an array of #array_parents.
Not the same thing. And even our own docs get it wrong in one place:

+   * @param array $limit_element_submit
+   *   An array of form element #parents arrays to limit element level
+   *   submitting to.
czigor’s picture

Fixed docs.

To me #array_parents feels a bit better choice since all levels are always available that way (in case you can't control #tree for some reason). Of course we can't change #limit_validation_errors now. In a follow-up issue we could emphasize this difference.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

jhedstrom’s picture

Status: Needs review » Needs work

Patch failed to apply in #88.

czigor’s picture

Status: Needs work » Needs review
FileSize
17.6 KB

Reroll.

Status: Needs review » Needs work

The last submitted patch, 91: 2820359-element_submit-91.patch, failed testing. View results

czigor’s picture

Status: Needs work » Needs review
FileSize
20.44 KB

Status: Needs review » Needs work

The last submitted patch, 93: 2820359-element_submit-93.patch, failed testing. View results

czigor’s picture

Trying to fix tests.

czigor’s picture

Status: Needs work » Needs review
czigor’s picture

Status: Needs review » Needs work

The last submitted patch, 97: 2820359-element_submit-97.patch, failed testing. View results

kpv’s picture

czigor’s picture

Status: Needs work » Needs review
FileSize
17.61 KB

Status: Needs review » Needs work

The last submitted patch, 100: 2820359-element_submit-100.patch, failed testing. View results

czigor’s picture

Status: Needs work » Needs review
FileSize
17.65 KB
724 bytes

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

geek-merlin’s picture

Yes, still needed a lot.

geek-merlin’s picture

Working in IEF into that direction. Let's start with an overview and consolidation ticket.

berliner’s picture

Just updated the last patch to apply on Drupal 9.1.10, not sure at what version it started to not properly apply anymore.

Status: Needs review » Needs work

The last submitted patch, 108: 2820359-element_submit-108.patch, failed testing. View results

Meenakshi_j’s picture

Status: Needs work » Needs review
FileSize
17.17 KB
2.16 KB

Fixed the fails of #108

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

jonathanshaw’s picture

Has the test coverage requested in #76 been added?

geek-merlin’s picture

Status: Needs review » Needs work

There are tests in the patch.

We need to prove it covers the new code though, with a test-only patch.
(Anti-Mess: If someone can take this simple task, please attach the test-only patch first, then the full patch second, to your comment.)

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

berliner’s picture

Re-rolled for 10.1 and extracted a test-only patch from #110.

berliner’s picture

Status: Needs work » Needs review
smustgrave’s picture

Status: Needs review » Needs work

May need to be rerolled for 11.x

Also was tagged for change record which still believe is needed.

_utsavsharma’s picture

Rerolled patch for 11.x