Mostrando entradas con la etiqueta formularios. Mostrar todas las entradas
Mostrando entradas con la etiqueta formularios. Mostrar todas las entradas

sábado, 9 de noviembre de 2013

Using form inheritance in Symfony 2

During the development of a web app it's fairly common to need forms sharing most of their fields. For example we often need a "new" and an "edit" form for some of the entities in our app. Normally we only need to add or remove some fields to get the new form and we don't want to replicate code as it will make our app harder to maintain and more error-prone.

Let's say we have an Event entity and we need two forms: an EventNew form to create a new Event and another form that we will call EventEdit in order to edit an Event entity. We want our New form to have the following fields:

  • Name
  • Category
  • Subcategory
  • Datetime

On the other hand, we want the EventEdit form to have the same fields except for Datetime (for some reason we don't want the user to be able to change the Datetime of the event once it's created). In addition, we have the Edit form to have a textarea field named "description" (we didn't want to annoy the user requiring a description for the event when it's created). So the list of fields for the edit form would be as follows:
  • Name
  • Category
  • Subcategory
  • Description

We have at least two ways to solve this problem. We can create a BaseEventType class including the common fields for both forms and then inherit from it adding/removing fields as needed or we can create just two forms (the "new" one and the "edit" one) and make the EventEditType inherit from EventNewType. If you're sure you won't need more Event forms in the future you can just stick to option two. If we take option one we should create a class named BaseEventType containing all the common fields:


Now we need an EventNewType for our new event form and we'll add the datetime field. Note that we need to call to the method buildForm of parent class (BaseEventType, which we extend).


Last but not least we create our EventEditType and we already have our edit event form:

If we decided to take option 2 we should create a EventNewType including all 4 fields (name, category, subcategory, datetime). Then we would create EventEditType inheriting from EventNewType and add/remove fields as necessary:




Usando la herencia de formularios en Symfony2

Durante el desarrollo de una aplicación web en Symfony 2 es bastante común encontrarnos con la necesidad de tener varios formularios similares entre sí. Por ejemplo es muy común necesitar un formulario para crear una nueva entidad y otro para editar dicha entidad. Normalmente la diferencia entre uno y otro no es más que añadir o eliminar algunos campos y no deseamos tener que copiar prácticamente todo el código del formulario ya que eso haría nuestro código menos mantenible y nuestra aplicación más propensa a errores.

Digamos que tenemos una entidad Event y necesitamos dos formularios: uno al que llamaremos EventNew y que sirve para crear un nuevo evento y otro llamado EventEdit que servirá para editar un evento. Queremos que el formulario para crear un nuevo evento tenga los siguientes campos:

  • Name
  • Category
  • Subcategory
  • Datetime

Por otra parte queremos que el formulario de edición tenga los mismos campos excepto la fecha/hora del evento (por alguna razón no deseamos que este dato pueda cambiarse una vez creado el evento). Además queremos que nuestro formulario de edición incluya un campo description, ya que hemos decidido que en el formulario de nuevo evento no lo queremos para agilizar el proceso de creación de un nuevo evento. Así pues la lista de campos del formulario de edición sería la siguiente::
  • Name
  • Category
  • Subcategory
  • Description

Tenemos como mínimo dos maneras de resolver este problema. Podemos crear una clase llamada BaseEventType de la cual heredarán EventNewType y EventEditType, la cual contendrá los campos que son comunes a ambos formularios (nombre, categoría y subcategoría). La segunda opción es simplemente hacer que EventEditType herede de EventNewType (el cual contendrá sus 4 campos descritos anteriormente) y añadir o eliminar los campos necesarios. Probablemente la opción 1 es más adecuada de cara a ampliar en un futuro con más formularios. Si estás seguro de que solamente vas a necesitar estos dos la opción 2 es más rápida. Si escogemos la primera opción la clase BaseEventType quedaría así:


Ahora necesitamos la clase EventNewType que heredará de la Base y añade el campo datetime. Fíjate como llamamos en buildForm al método buildForm de la clase padre (BaseEventType) con el fin de heredar los campos que hemos incluido en el base:


Por último creamos la clase EventEditType:

Si optamos por la segunda opción planteada anteriormente crearíamos la clase EventNewType incluyendo los cuatro campos (name, category, subcategory, datetime). Luego crearíamos la clase EventEditType heredando de EventNewType. Eliminaríamos el campo datetime y añadiríamos el campo description empleando los metodos add y remove de FormBuilderInterface: