La plantilla _form.php
actual del módulo product
contiene el siguiente
código:
// apps/frontend/module/product/templates/_form.php
<!-- ... -->
<tbody>
<?php echo $form ?>
</tbody>
<!-- ... -->
La instrucción <?php echo $form ?>
es la forma más sencilla de mostrar un
formulario, incluso para los formularios más complejos. Aunque se trata de algo
muy útil cuando se prototipa una aplicación, se debe sustituir por tu propio
código si quieres modificar la forma en la que se muestra el formulario. Borra
esa línea de código porque se va a reemplazar en esta misma sección.
Lo más importante que hay que saber al mostrar formularios embebidos en la
vista es la organización multidimensional del array widgetSchema
que se
explicó en la sección anterior. En este ejemplo se empieza mostrando los campos
básicos name
y price
del formulario ProductForm
:
// apps/frontend/module/product/templates/_form.php
<?php echo $form['name']->renderRow() ?>
<?php echo $form['price']->renderRow() ?>
<?php echo $form->renderHiddenFields() ?>
Como su propio nombre indica, renderHiddenFields()
incluye todos los campos
ocultos del formulario.
Nota El código de las acciones se ha omitido a propósito porque no requiere de
ninguna atención especial. Puedes echar un vistazo al código del archivo
apps/frontend/modules/product/actions/actions.class.php
. Su aspecto es el de
cualquier CRUD normal y se puede generar automáticamente mediante la tarea
doctrine:generate-module
.
Como se acaba de explicar, la clase sfForm
incluye los arrays widgetSchema
y validatorSchema
que definen nuestros campos. Además, la clase sfForm
implementa la interfaz nativa de PHP 5 ArrayAccess
, lo que significa que se
puede acceder directamente a los campos de un formulario utilizando la sintaxis
de los arrays mostrada anteriormente.
Para mostrar los campos en la vista, se pueden acceder directamente invocando
el método renderRow()
. ¿Qué tipo de objeto es $form['name']
? Aunque puede
que pienses que la respuesta es el widget sfWidgetFormInputText
del campo
name
, la respuesta correcta es ligeramente diferente.
6.7.1. Mostrando cada campo de formulario con sfFormField
La clase sfForm
genera automáticamente un tercer array llamado sfFormFieldSchema
utilizando los arrays widgetSchema
y validatorSchema
definidos en cada clase
de formulario. Este array contiene un objeto especial para cada campo que actúa
como una clase de tipo helper encargada de mostrar cada campo. El objeto, de
tipo sfFormField
, es una combinación del widget y el validador de cada campo
y se crea de forma automática.
<?php echo $form['name']->renderRow() ?>
En el código anterior, $form['name']
es un objeto de tipo sfFormField
, que
incluye el método renderRow()
junto con muchas otras funciones útiles para
mostrar los campos.
6.7.2. Métodos de sfFormField
Cada objeto sfFormField
se puede emplear para mostrar fácilmente cada aspecto
del campo al que representa (por ejemplo el propio campo, su título, los
mensajes de error, etc.) A continuación se muestran algunos de los métodos más
útiles de sfFormField
. El resto de métodos los puedes consultar en la
API de Symfony 1.3.
sfFormField->render()
: muestra el campo del formulario (es decir, la etiqueta<input>
,<select>
, etc.) con su valor correcto de acuerdo al objeto del widget del campo.sfFormField->renderError()
: muestra cualquier error de validación del campo utilizando el objeto del validador del campo.sfFormField->renderRow()
: todo en uno que muestra el título, el campo de formulario, los errores y los mensajes de ayuda dentro de un contenedor de código XHTML.
Nota En realidad, cada función de visualización de la clase sfFormField
también
utiliza información de la propiedad widgetSchema
del formulario (el objeto
sfWidgetFormSchema
que incluye todos los widgets del formulario). Esta clase
ayuda en la generación de los atributos name
e id
de cada campo, genera el
título de cada campo y define el código XHTML utilizado por renderRow()
.
Otro aspecto importante es que el array formFieldSchema
siempre es idéntico
a la estructura de los arrays widgetSchema
y validatorSchema
del formulario.
El array formFieldSchema
por ejemplo del formulario ProductForm
completo
tendría la siguiente estructura, que es imprescindible para mostrar cada campo
del formulario:
formFieldSchema => array
(
[id] => sfFormField
[name] => sfFormField,
[price] => sfFormField,
[newPhotos] => array(
[0] => array(
[id] => sfFormField,
[filename] => sfFormField,
[caption] => sfFormField,
),
[1] => array(
[id] => sfFormField,
[filename] => sfFormField,
[caption] => sfFormField,
),
),
)
6.7.3. Mostrando el nuevo ProductForm
Utilizando el array superior como una especie de mapa, se pueden mostrar
fácilmente los campos del formulario ProductPhotoForm
embebido localizando
y mostrando los objetos sfFormField
adecuados:
// apps/frontend/module/product/templates/_form.php
<?php foreach ($form['newPhotos'] as $photo): ?>
<?php echo $photo['caption']->renderRow() ?>
<?php echo $photo['filename']->renderRow() ?>
<?php endforeach; ?>
El bloque de código anterior se ejecuta dos veces, una para el array de campos
de formulario 0
y otra para el array de campos de formulario 1
. Como se
observa en el diagrama anterior, los objetos asociados con cada array son
objetos de tipo sfFormField
, que se pueden mostrar como cualquier otro campo.