Skip to content

[Form] Views of compound forms without children are not considered rendered #17580

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

Closed
backbone87 opened this issue Jan 27, 2016 · 10 comments
Closed

Comments

@backbone87
Copy link
Contributor

Well the title says it all.

{{ form_start(form) }}
  {{ form_errors(form) }}
  {% for subForm in form.components %}
    {{ form_row(subForm) }}
  {% else %}
    no components
  {% endif %}
{{ form_end(form) }}

If form.components is empty, it is not considered as rendered at the time form_end is called, causing its "container" markup to be rendered. This is especially annoying when you have expanded choices with an empty array of choices.

This is partly related to: #17579

@backbone87
Copy link
Contributor Author

@webmozart can you review this? if my proposed behavior gets accepted, i can provide a PR for it

@webmozart
Copy link
Contributor

Thank you for reporting this issue @backbone87! :)

if my proposed behavior gets accepted

I don't find any information related to that in your description? What behavior do you propose?

@backbone87
Copy link
Contributor Author

always consider compound forms that have no children as rendered

idk, if this has any other implications, obviously its a behavior change and could alter the rendering results of existing code.

@webmozart
Copy link
Contributor

@backbone87 This is already the case (see https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/FormView.php#L70). Your problem is that your form contains a child, namely "components". That child is never rendered though.

Your problem can be fixed by passing the render_rest option to form_end():

{{ form_end(form, {'render_rest': false}) }}

I don't think there's anything we can fix on our side.

@backbone87
Copy link
Contributor Author

@webmozart Its about inconsistency: using the tpl code from the OP, we observe 2 cases:

  • form.components has children (the for loop gets called for each of them and output them with form_row): form_end will just close the form tag, because it considers form.components to be rendered, because form.components is compound and all children are rendered.
  • form.components has no children (the for loop gets not called and the else branch is executed): form_end will render form.components and close the form tag, because it considers form.components not to be rendered, but the condition form.components is compound and all children are rendered still applies.

ok that description wasnt as good as i expected. ok, lets try this with another one:
the current check of isRendered: rendered flag is set OR (form has at least one child AND each child is rendered)
my proposed check: rendered flag is set OR (form is compound AND each child is rendered)

if form is not empty, both checks always return the same bool. but if the form is an empty compound form my check will consider it rendered, while the current one doesnt.

@backbone87
Copy link
Contributor Author

a similar reasoning for checking compound vs. checking number of children is given here:
https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/Form.php#L549

@backbone87
Copy link
Contributor Author

compare this to: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Form/FormView.php#L68

my proposed change:

    public function isRendered()
    {
        if ($this->rendered) {
            return true;
        }

        if (!$this->vars->compound) {
            return false;
        }

        foreach ($this->children as $child) {
            if (!$child->isRendered()) {
                return false;
            }
        }

        return $this->rendered = true;
    }

@webmozart
Copy link
Contributor

@backbone87 Sounds reasonable. The change should only affect form_rest() (or form_end()) statements, which aren't commonly used to render rows in the first place, so the implication on existing applications should be minimal.

@backbone87
Copy link
Contributor Author

and update on this?

@HeahDude
Copy link
Contributor

the current check of isRendered: rendered flag is set OR (form has at least one child AND each child is rendered)
my proposed check: rendered flag is set OR (form is compound AND each child is rendered)

@backbone87 It seems that @webmozart said that it "sounds reasonable" so please open a PR :)

backbone87 added a commit to backbone87/symfony that referenced this issue Sep 28, 2016
backbone87 added a commit to backbone87/symfony that referenced this issue Sep 28, 2016
backbone87 added a commit to backbone87/symfony that referenced this issue Sep 28, 2016
fabpot added a commit that referenced this issue Sep 29, 2016
…d rendered implicitly (backbone87)

This PR was merged into the 2.7 branch.

Discussion
----------

[Form] compound forms without children should be considered rendered implicitly

| Q             | A
| ------------- | ---
| Branch?       | 2.7
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | possibly
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #17580
| License       | MIT
| Doc PR        | n/a

Commits
-------

8234f2a #17580 compound forms without children should be considered rendered implicitly
@fabpot fabpot closed this as completed Sep 29, 2016
fabpot added a commit that referenced this issue Sep 30, 2016
* 2.7:
  [TwigBundle] Fix CacheWarmingTest are order dependent
  Revert "bug #20080 [Form] compound forms without children should be considered rendered implicitly (backbone87)"
  #17580 compound forms without children should be considered rendered implicitly
fabpot added a commit that referenced this issue Oct 1, 2016
* 2.8:
  [TwigBundle] added missing dependencies for tests
  fixed CS
  [TwigBundle] Adjust CacheWarmingTest for TemplateCacheWarmer introduced in 2.8
  [TwigBundle] Fix CacheWarmingTest are order dependent
  Revert "bug #20080 [Form] compound forms without children should be considered rendered implicitly (backbone87)"
  Fix #19943 Make sure to process each interface metadata only once
  #17580 compound forms without children should be considered rendered implicitly
fabpot added a commit that referenced this issue Oct 1, 2016
* 3.1:
  [TwigBundle] added missing dependencies for tests
  fixed CS
  adding missing dep
  [TwigBundle] Adjust CacheWarmingTest for TemplateCacheWarmer introduced in 2.8
  [TwigBundle] Fix CacheWarmingTest are order dependent
  Revert "bug #20080 [Form] compound forms without children should be considered rendered implicitly (backbone87)"
  [2.7][VarDumper] Fix PHP 7.1 compat
  [2.8][VarDumper] Fix PHP 7.1 compat
  silent file operation to avoid open basedir issues
  Fix #19943 Make sure to process each interface metadata only once
  #17580 compound forms without children should be considered rendered implicitly
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants