Skip to content

Conversation

@stakovicz
Copy link

Q A
Bug fix? no
New feature? yes
Tickets Fix #3
License MIT

Handle form collections, add & remove buttons

Copy link
Member

@weaverryan weaverryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm super excited that someone has taken this in - it will be a huge win! I have one major comment that discusses direction on this feature. Btw, don't hesitate to ping me in Symfony's slack if you'd like to discuss in real time :)

```
You have 2 different themes :
- `@FormCollection/form_theme_div.html.twig`
- `@FormCollection/form_theme_table.html.twig`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the biggest question make for me with this very nice PR. If we provide a built-in form theme to "rendering everything for them", then we will also need a Bootstrap 4/5 theme... and a tailwind theme. And, if the user needs to customize how things look, then they need to override a fairly complex form theme that we've created here.

I'm not definitely against this. However, I'd like to see if we can document how this new feature could be used if there were no form themes included. For example,

Now that your BlogFormType form set up and with a comments field that is a CollectionType, you can
render it in your template:

{% macro commentFormRow(commentForm) %}
    <div
        class="col-4"
        data-symfony--ux-form-collection--collection-target="entry"
    >
        {{ form_errors(commentForm) }}
        {{ form_row(commentForm.content) }}
        {{ form_row(commentForm.otherField) }}

        <a data-action="symfony--ux-form-collection--collection#delete">
            Remove
        </a>
    </div>
{% endblock %}

<div
    class="row"
    {{ stimulus_controller('symfony/ux-form-collection/collection', {
        prototype: _self.commentFormRow(form.comments.vars.prototype),
    }) }}
>
    {% for commentForm in form.comments %}
        {{ _self.commentFormRow(commentForm) }}
    {% endfor %}

    <a data-action="symfony--ux-form-collection--collection#add">
        Add Another
    </a>
</div>

This would give me full control over everything, including the buttons. The Stimulus controller would just handle making it all work :). The worst pieces are the super-ugly data-action and data-...-target attributes. But this would look much nicer if we merged symfony/webpack-encore-bundle#124

There may be some other missing pieces... but in theory, this should be enough to work. The "delete" button should not need a data-index-entry attribute, as we can look to its ancestors for the "closest" entry target to know which item is being removed.

So, this is my thinking :). No form theme, but we make it as dead-simple as possible for users to render things themselves.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My idea was to make a component very easy to use.
It's true that template overloading can be complicated due to attributes related to Stimulus.
With these 2 templates (@FormCollection/form_theme_div.html.twig, @FormCollection/form_theme_table.html.twig) we cover a maximum of use cases.

For your proposal, there should be explicit errors when the controller is wrong or the action is not correctly entered.

I think you need to know Stimulus to be able to set up HTML according to the documentation.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make a better judgement, I'll need some time to play with this in a real project :). Would you be willing/able to push a demo app to GitHub that uses this (with some quick setup instructions)?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you have my repo for my test :
https://github.com/stakovicz/ux-collection-test/
Enjoy !

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've made an update.
Now you can use a predefined theme or not.
You have the choice.

I need help to do more tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @weaverryan,

Any reason to use a macro instead of a proper form theme here?

The macro forces you to use it everywhere it's needed (eg. prototype & entries as in your example) while a "real" form theme would apply automatically to both.

@stakovicz
Copy link
Author

Thanks @weaverryan, for taking the time to the review.
I'm intimidated by you because I know you through SymfonyCast ;-)

This is my first contribution, but you are all very kind to help me!

@weaverryan
Copy link
Member

Thanks @weaverryan, for taking the time to the review.
I'm intimidated by you because I know you through SymfonyCast ;-)

Well, I'm happy to know you know too ;)

This is my first contribution, but you are all very kind to help me!

It's a very big feature for a first contribution - nice work!

@tgalopin
Copy link
Contributor

tgalopin commented May 8, 2021

Hi @stakovicz !

Thanks very much for your PR, as Ryan I'm quite excited by this as it's a major requirement for Symfony Forms.

I think, as Ryan mentioned, the only point where I think we need to spend some time thinking is how templates are handled (ie. what HTML is generated). Generally speaking, Symfony as a framework has helpers that generate several HTML tags (like in forms) but usually these helpers become more complex to work with than the original HTML. This was the reasoning behind https://symfony.com/blog/new-in-symfony-5-2-form-field-helpers for instance: use inline attribute helpers instead of tags helpers.

Perhaps your solution is the best, I don't know yet as I didn't have a deep look into it, but it' worth spending some time: it will have a huge impact on developer experience.

I'll have a deeper look asap :) .

Copy link
Author

@stakovicz stakovicz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @tgalopin!

Thank you for your look.

Indeed, I am divided.
On the one hand, the solution that I propose allows an almost instantaneous use.
On the other hand, your solution is very flexible and allows maximum customization.

You know the community better than I do.
You also have a lot more experience.
I trust you in the final choice and you will follow.

Comment on lines 53 to 101
'button_add' => [
// Default text for the add button
'text' => 'Add',
// Add HTML classes to the add button
'class' => 'btn btn-outline-primary'
],
'button_delete' => [
// Default text for the delete button
'text' => 'Remove',
// Add HTML classes to the add button
'class' => 'btn btn-outline-secondary'
],
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@weaverryan I'm not sure how to refactor these defaults values for the same project.
When using an HTML framework, the classes are always the same for buttons (for example).

Copy link

@maxhelias maxhelias May 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure but have you tried with 2 ButtonType in the Form when the options "allow_add" & "allow_delete" are true?
This would allow to modify their appearance via the twig blocks

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@maxhelias allow_add is a boolean type from the original FormType.

Copy link
Contributor

@jmsche jmsche left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,

As my knowledge about JavaScript is pretty much not existent, I reviewed the PR but only for PHP, Twig & docs :)

My main goals with this review are (as explained in the review):

  • Putting the default translations in the Form Type rather than in the templates
  • Having 4 distinct options with allowed types, instead of two arrays with no types at all
  • Docs: form theme instead of macros

Thanks for your PR! :)

@zmitic
Copy link

zmitic commented Jun 5, 2021

@stakovicz
First I want to thank you for doing this. I have projects with deeply nested collections, this addition is more than welcome,


I have one question about the problem I encountered few times and suggested jquery.collection plugin suffered from it; I had to make my own implementation because of that.

TL;DR
Will it be possible to affect how the index is increased in this line?

Or better: a way to set base index not as the number of existing, but for example seconds since Unix epoch?

Reason, click to expand

Imagine editing (create is not a problem) a form with a collection that has 3 Users.

So Symfony renders them with keys 0, 1, 2.

Now you delete all of them and add new User. Submitted array to the server will only have key 3; so far it is good, Symfony knows you deleted first 3 and added new one.

Here comes the problem. Validation fails and the form is rendered again, with that one user (the new one). You add 2 new users but instead of creating keys 4 and 5, the suggested Symfony plugin will reset keys.

The problem is that now backend will think that data has been updated (because submitted keys are the same as when form was first created), and not know that old users were deleted and new ones were created.

Keys are very important here; default mapper is sort-of doing some bypass by searching for objects (mostly entities) but I have more extreme cases.

I solved it by making the base index not to be the count of existing elements, but the seconds of the current time. Submitted data has big keys but no problem since that.

Any thoughts?

@stakovicz
Copy link
Author

@zmitic

First I want to thank you for doing this. I have projects with deeply nested collections, this addition is more than welcome,

Thanks a lot !

...
Any thoughts?

OK I see the problem. I watch what I can do.

@stakovicz
Copy link
Author

@zmitic this commit allow you to set the default index :
8b23e78

The value is set automatically if you use a predefined theme.

@zmitic
Copy link

zmitic commented Jun 6, 2021

@stakovicz Perfect! I will find a way to override it, still didn't figure that for Stimulus.

Thank you.

@stakovicz
Copy link
Author

@weaverryan @tgalopin do you have any feedback ?

@jorismak
Copy link

jorismak commented Jun 18, 2021

To be honest, I tried making - ahem, for my self - some re-usable javascript code to handle Collections.
But every time I try to use it, my use case for a Collection is slightly different, and I end up customizing a lot anyway.

The HTML changes per project (sometimes only widgets in a table, sometimes a 'normal' bootstrap horizontal form, then again something different, then the keys are numeric and have no meaning, then the keys are identifiers which need to be precise, etc...).

Now aboard the Stimulus hype-train, I have a simple 'collection_controller' that handles the add-button and delete-button code. With a delete-button with a data-action= attribute and a simple data-remove-key= attribute, I have enough that all my everytime-it-is-slightly-different templates can work.

I make a macro that handles a single child of the collection. That macro is then also usable to render a prototype string (simply calling the macro in an html-attribute will escape it properly) and for me it's easier to write a small template for the collection-at-hand then try to make a 'one size fits all template'.

So personally, I wouldn't bother with trying to come up with some template-style that fits all... because it never will in my experience.

Include a 'simple' piece of form theme that uses existing form_row() and form_label() so that it is as generic as possible, but make sure the stimulus controller doesn't depend on it hard. And include a little bit of 'demo' template for people whishing to do it their way.

This way Symfony has - ahem, finally - working out-of-the-box javascript for Collections :), but it's still easy enough for people who know how to customize a collection to use a partial-twig as form-theme and just render it there how they see fit.

Copy link
Contributor

@ker0x ker0x left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @stakovicz for this work. I have taken inspiration from what you did to build my own custom collection type with some improvements.

I also made some feedback 😉

For those who are interested, here is a gist of my current implementation: https://gist.github.com/ker0x/8a1bad79a22f0ebae9ddf28c264dd13f

{
$resolver->setDefaults([
'button_add_text' => 'Add',
'button_add_class' => '',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will renamed this key button_add_attr to allow user to set multiple attributes to the Add button and use the attribute block available in the form_theme to build them. Same for the button_delete_class

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

@ker0x ker0x Jul 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed it's better, gist updated! Thanks 😉

@seb-jean
Copy link
Contributor

I am interested :)

@seb-jean
Copy link
Contributor

Hi,

With example below, data-ux-form-collection-prototype-value is badly encoded because there is html_attr on value : https://github.com/symfony/webpack-encore-bundle/blob/main/src/Twig/StimulusTwigExtension.php#L69

{% macro commentFormRow(commentForm) %}
    <div
        class="col-4"
        data-symfony--ux-form-collection--collection-target="entry"
    >
        {{ form_errors(commentForm) }}
        {{ form_row(commentForm.content) }}
        {{ form_row(commentForm.otherField) }}

        <a data-action="symfony--ux-form-collection--collection#delete">
            Remove
        </a>
    </div>
{% endblock %}

<div
    class="row"
    {{ stimulus_controller('symfony/ux-form-collection/collection', {
        prototype: _self.commentFormRow(form.comments.vars.prototype),
    }) }}
>
    {% for commentForm in form.comments %}
        {{ _self.commentFormRow(commentForm) }}
    {% endfor %}

    <a data-action="symfony--ux-form-collection--collection#add">
        Add Another
    </a>
</div>

@tgalopin
Copy link
Contributor

Hello @stakovicz

Sorry for the delayed answer, I didn't have much time to work on UX lately. I plan to spend more time on it in the coming weeks.

As Ryan explained, I think we need to find a way to tackle the templating, especially for custom needs. I'll have a look at your example repository and see if there are interesting ideas we could have.

Copy link
Contributor

@alexander-schranz alexander-schranz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would really like to see something like this in the symfony/ux component. Would just look that add and remove buttons are rendered using symfony form theme. I added a few comments about it.

/cc @weaverryan @tgalopin what do you think about them?

@@ -0,0 +1,52 @@
{%- block button_add -%}
{%- set attrDataAction = (attr['data-action']|default('') ~ ' ' ~ controllerName ~ '#add')|trim -%}
<button data-action="{{ attrDataAction }}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be better if we can use the exist button_widget block:

https://github.com/symfony/symfony/blob/41697e78a158156952f8c445512f11bd58f90958/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig#L224

Maybe we can use in the Form Builder the ButtonType and then give it also a special block_prefix so we can go with collection_button_add_widget to overwrite it.

So we could go with:

'button_add_options => [
    'label' => 'app.button_add',
    'label_translation_parameters' => [],
    'attr' => ['class' => '...']
],

This make it possible to use any of the exist button options and would be easier for theming also for future themes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, this is interesting. To accomplish this, I think it would be very similar to how prototype is done, which is sort of a "fake field" that is added to the form... without being a real field.

You can see how the prototype is created in buildForm()... but not actually added to the field: https://github.com/symfony/symfony/blob/a05702965e9fc0de7ce77d1641e772e2fbfe9911/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php#L39-L40

Later, it's added as a view variable: https://github.com/symfony/symfony/blob/a05702965e9fc0de7ce77d1641e772e2fbfe9911/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php#L91-L101

It would be interesting to do the same thing with both buttons. We would pass button_add_options directly to the $builder->create() call - e.g. how prototype_options are passed here: https://github.com/symfony/symfony/blob/a05702965e9fc0de7ce77d1641e772e2fbfe9911/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php#L33

<div data-controller="{{ dataController }}"
data-{{ controllerName }}-allow-add-value="{{ allow_add|json_encode }}"
data-{{ controllerName }}-allow-delete-value="{{ allow_delete|json_encode }}"
data-{{ controllerName }}-button-add-value="{{ block('button_add')|e('html_attr') }}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think we should go here with form_widget(button_add_prototype).

We can create the button add prototype this way:

// build form
$prototype = $builder->create('button_add', ButtonType, array_merge(['block_prefix' => 'collection_add_button'], $options['button_add_options']));
$builder->setAttribute('button_add_prototype', $prototype->getForm());

// build view
if ($form->getConfig()->hasAttribute('button_add_prototype')) {
    $prototype = $form->getConfig()->getAttribute('button_add_prototype');
    $view->vars['button_add_prototype'] = $prototype->setParent($form)->createView($view);
}

This is similar how the prototype of the collection itself is created:

https://github.com/symfony/symfony/blob/41697e78a158156952f8c445512f11bd58f90958/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php#L39-L40

https://github.com/symfony/symfony/blob/6.1/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php#L64-L67

This way we make sure the button using the form theme and we can use button_widget or collection_add_button_widget to overwrite it the Theme way of symfony forms.

{% set startIndex = indexKeys|length == 0 ? 0 : max(indexKeys) %}

<div data-controller="{{ dataController }}"
data-{{ controllerName }}-allow-add-value="{{ allow_add|json_encode }}"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find -allow-add-value and button-add-value confusing. I think I would just go with button-add-prototype. If it is set there is add if not there is no add else it could be confusing that I can set the prototype but its not used.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I'm personally missing is a -button-remove-target-selector. So I can adjust were the ux javascript will render target the button.

@mario-fehr
Copy link

@stakovicz any progress on this to finish it? Would love to use this.

@weaverryan
Copy link
Member

I like @alexander-schranz's ideas, and I think if we can implement those, I would support this. @stakovicz you've done a lot of great work on this, but we've been slow to review. Are you still able/interested to finish this?

Thx :)

@stakovicz
Copy link
Author

Yes, I'm in !
I think can do the last changes.

Copy link
Member

@weaverryan weaverryan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @stakovicz!

I just had an opportunity to put this to the test on a local project - I really enjoyed it! I like how you have built both an automatic feature (just render the "form row" and everything is added automatically) but also an "escape hatch" where you can render all of the part of the collection field manually, but still take advantage of the Stimulus controller.

I've left some feedback: I think we just need to smooth out some technical details and this will be ready. I'm really excited for it :).

Cheers!

"symfony/framework-bundle": "^4.4.17|^5.0",
"symfony/phpunit-bridge": "^5.2",
"symfony/twig-bundle": "^4.4.17|^5.0",
"symfony/var-dumper": "^4.4.17|^5.0"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should all be updated to ^5.4|^6.0

]
},
"require": {
"php": ">=7.2.5",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change to "php": ">=8.0", and then we can update code accordingly (e.g. using property promotion, etc). We could even bump to 8.1 if necessary, but it looks like you got things working on 7.2, so 8.0 should, hopefully, be easy enough :).

@@ -0,0 +1,190 @@
# UX Form Collection
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're now doing this as an index.rst file. So, it just needs to move, then convert to RST

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see any RST files in the other parts 🤨. They are all in .md

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your branch may be a little out-of-date, see eg. https://github.com/symfony/ux/tree/2.x/src/Chartjs/Resources/doc

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I had not looked in this file 😬

@@ -0,0 +1,190 @@
# UX Form Collection

Symfony UX Form collection is a Symfony bundle providing light UX for collection
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Symfony UX Form collection is a Symfony bundle providing light UX for collection
Symfony UX Form collection is a Symfony bundle providing JavaScript-powered "add" and "remove"
buttons to your `CollectionType` fields.

It'd be GREAT to have a little screenshot :)


## Use predefined theme

You need to select the right theme from the one you are using:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You need to select the right theme from the one you are using:
First, choose a form theme to use for styling your collection type:


[Check the Symfony doc](https://symfony.com/doc/4.4/form/form_themes.html) for the different ways to set themes in Symfony.

## Use a custom form theme
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this section down, below Usage. And we can call it: Customizing how the Field Renders.

{{ form_row(comments) }}
{# ... #}
{{ form_end(form) }}
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somewhere, we need to mention that, in order for this to work, they likely need orphanRemoval and cascade=['persist'] on their entities. This is what my field looks like:

#[ORM\OneToMany(mappedBy: 'directory', targetEntity: File::class, orphanRemoval: true, cascade: ['persist'])]
private $files;

{
$builder
// ...
->add('comments', UXCollectionType::class, [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be as helpful as possible, I think we need to show the user a simple CommentType class. And then, use that here with 'entry_type' => CommentType::class`.

