I going to set up some large forms with up to 100 fields.
Now my question is if there is some best practise about handling such forms.
Especially:
Entity relations
Form object it self
Does somebody have experience about such tasks?
Should I put all together in one entity, one form, structured with jQuery in subforms or should I group the attributes to arrays as much as possible?
Regards,
Bodo
Whereas official documentation show many examples of forms directly linked to entities, I think this is not the best approach. In rare case it's good, when your form has exactly the same fields as your entity.
Your form must represent what you get in the browser, so only html inputs/textearea/select. I usually create a formData class, like an entity, that holds validation constraints and has the same structure as the form.
You have to initialize this formData object with your persisted datas before loading the form, and after submission, you update your entities with your formData object...
I am creating some complex forms that are built from multiple entities. I create a form class for each entity and then create a composite form class that holds the various combinations of forms I need (which is in someways similar to PéCé's suggestion).
If I don't need all of the fields, that is fine because I can control which fields are rendered in the twig template. If I need fields that aren't in the form class, I can add them to the template and process the form data as appropriate. For all of this effort I get some built in validation and flexibility to reuse forms from multiple entities and bundles.
Related
I have a problem that's probably easy to fix, but I don't find the right way to do it.
I have the following situation:
I am building a web application where I use several forms. One of the forms uses and displays two Entity Framework models that have a 1:1 relation. It's one entity for all BaseData (common Data) and one entity for AdditionalData (specific Data). The form's Model is of type AdditionalData, which has a NavigationProperty of type BaseData.
When I want to save this "form" i.e. the two entities - what is the best way to do that?
Do I call two Actions seperately, like "Save(BaseData) then Save(AdditionalData)"(how?)?
Do I redirect from one Save Action to the Other one (also how?)?
Do I need to build a new Model to accomplish what I need (maybe with a special ModelBinder) or do I only need a special ModelBinder?
Can I manually invoke the ModelBinder for the "BaseData" manually from the Save Action of the AddidionalDataController?
Am I doing it completely wrong in the first place?
Thank you for any help!
I am building a very large form with multisteps and some conditional fields and cannot find a good solution for my problem.
For example if field A is "Foo" then field B is shown via Javascript and must be validated via Symfony, otherwise the field must be empty. Is there a Way to do this?
PS:
Is https://github.com/craue/CraueFormFlowBundle a good way to go for complex multistep forms and should I use groups and entities or build it without a class? Whats the best practice?
Thanks!
My solution:
I think you should use Symfony Form Events. In events you can do such custom stuff like adding errors, check values in all form, remove and add validators/fields dynamically.
More about form events flow you can read here
Here Add error to Symfony 2 form element you have question howto add error to field from event listener(In symfony 4 it is done similarly)
My opinion about craue/CraueFormFlowBundle:
I use CraueFormFlowBundle in my projects to create complicated multistep forms. It's useful Bundle and saves a lot of time. I created a lot of forms based on CraueFormFlowBundle + Doctrine entities in combination with validation groups + symfony form events - powerful and flexible solution which I can recommend
Consider the following scenario
We have a simple database that involves two entities: user and category.
For our hypothesis let's say that a user can have only a type of category and a category can be associated with n users.
Now, consider a web page where a user - say ROLE_ADMINISTRATOR - could edit user table and associate them to a different one category.
As far I know (and I'm still new to symfony in general) if I use Doctrine and symfony2 in tandem, with - let's say - annotation method, i'll have two entity (php classes).
Embedded form
I will create a form that will show the user and, for show - and persist, of course! - also his category I "choose" to follow the "embedded form" strategy.
Having said that the entity has been created, i'll have to create a form for category (suppose that into formBuilder I'll add only id attribute of the category).
After that I have to add to formBuilder of UserType class the previous form and, with "some kind of magic" the form will render (after the appropriate operations) as magic and just as magically, when i'll post it (and bind, and so on) back all the informations will be persists onto database
Data Transformers
A.K.A. trasnform an input of a form into an object and vice versa.
In that way I'll have to define a - let's say - CategorySelectorType that into his builder, will add a Class (service ?) that will do those transformations.
Now we define the data transformer itself that will implement the DataTransofmerInterface (with his method and so on...)
The next step will be register that entity into services and add into UserType the form that will use this service.
So I don't understand any "strong" difference between those two metodology but "reusability" of the service. Somebody can offer me a different point of view and explain me the differences, if any?
A data transformer does not replace a embedded form, it rather enhances forms and wraps data transformation nicely.
The first sentence on the cookbook page about Data Transformers sums it up nicely:
You'll often find the need to transform the data the user entered in a
form into something else for use in your program.
In your example above, you could add a drop-down list of categories so the admin can select one for the given user. This would be done using a embedded form. As the category field is the id of an existing category, there is no need to transform the data.
For some reason you now want the admin to be able to enter a free text of the category. Now you need to do some tranformation of the text into the object in question. Maybe you want him to be able to either add a new or select a current category with this text field. Both is possible by using a data transformer which takes the text and searches for the category. Depending on your needs, not existing categories can be created and returned.
Another use case is when a user enters data which needs to be modified in some way before storing them. Let's say the user enters a street, house number and city but you want to store the coordinates instead.
In both cases it doesn't matter if you embed the form into another!
Could you do that in your controller? Of course. Is it a good idea to do such things in the controller? Probably not, as you have a hard time testing (while doing it in the transformer let you unit test the transformation nicely) or reusing it.
UPDATE
Of course it is possible to place the transformation code someplace else. The user object itself is not a good place, as the model should not know about the entity manager, which is needed to do the transformation.
The user type would be possible, but this means that it gets tied to the entity manager.
It all adds up to the very powerfull concept of Separation of concerns, which states that one class should only do one thing to make it maintainable, resuable, testable and so on. If you follow this concept, than it should be clear that data transformation is a thing on its own and should be threated as such. If you don't care, you may not need the transformation functionality.
Doctrine 2 integration into ZF seems to make simple things very hard and time consuming(At least for me).
I cant just give a submitted form array to doctrine to automatically map key/value pairs to doctrine entities and it gets very complicated if i have a many-to-many entity and submitted form has nested array.
In symfony, submitted form keys/values are easily and AUTOMATICALLY mapped and saved to doctrine tables. I don't know how to do that in ZF especially if I have "Many to Many" and/or "Many to One" doctrine entities and I have **nested form elements which need multi-level iteration.
I don't want to Set every entity explicitly and create every entity object manually**.
Pain would be alot less if i used ZF`s native database architecture.
I have done some coding and now its done half-automatically but is not very useful.
I think the best solution is to use PHP's Reflection API to inject/retrieve values from your entities (using smart get/set detection as well). I started a little library called ObjectSerializer to help with the process but never finished. That said, if you look at the logic contained in these two classes you might get a good idea where to start.
You should program this sort of logic into your models.
I usually add this sort of logic into my form, for example
class Application_Form_SomeModel extends Zend_Form
{
// the usual stuff
public function populateModel(\Entity\Model $model)
{
$model->setSomething($this->getValue('something'));
$subForm = $this->getSubForm('name');
$relatedModel = new \Entity\RelatedModel;
$relatedModel->setSomething($subForm->getValue('something'));
$model->getRelatedModels()->add($relatedModel);
// assuming the related model collection has cascade persist
// otherwise you'll need to pass in the entity manager to persist
// the new model
}
}
I do it this way due to the fact the form's elements are really only known to the form. This allows you to encapsulate everything to do with the form and its element names within the form without having to assume anything else knows this information.
Setup: I have a simple web app that has a handfull of forms, each on a separate page. These forms represent patient data. There is a one-to-one relationship between patient and all these forms/entities. Each form maps directly to a db table and a JPA entity, maybe not the best architecture but it works and is simple.
Question: If form/entity A and form/entity B share a common chunk of data (one of more fields), what is the best way to handle that in JPA. I.E. - If the data gets inserted via form A, I need it to show up in form B as existing data and vice versa. In other words its logical for both entities to contain that data. I believe I will have to move the common data into its own entity and define the relationships that way, but I have tried many different ways and none gets me all the way, at least with basic JPA. Can this be done through pure JPA relationships or will I have to write a bunch of code to make this happen manually. Not looking for code specifically, just the correct way to model this data. Thanks.
If the forms have separate tables with duplicate columns for the common data, then you cannot directly share the data. You will need to copy the data from one Entity to the other in your application. You could use a Embeddable to define the common data, but would still need to copy this Embeddable from one form to the other.
If you put the common data in a 3rd table, then you can share the data. Form A and Form B would define a OneToOne relationship to the common data.