Jérôme Tamarelle I share so I am

19mar/102

sfWidget rendu via un composant Symfony

Les formulaires créés en utilisant Symfony sont composés de widgets et de validators. Les widgets décrivent l'apparence des champs du formulaire alors que les validators décrivent leur contenu. Il est actuellement possible de choisir parmi plus de 80 types de widget différents (entre ceux de l'API et les plugins). Ils correspondent globalement à des éléments d'interface standardisés.

Si vous avez essayé de créer votre propre widget, vous avez du vous apercevoir que le rendu est fait a l'intérieur de la fonction sfWidget->render(). Ce qui suffit pour des rendus simples, mais s'avère inapproprié lorsque votre champ de formulaire se complexifie. La structure vue-contrôleur du framework n'est pas respectée.

Pour compenser ce manque, j'ai créé un widget dont le rendu se fait via un composant (component) ou une vue partielle (partial). Ce widget est destiné à faciliter la création de champ de formulaire spécifiques pouvant utiliser entre autre AJAX, le profil de l'utilisateur, l'objet sfContext et sfRequest...

Le code du widget sfWidgetFormComponent

# /lib/widget/sfWidgetFormComponent.class.php
/**
 * sfWidgetComponent is a widget rendered on a component.
 * The component will recieve this vars :
 *  * $name        The element name
 *  * $value       The value selected in this widget
 *  * $attributes  An array of HTML attributes to be merged with the default HTML attributes
 *  * $errors      An array of errors for the field
 *  * $id          An unique id
 *  * $is_hidden   Is the field hidden ?
 *
 * @package    core
 * @subpackage widget
 * @author     Jerome TAMARELLE <http://jerome.tamarelle.net/>
 */
class sfWidgetFormComponent extends sfWidgetForm
{
  /**
   * Constructor.
   *
   * Available options:
   *  * module:       The module name
   *  * component:    The component name
   *  * context:      Current context object
   *
   * @param array $options     An array of options
   * @param array $attributes  An array of default HTML attributes
   * @see sfWidgetForm
   */
  protected function configure($options = array(), $attributes = array()) {
    $this->addRequiredOption('module');
    $this->addRequiredOption('component');
    $this->addOption('is_partial', false);
    $this->addOption('context', sfContext::hasInstance() ? sfContext::getInstance() : null);
  }

  /**
   * @param  string $name        The element name
   * @param  string $value       The value selected in this widget
   * @param  array  $attributes  An array of HTML attributes to be merged with the default HTML attributes
   * @param  array  $errors      An array of errors for the field
   * @return string The rendered component
   * @see sfWidgetForm
   */
  public function render($name, $value = null, $attributes = array(), $errors = array()) {
    try {
      $this->getOption('context')->getConfiguration()->loadHelpers('Partial');
    } catch (Exception $e) {
      throw new Exception('sfWidgetFormComponent requires &quot;context&quot; option to be an instance of sfContext.');
    }

    $vars = array(
      'name'        => $name,
      'value'       => $value,
      'attributes'  => $attributes,
      'errors'      => $errors,
      'id'          => $this->generateId($name),
      'is_hidden'   => $this->getOption('is_hidden'),
    );

    if($this->getOption('is_partial')) {
      return get_partial($this->getOption('module').'/'.$this->getOption('component'), $vars);
    } else {
      return get_component($this->getOption('module'), $this->getOption('component'), $vars);
    }
  }
}

Utilisation

sfWidgetFormComponent est un widget comme les autres ! Pour l'utiliser il suffit de l'ajouter à votre formulaire dans la fonction configure() de celui-ci.

# /lib/form/MyModelForm.class.php
class MyModelForm extends BaseMyModelForm {
  public function configure() {
    $this->setWidget('field',
      new sfWidgetFormComponent(array(
                      'module'=>'ajax',
                      'component'=>'myModelWidget'
    )));
  }
}

Options du widget

Option Valeur par défaut Description
module (Obligatoire) Nom du module
component (Obligatoire) Nom du composant ou de la vue partielle
is_partial false Indique s'il s'agit d'un composant ou d'une vue partielle
context sfContext::getInstance() Contexte d'exécution (pas besoin de le modifier)

Variables transmises au component/partial

Variable Type Description
$name string Nom du champ contenant la valeur
$value string/array Valeur par défaut
$attributes array Liste d'attributs HTML
$errors array Liste des erreurs fournies par le validator
$id string Identifiant unique
$is_hidden boolean Indique si le champ doit être masqué

Il ne vous reste plus qu'à créer le composant qui conviendra le mieux à votre besoin !

Voir aussi

Commentaires (2) Trackbacks (0)
  1. Hé ben piting, je bataille pour intégrer le javascript de CKFinder depuis 2 jours, ce widget me sauve la vie : )
    Par contre, il me semble qu’il y a une petite erreur :
    ligne 32 : remplacer $this->addRequiredOption(‘partial’);
    par $this->addRequiredOption(‘component’);

    ou bien changer l’appel du widget par

    new sfWidgetFormComponent(array(
    ‘module’=>’ajax’,
    ‘partial’=>’myModelWidget’ ));

    Très bon code en totu cas, merci !!

  2. Content de t’avoir rendu service Baptiste.
    Merci pour la correction, j’ai modifié mon code en conséquence.


Laisser un commentaire


Aucun trackbacks pour l'instant