La configuración de las páginas de los formularios se realiza en tres secciones: form
, edit
y new
. Todas tienen las mismas opciones de configuración y la sección form
sólo existe por si no existen las secciones edit
y new
.
12.9.1. La opción display
Al igual que en el listado, si quieres modificar el orden en el que se muestran los campos, puedes utilizar la opción display
. No obstante, como el formulario que se muestra está definido en una clase, no intentes quitar un campo porque podrían producirse errores de validación inesperados.
La opción display
de las páginas de formularios también se puede utilizar para agrupar los campos:
# apps/backend/modules/job/config/generator.yml
config:
form:
display:
Content: [category_id, type, company, logo, url, position, location, description, how_to_apply, is_public, email]
Admin: [_generated_token, is_activated, expires_at]
La configuración anterior define dos grupos (Content
y Admin
), cada uno de los cuales contiene un subconjunto de campos de formulario.
Nota Las columnas del grupo Admin
todavía no se muestran en el navegador porque han sido eliminadas en la definición del formulario. Estas columnas aparecerán en algunas secciones cuando definamos una clase propia para el formulario job
de la aplicación de administración.
El generador de la parte de administración incluye soporte para las relaciones muchos-a-muchos entre tablas de la base de datos. En el formulario para categorías, se muestra un cuadro de texto para el nombre, otro para el slug y una lista desplegable para los afiliados relacionados. Como no tiene sentido modificar esta relación en esta página, vamos a eliminarla:
// lib/form/JobeetCategoryForm.class.php
class JobeetCategoryForm extends BaseJobeetCategoryForm
{
public function configure()
{
unset($this['jobeet_category_affiliate_list']);
}
}
12.9.2. Columnas virtuales
En la opción display
del formulario, el nombre del campo _generated_token
comienza por un guión bajo (_
). Esto significa que la forma en la que se muestra por pantalla este campo se controla mediante un elemento parcial llamado _generated_token.php
.
Crea este elemento parcial con el siguiente contenido:
// apps/backend/modules/job/templates/_generated_token.php
<div class="sf_admin_form_row">
<label>Token</label>
<?php echo $form->getObject()->getToken() ?>
</div>
En este elemento parcial se puede acceder al formulario actual mediante la variable $form
y el objeto relacionado se puede obtener mediante el método getObject()
.
Nota Si quieres utilizar un componente en vez de un elemento parcial para mostrar ese campo, puedes prefijar el nombre del campo con el símbolo ~
12.9.3. La opción class
Como este formulario lo van a utilizar los administradores, hemos mostrado más información que la que incluye el formulario que utilizan los usuarios normales. Sin embargo, por el momento el formulario no muestra parte de la información porque se ha eliminado en la clase JobeetJobForm
.
Para utilizar diferentes formularios en la aplicación frontend
y en la aplicación backend
, tenemos que crear dos clases para ese formulario. Vamos a crear una clase BackendJobeetJobForm
que herede de la clase JobeetJobForm
. Como no vamos a tener los mismos campos ocultos, tenemos que refactorizar un poco la clase JobeetJobForm
para mover la instrucción unset()
a un método que sea redefinido en la clase BackendJobeetJobForm
:
// lib/form/JobeetJobForm.class.php
class JobeetJobForm extends BaseJobeetJobForm
{
public function configure()
{
$this->removeFields();
$this->validatorSchema['email'] = new sfValidatorAnd(array(
$this->validatorSchema['email'],
new sfValidatorEmail(),
));
// ...
}
protected function removeFields()
{
unset(
$this['created_at'], $this['updated_at'],
$this['expires_at'], $this['is_activated'],
$this['token']
);
}
}
// lib/form/BackendJobeetJobForm.class.php
class BackendJobeetJobForm extends JobeetJobForm
{
public function configure()
{
parent::configure();
}
protected function removeFields()
{
unset(
$this['created_at'], $this['updated_at'],
$this['token']
);
}
}
La opción class
permite redefinir la clase de formulario utilizada por el generador de la parte de administración:
# apps/backend/modules/job/config/generator.yml
config:
form:
class: BackendJobeetJobForm
Nota Como acabamos de añadir una nueva clase, no te olvides de borrar la cache.
El formulario edit
todavía tiene un pequeño inconveniente. El logotipo que se ha subido no se muestra en ninguna parte y tampoco se puede eliminar. El widget sfWidgetFormInputFileEditable
añade estas opciones de modificación a cualquier campo simple que permita adjuntar archivos:
// lib/form/BackendJobeetJobForm.class.php
class BackendJobeetJobForm extends JobeetJobForm
{
public function configure()
{
parent::configure();
$this->widgetSchema['logo'] = new sfWidgetFormInputFileEditable(array(
'label' => 'Company logo',
'file_src' => '/uploads/jobs/'.$this->getObject()->getLogo(),
'is_image' => true,
'edit_mode' => !$this->isNew(),
'template' => '<div>%file%<br />%input%<br />%delete% %delete_label%</div>',
));
$this->validatorSchema['logo_delete'] = new sfValidatorPass();
}
// ...
}
El widget sfWidgetFormInputFileEditable
utiliza diversas opciones para configurar sus características y la forma en la que se muestra:
file_src
: la ruta web del archivo subidois_image
: si valetrue
, el archivo se muestra como una imagenedit_mode
: indica si el formulario se encuentra o no en el modo de ediciónwith_delete
: indica si se muestra el checkbox que permite borrar el archivotemplate
: define la plantilla utilizada para mostrar el widget
Nota El aspecto del generador de la parte de administración se puede configurar fácilmente porque las plantillas generadas incluyen muchos atributos class
e id
. El campo logo
por ejemplo se puede modificar utilizando la clase sf_admin_form_field_logo
. Cada campo también tiene un atributo class
dependiente del tipo de campo, como por ejemplo sf_admin_text
o sf_admin_boolean
.
La opción edit_mode
utiliza el método sfPropel::isNew()
, que devuelve true
si el objeto del formulario es nuevo y false
en cualquier otro caso. Este método es muy útil cuando tienes diferentes widgets y validadores dependiendo del estado del objeto incluido.