8000 [Form] setReadOnly and setAttribute on a Form after creation by acasademont · Pull Request #2797 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Form] setReadOnly and setAttribute on a Form after creation #2797

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
wants to merge 1 commit into from
Closed

[Form] setReadOnly and setAttribute on a Form after creation #2797

wants to merge 1 commit into from

Conversation

acasademont
Copy link
Contributor

Bug fix: no
Feature addition: yes
Backwards compatibility break: no
Symfony2 tests pass: Build Status
Fixes the following tickets: -
Todo: -

In a From EventSubscriber i can manage to get the form via $event->getForm() but i am pretty limited about what i can do with that form. If i only want to change the read_only property i can't because it's private, so i end up creating the field again with the same name and overwriting it with

$form->add($this->factory->createNamed('text', 'name', null, array('read_only' => false)));

which is a bit time consuming since i only wanted to set the read_only property of that field to false.

I must say that i found it a bit strange that there weren't any options for doing this so please, tell me if there is any powerful reason for not being able to change the read_only (or other attributes) when the form is already created.

@acasademont
Copy link
Contributor Author

Any good/bad comments on the issue?

@stof
Copy link
Member
stof commented Dec 19, 2011

@bschussek can you give your mind here ?

@Burgov
Copy link
Contributor
Burgov commented Dec 23, 2011

+1. I'm in the situation where I need to set my form to readonly depending on the data being set on it, which is impossible at the moment

@Burgov
Copy link
Contributor
Burgov commented Dec 28, 2011

Any news on this one?

@acasademont
Copy link
Contributor Author

Not that i know! Waiting for @bschussek blessings

@acasademont
Copy link
Contributor Author

@stof can i do something with this one? It's kinda frustrating, sincerely...

@acasademont
Copy link
Contributor Author

Seems like there is a lot of activity regarding #3193, so this PR should change the things from "read_only" to "disabled"

@webmozart
Copy link
Contributor

The problem about this PR is that event listeners and data mappers access the form's attributes during initialization of a form. Changing the attributes after construction leaves the form in an inconsistent state, unless you call setData() again. In simple forms, this might not seem like a problem, but for complex forms, this might lead to weird and hard-to-track bugs.

So, although I am not completely decided yet, I'm rather opposed to this change.

@acasademont
Copy link
Contributor Author

I think in that case that should be a responsability of the coder to use it wisely. I only call this from the preSetData event, so i guess there are no problems there. Is there any test case i could build to break the thing?

Or we should maybe mimic the add(FormInterface $child function that calls the dataMapper action which in turn calls the setData() if necessary, what do you think?

@Burgov
Copy link
Contributor
Burgov commented Jan 31, 2012

still +1

I'd also use this in PreSetData only. Today I ran into a situation again, were i'd want to change the form after it was build, but before the data was set:

I have a choicelist where the list of choices depends on the value being set. My only option now is to hack the choices into the view in buildViewBottomUp, while i'd actually want to do: $form->set('choice_list', new EntityChoiceList($em, $class, $choices));

@webmozart
Copy link
Contributor

@Burgov This is again an example why I'm against this change. Changing the "choice_list" attribute of a form after its initialization breaks the form and requires reconfiguration in case of expanded choice lists. This will confuse people, like it confused you already.

In your case you should create a new choice field with the new list of choices.

@acasademont
Copy link
Contributor Author

Maybe this pull request is too "open" and the problems arise when you change attributes like the 'choice_list' you mentioned. It should probably be limited to the readOnly var...

@webmozart
Copy link
Contributor

@acasademont How do you want to decide which properties to restrict it too? What if a dev adds a choice type with attributes that in theory can be changed too without problems? How will users know which attributes they can change and which they can't?

This gets way too messy IMO.

@acasademont
Copy link
Contributor Author

"read_only" attribute it's treated very different from other attributes as it has its own private variable whereas the others are stored in an array. But yes, if it doesn't make sense for any attribute it doesn't make sense for the read_only either.

The main goal of this PR is to minimize code duplicates, as now i have to have the exact same lines in my FormType and in my Form Subscribers if i want to change something on the form based on the current data. Even worse, as in the form subscriber i have to manually set the field_type of the form field, whereas in the FormType i have the type guesser available. And as you know there are some form types (collection basically) that have a lot of options and properties that it's a pain in the ass to write 2 times...with the problems that arise if i change something in my FormType and i forget to change it in the subscriber.

That should be the main goal. Maybe this is not the correct approach for solving the original problem, that's possible :)

@webmozart
Copy link
Contributor

You can minimize the duplicated code by always adding the affected field in event listeners. You can have the listener listen to PRE_BIND and PRE_SET_DATA and use an internal method for creating the field in both cases.

Furthermore, you can inject the FormFactory into your listener to make use of field guessing (see createForProperty and createBuilderForProperty).

8000

@acasademont
Copy link
Contributor Author

That would be nice, but as far as i know, it's not possible to set the position in which a field should be added, so fields created in the listener would always be at the end of the form if they have not been previously set in the FormType.

@webmozart
Copy link
Contributor

You should control the order of the fields in the template, not in the form type.

@acasademont
Copy link
Contributor Author

Sure, and i do that with some complex forms whose layout must be carefully set. But for the majority of entities it suffices with the {{ form_widget(form) }} provided by the TwigBridge and that uses the insertion order of the form type. No easy solution!

@webmozart
Copy link
Contributor

@acasademont Then what you really want is to pass the order of rendered fields to form_widget, which is a possible extension. Can you add a ticket for this?

I'm closing this PR as there wasn't really any powerful argument yet for this functionality that warrants the risks that we introduce. We can discuss how to solve the desired use cases on the ML.

@webmozart webmozart closed this Feb 2, 2012
@acasademont
Copy link
Contributor Author

Fair enough!

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

Successfully merging this pull request may close these issues.

4 participants
0