El tutorial Jobeet

12.9. Configuración de la página de formularios

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.

Agrupación de campos

Figura 12.13 Agrupación de campos

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 subido
  • is_image: si vale true, el archivo se muestra como una imagen
  • edit_mode: indica si el formulario se encuentra o no en el modo de edición
  • with_delete: indica si se muestra el checkbox que permite borrar el archivo
  • template: define la plantilla utilizada para mostrar el widget
Subiendo un archivo

Figura 12.14 Subiendo un archivo

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.