Overall, this is how my example looks locally - I think these options are helpful to all show!

'allow_add' => true,
'allow_delete' => true,
'entry_type' => FileType::class,
// ideally UXCollectionType can set this for us
'by_reference' => false,
'entry_options' => [
    // hides the "0", "1", "2" labels on the embedded forms
    'label' => false,
],
'button_add_options' => [
    'label' => '<span class="fa fa-plus"></span>',
    'label_html' => true,
    'class' => 'btn btn-secondary btn-sm'
],
'button_delete_options' => [
    'label' => '<span class="fa fa-times"></span>',
    'label_html' => true,
    'class' => 'btn btn-danger btn-sm'
],

@@ -0,0 +1,52 @@
{%- block button_add -%}
{%- set attrDataAction = (attr['data-action']|default('') ~ ' ' ~ controllerName ~ '#add')|trim -%}
<button data-action="{{ attrDataAction }}"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, this is interesting. To accomplish this, I think it would be very similar to how prototype is done, which is sort of a "fake field" that is added to the form... without being a real field.

You can see how the prototype is created in buildForm()... but not actually added to the field: https://github.com/symfony/symfony/blob/a05702965e9fc0de7ce77d1641e772e2fbfe9911/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php#L39-L40

Later, it's added as a view variable: https://github.com/symfony/symfony/blob/a05702965e9fc0de7ce77d1641e772e2fbfe9911/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php#L91-L101

