Vous êtes ici : Accueil / Développement / Symfony 1.0 / Utiliser le contrôle admin_double_list dans vos formulaires Symfony

Utiliser le contrôle admin_double_list dans vos formulaires Symfony

Par Pierre-Yves Landuré Dernière modification 08/09/2011 18:56

Le contrôle admin_double_list est un champ normallement réservé à l'admin generator de Symfony. Ce champ permet de gérer de manière élégante les relations N:N. Cet article décrit comment l'utiliser dans vos formulaires hors de l'admin generator.

Ce guide est testé sur:

  • Symfony 1.0

Dans cet article, nous établissons une relation N:N entre une table User et une table Group.

Schéma de base de données

Pour notre relation N:N, il faut une table reliant  la table User et la table Group. Nous nommons cette table UserGroup.

Syntaxe XML

Si vous utilisez le XML pour décrire votre schéma (fichier schema.xml), voici un exemple de syntaxe :

<table name="user_group" phpName="UserGroup">
    <column name="user_id" type="INTEGER" primaryKey="true" />
    <foreign-key foreignTable="user" onDelete="cascade">
       <reference local="user_id" foreign="id" />
    </foreign-key>
    <column name="group_id" type="INTEGER" primaryKey="true" />
    <foreign-key foreignTable="group" onDelete="cascade">
       <reference local="group_id" foreign="id" />
    </foreign-key>
</table>

Formulaire

Deux élément sont à modifier dans le formulaire destiné à recevoir votre "admin_double_list".

Le helper ObjectAdmin

Pour pouvoir afficher un champ "admin_double_list", vous devez faire appel au helper ObjectAdmin dans votre formulaire :

<?php use_helper('ObjectAdmin'); ?>

La balise FORM

Votre balise FORM doit contenir deux éléments obligatoire pour que votre "admin_double_list" fonctionne et renvoie des valeurs. Ces éléments sont:

  • Un Id (par exemple: 'user-edit-form').
  • Un appel à la fonction Javascript 'double_list_submit' avec l'id du formulaire en argument (par exemple: double_list_submit('user-edit-form')).

Balise FORM standard

<?php echo form_tag('user/update', array(
      'onsubmit'    => "double_list_submit('user-edit-form'); return true;",
      'id'        => 'user-edit-form',
    )
) ?>

Balise FORM Ajax

Voici un exemple de balise FORM Ajax :

<?php echo form_remote_tag(array(
      'name'      => 'edit-form',
      'update'    => 'ajax-content',
      'url'       => 'user/update',
      'before'    => "double_list_submit('user-edit-form')",
    ), array(
      'id'        => 'user-edit-form',
    )
) ?>

Le champ admin_double_list

Pour afficher le champ admin_double_list dans votre formulaire, vous pouvez utiliser le code PHP suivant :

<?php echo object_admin_double_list($user, 'getUserGroups', array(
'through_class' => 'UserGroup',
'associated' => 'groups',
'unassociated' => 'not_groups',
'associated_label' => __('Member of'),
'unassociated_label' => __('Not member of'),
)) ?>

Remarque: les classes CSS des select 'associated' et 'unassociated' sont respectivement 'sf_admin_multiple-selected' et 'sf_admin_multiple'.

Le champ admin_check_list

Pour afficher le champ admin_check_list dans votre formulaire, vous pouvez utiliser le code PHP suivant :

<?php echo object_admin_check_list($user, 'getUserGroups', array(
'through_class' => 'UserGroup',
'associated' => 'groups',
)) ?>

L'action

Dans l'action update utilisée pour sauvegarder le formulaire, vous pouvez utiliser le code suivant pour sauvegarder les saisies obtenues à l'aide de votre champ admin_double_list :

// Fetching admin_double_list values
$group_ids = $this->getRequestParameter('associated_user_groups[]', array());

// Deleting removed Groups if it is not a new object.
if($user->getId())
{
$criteria = new Criteria();
$criteria->add(UserGroupPeer::USER_ID, $user->getId(), Criteria::EQUAL);
$criteria->add(UserGroupPeer::GROUP_ID, $group_ids, Criteria::NOT_IN);
UserGroupPeer::doDelete($criteria);
}

// Fetch groups that are not already associated to the user.
$criteria = new Criteria();
$criterion = $criteria->getNewCriterion(GroupPeer::ID, $group_ids, Criteria::IN);
$sql_query = sprintf('%s NOT IN (SELECT %s FROM %s WHERE %s = %d)', GroupPeer::ID,
UserGroupPeer::GROUP_ID, UserGroupPeer::TABLE_NAME,
UserGroupPeer::USER_ID, $user->getId());
$criterion->addAnd($criteria->getNewCriterion(GroupPeer::ID, $sql_query, Criteria::CUSTOM));
$criteria->add($criterion);
$groups = GroupPeer::doSelect($criteria);

// We create the new UserGroup associations.
foreach($groups as $group)
{
$user_group = new UserGroup();
$user_group->setGroupId($group->getId());

// This is a little trick for Symfony to do all the saving in one time.
$user->addUserGroup($user_group);
}

// Save $user object and new UserGroup objects.
$user->save();

Remerciements

  • Merci à Fabien Tillon qui a effectué la majeur partie du travail de documentation pour cet article.
  • Merci aux développeurs de Symfony pour leur superbe travail.