JEditable et formulaire Symfony 1.2

Comment intégrer un plugin jQuery dans un projet Symfony 1.2 ?

La réponse à cette question ne pouvant pas tenir dans le modeste blog de Lexik.fr, je vais seulement vous expliquer comment intégrer la modification d’un champ « INPUT » en ajax dans un formulaire Symfony 1.2, à l’aide du plugin jQuery JEditable.

A ce stade, je vous recommande ce lien : JEditable

Pré-requis

  • Comme d’habitude, l’éternel plugin : sfFormExtraPlugin
  • Les JS :

    • jquery-1.3.2.min.js
    • jquery.jeditable.js

Le widget

Chemin :
[votre_projet]/plugins/sfFormExtraPlugin/lib/widget/sfWidgetFormInputEditInPlace.class.php

Code source :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?php
class sfWidgetFormInputEditInPlace extends sfWidgetFormInput
{
  public $object;
  public $route;
  public function __construct($option = array(), $messages = array(), $object = null, $route = null)
  {
    parent::__construct($option, $messages);
    $this->object = $object;
    $this->route = $route;
  }
  public function configure($options = array(), $messages = array())
  {
    parent::configure($options, $messages);
  }
  public function render($name, $value = null, $attributes = array(), $errors = array())
  {    
    $prefix = $this->generateId($name);    
    return sprintf(<<<EOF
<b id="%s">%s</b>
<script type="text/javascript">
$(function() {
  $("#%s").editable(
    "%s",
    {
      indicator : 'Saving...',      
      type   : "text",
      submit : "OK",
      style  : "inherit",
      id       : 'ajaxfield_id'
  });
});
</script>
EOF
    , $prefix, $value,
      $prefix,
      url_for($this->route, $this->object, array('absolute'=>true))
   );
  }
}

Pour ce widget, j’ai créer 2 attributs.

  • object
    Cet attribut contient l’objet de la route objet Symfony.

    4
    
     public $object;
  • route
    Cet attribut contient le nom de la route objet Symfony.

    5
    
     public $route;
  • Ces attributs nous permettent de générer l’URL de la page qui va valider et éventuellement sauvegarder les données postées par le widget JQuery.

36
url_for($this->route, $this->object, array('absolute'=>true))

Maintenant que l’outil est créé, utilisons le !
Toute la suite de l’article n’est qu’un exemple d’utilisation.

Schéma

Person:
  columns:
    firstname:
      type: string(255)
    lastname:
      type: string(255)
    email:
      type: string(255)

Routing

  • show_person
    La route du formulaire.
  • save_person_eip
    Route de l’action « executeSaveEIP » qui valide et sauve les champs du modèle « Person »
# Route du formulaire
show_person:
  url:     /person/show/:id
  class:   sfDoctrineRoute
  options: { model: Person, type: object }
  param:   { module: person, action: show }
 
# Route de la page sauvant les données postées en ajax
save_person_eip:
  url:     /person/saveEIP/:id
  class:   sfDoctrineRoute
  options: { model: Person, type: object }
  param:   { module: person, action: saveEIP }
  requirements:
    id: d+
    sf_method: [post]

Actions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// L'action pour le formulaire de base
public function executeShow(sfWebRequest $request)
{
  $this->person = $this->getRoute()->getObject();
  $this->form = new PersonForm($this->person);
}
 
// L'action qui traite le post en ajax
public function executeSaveEIP(sfWebRequest $request)
{
  // Récupération de l'objet de la route
  $this->person = $this->getRoute()->getObject();
 
  // Récupération des données postées par le widget JQuery
  $id = $request->getParameter('ajaxfield_id');
  $this->value = $request->getParameter('value');
 
  // Récupération du nom du champ
  if(ereg("person_(.*)$", $id, $key))
  {
    $champ = $key[1]; 
  }
 
  // Instanciation d'un formulaire lié à notre objet
  $form = new PersonForm();
 
  // Récupération du validateur du champ
  $validator = $form->getValidator($champ);
 
  // On tente de valider le champ
  try
  {
    $cleaned = $validator->clean($this->value);
    $this->person->set($champ, $this->value);
    $this->joueur->save();
  }
  catch(sfValidatorError $e)
  {
     // Erreur lors de la validation du champ 
     // La valeur à afficher dans le template doit être la valeur actuelle de l'objet
     $this->value = $this->person->get($champ);
  }
}

Templates

  • showSuccess.php
    <h1>Edition d'une personne</h1>
    <?php echo $form['firstname']->render();?><br>
    <?php echo $form['lastname']->render();?><br>
    <?php echo $form['email']->render();?><br>
  • saveEIPSuccess.php
    <?php echo $value ?>

Formulaire

  • On construit chacun des widgets avec l’objet et le nom de la route.
  • On définit les validators.
  public function configure()
  {
    // Widgets
    $this->widgetSchema['firstname'] = new sfWidgetFormEditInPlace(array(), array(), $this->getObject(), 'save_joueur_eip');
    $this->widgetSchema['lastname'] = new sfWidgetFormEditInPlace(array(), array(), $this->getObject(), 'save_joueur_eip');
    $this->widgetSchema['email'] = new sfWidgetFormEditInPlace(array(), array(), $this->getObject(), 'save_joueur_eip');
 
    // Validators
    $this->validatorSchema['firstname'] = new sfValidatorString();
    $this->validatorSchema['lastname'] = new sfValidatorString();
    $this->validatorSchema['email'] = new sfValidatorEmail();  
  }

View.yml

[...]
default:
  javascripts:    [jquery-1.3.2.min.js, jquery.jeditable.js]
[...]

Partagez cet article