It would be interesting to do the same thing with both buttons. We would pass button_add_options directly to the $builder->create() call - e.g. how prototype_options are passed here: https://github.com/symfony/symfony/blob/a05702965e9fc0de7ce77d1641e772e2fbfe9911/src/Symfony/Component/Form/Extension/Core/Type/CollectionType.php#L33

{% macro commentFormRow(commentForm) %}
<div
class="col-4"
data-symfony--ux-form-collection--collection-target="entry"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should show {{ stimulus_controller() }} here, and {{ stimulus_action() }} and `{{ stimulus_target() }} in the other places.

>
{%- if form is rootform -%}
{{ form_errors(form) }}
{%- endif -%}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this for?

if (this.allowAddValue) {
// Add button Add
const buttonAdd = this._textToNode(this.buttonAddValue);
this.element.prepend(buttonAdd);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should actually be added to the bottom. In the future, we may make it configurable, bottom seems like a better default to me.

@weaverryan
Copy link
Member

Friendly ping - let us know if and how we can help, or if anything is unclear :)

@stakovicz
Copy link
Author

stakovicz commented Jun 20, 2022

Good evening Ryan,

Thanks for the reminder, everything is clear.
However, at the moment, I can't find time for this project.

If you wish, you can continue.

Best regards,

@weaverryan
Copy link
Member

Totally understandable :). If anyone else wants to continue this PR, please feel free to take this code, build on top of it, and submit a new PR. I would like it to be finished - it's a very nice idea.

@alexander-schranz
Copy link
Contributor

alexander-schranz commented Jul 18, 2022

I'm currently trying based on this implement and the feedback trying to implemented a new variation of the UXCollectionType which does not requiring even .html.twig to solve also the comment about the overwrite the collection_widget block.

I'm nearly there to remove all .html.twig and set all required attributes and even the buttons inside the form types. I sadly has one thing I could not yet solve and that is I need to wrap the entry_type to add the remove button there, for this I'm doing the following in the UXCollectionType:

$entryTypeNormalizer = function (OptionsResolver $options, $value) {
   return UXCollectionEntryType::class; // overwrite the given entry_point with wrapped component
};

$entryOptionsNormalizer = function (OptionsResolver $options, $value) {
    return [
        'entry_type' => $options['entry_type'], // TODO get the original entry_type here
        'entry_options' => $value, // forwards options
    ];
};

$resolver->addNormalizer('entry_type', $entryTypeNormalizer);
$resolver->addNormalizer('entry_options', $entryOptionsNormalizer);

The problem is I'm loosing the original given 'entry_type' option this way. Which I need to forward to my UXCollectionEntryType. Sure we could go with ux_entry_type as option but that would in my case be a bad developer experience. So is there any way we get the original value here or somebody have another idea here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Proposal: component to handle form collections