Development

Documentation/fr_FR/easy_ajax/trunk

You must first sign up to be able to contribute.

Version 4 (modified by chtito, 11 years ago)
faute d'orthographe

Cette partie de la documentation est en cours de traduction. Cela signifie qu'elle est traduite de manière soit incomplète, soit inexacte. En attendant que cette traduction soit terminée, vous pouvez consulter la version en anglais pour des informations plus fiables.

L'ajax Facile avec symfony

Vue d'ensemble

Symfony possède des helpers qui facilitent grandement la programmation Ajax. Ce tutoriel va vous montrer point par point comment créer une application symfony Ajax-powered en une minutes.

Introduction

Nous conseillerons aux véritables paresseux qui n'ont pas le courage de lire de regarder le screencast disponible en ligne qui décris exactement tous ce qui suit.

Ajouter des articles au caddie virtuel des applications communes d'e-commerce ne colle pas réellement du concept de ≪ ajouter au panier ≫, puisque cela exige de cliquer sur un bouton ≪ ajouter au panier ≫, afficher une nouvelle page (le caddie), et revenir a la boutique en cliquant sur un autre bouton.

Ajax permet de se rapprocher de ce concept, en permettant des actions dites de drag-and-drop et en affichant immédiatement un résultat a l'écran, cela sans quitter le boutique.

Nous développerons dans ce tutoriel un portage avec symfony de la demo "shoping cart" publiée par script.aculo.us en rail. Cette demo inclus le framework javascript Prototype (inclus dans symfony) et quelques scripts de script.aculo.us javascript qui représentent le noyau des helpers javascript.

Installation de l'application

D'abord, créons un projet "sfdemo", une application "app" et un module "cart" :

$ cd /home/steve
$ mkdir sfdemo
$ cd sfdemo
$ symfony init-project sfdemo
$ symfony init-app app
$ symfony init-module app cart

Configurez votre serveur web pour pouvoir accéder a cette nouvelle application (En utilisant un virtual host ou un alias, comme décrit dans le chapitre installation du serveur web de la documentation). Pour cet exemple, supposons que ce module est accessible par l'intermédiaire de localhost :

http://localhost/cart/

Le message de félicitation doit apparaître.

Votre app doit pouvoir accéder au librairies javascript de symfony. Si ça ne fonctionne pas, vérifiez si vous pouvez y accéder a l'aide de votre navigateur (testez http://localhost/sf/js/prototype.js par exemple). Si vous n'y arrivez pas, voici trois possibilité pour arranger le problème :

  • configurez Apache avec l'Alias suivant:

    Alias /sf /$data_dir/symfony/web/sf
    
  • créez un lien symbolique sf dans votre web directory:

    $ cd /home/steve/sfdemo/web
    $ ln -sf /$data_dir/symfony/web/sf sf
    
  • copiez les dossiers javascript dans le répertoire web/js :

    $ cd /home/steve/sfdemo/web
    $ mkdir -p sf/js
    $ cp /$data_dir/symfony/web/sf/js/*.js sf/js/
    

La page principale

D'abord, vous devez créer une liste d'articles a acheter. Pour garder le projet simple, la liste d'élément est obtenue par l'intermédiaire d'une méthode getProducts() dans la classe d'actions du module cart. Le caddie est un paramètre simple de l'objet de sfUser, assigne avec le support de paramètre d'attribut. Modifier sfdemo/app/modules/cart/actions/actions.class.php :

class cartActions extends sfActions
{
    public function executeIndex()
    {
        $this->getUser()->setAttribute('cart', array());
        $this->products = $this->getProducts();
    }

    private function getProducts()
    {
        return array('iPod black', 'iMac', 'iMac RC', 'iPod');
    }
}

La page principale du module "cart" contiendra la liste des articles, et une zone pour y déposer les articles a ajouter au panier. Cette zone représente notre caddie. Ouvrons le template sfdemo/app/modules/cart/templates/indexSuccess.php et inscrivons-y:

<h1>symfony Apple store demo</h1>

<div id="shopping_cart">

    <h2>Products:</h2>

    <div id="product_list">
        <?php foreach($products as $id => $title): ?>
        <?php echo image_tag('product'.$id, array(
        'id'    => 'product_'.$id,
    'class' => 'products'
        )) ?>
        <?php endforeach ?>
    </div>

<h2>Cart:</h2>

    <div id="cart" class="cart">
    </div>

</div>

Vous pouvez voir que des produits sont montres par des images. Utilisez les images disponibles dans cette archive, et les placez les dans le répertoire sfdemo/web/images. Entre autre, une partie des CSS a ete faite a votre place, on vous recommande donc d'uploader ce stylesheet dans sfdemo/web/css/ et d'ajouter un fichier view.yml dans sfdemo/app/modules/cart/config/ avec le contenu suivant :

all:
    stylesheets:  [cart]

Admirez le résultat :

http://localhost/cart/

Focus sur le caddie

Le contenu du caddie changera a mesure ou vous y placerez des articles. Cela signifie que le contenu du caddie dans le template doit être un fichier indépendant. Utilisons le helper include_partial() pour cela. Les articles du caddie seront stocke dans des Divs avec la propriété de style float:left, un autre div, avec la propriété de style clear:both sera donc utile après le div conteneur. Changeons donc le template indexSuccess.php :

<h2>Cart:</h2>

<div id="cart" class="cart">
    <div id="items">
        <?php include_partial('cart') ?>
    </div>
    <div style="clear:both"></div>
</div>

</div>

Le helper include_partial() inclura un fichier _cart.php qu'il ira chercher dans le répertoire sfdemo/app/modules/cart/templates/ . Créez le avec le contenu suivant :

<?php foreach($sf_user->getAttribute('cart') as $product_id => $quantity): ?>
    <div>
        <?php for($i = 1; $i <= $quantity; $i++): ?>
            <?php echo image_tag('product'.$product_id, array(
            'class' => 'cart-items',
            'id'    => 'item_'.$product_id.'_'.$i,
            'style' => 'position:relative'
            )) ?>
        <?php endfor ?>
        (<?php echo $quantity ?> <?php echo $products[$product_id] ?>)
    </div>
<?php endforeach ?>

<?php if (!$sf_user->getAttribute('cart')): ?>
    nothing yet in your shopping cart.
<?php endif ?>

Si le caddies contient des articles, ils apparaissent sous forme d'images, autant de fois que vous avez ajoute d'articles; la quantité étant affichée après chaque série d'articles.

Jetons un nouveau coup d'œil a tout cela :

http://localhost/cart/

Bien, pas beaucoup de changement pour le moment, c'est un peu vide... C'est le moment de parler AJAX ..!

Ajout des comportement javascript

Éditez le template indexSuccess.php pour y inclure les hepers Javascript :

<?php use_helper('Javascript') ?>

Rendez les image draggable en ajoutant l'appel suivant a la fonction draggable_element du helper javascript :

<?php foreach($products as $id => $title): ?>
    <?php echo image_tag('product'.$id, array(
                         'id'    => 'product_'.$id,
                         'class' => 'products'
                         )) ?>
    <?php echo draggable_element('product_'.$id, array('revert' => true)) ?>
<?php endforeach ?>

Cela ajoute un comportement 'draggable' a chaque image de la liste d'articles. L'option "revert" fera revenir les image a leur position d'origine une fois celle ci relâchée (ou reçue par un élément de réception).

Maintenant, définissons le caddie comme élément de réception. Vous avez juste besoin de définir quelle partie du template devra être mise a jour quand l'évènement se produit, quelle action sera appelée, et quel type d'élément draggable peut y être dépose. Utilisez la fonction dropreceivingelements du helper javascript pour cela :

<?php echo drop_receiving_element('cart', array(
    'update'     => 'items',
    'url'        => 'cart/add',
    'accept'     => 'products',
)) ?>

Maintenant réessayez, et déplacez des articles dans le caddie: ça marche. Quand un élément draggable est lâche dans un élément de réception, un XMLHTTPRequest est envoyé a l'action add, et le résultat est affiche dans le div items. Le problème, c'est que l'action add du module cart n'est pas encore définie...

Définition de l'action de mise a jour

Éditez sfdemo/app/modules/cart/actions/actions.class.php pou ajouter l'action add:

public function executeAdd()
{
    $tmp = split('_', $this->getRequestParameter('id', ''));
    $product_id = $tmp[1];

    $cart = $this->getUser()->getAttribute('cart');
    if (!isset($cart[$product_id]))
    {
        $cart[$product_id] = 1;
    }
    else
    {
        ++$cart[$product_id];
    }
    $this->getUser()->setAttribute('cart', $cart);
    $this->products = $this->getProducts();      
}

Cette action cherche le paramètre envoyé par le javascript (l'id de l'article dépose) et l'ajoute au caddie.

le résultat de cette action sera le template addSuccess.php. Il s'agit d'une simple inclusion du partial _cart.php, mais cette fois, il faut passer les articles en paramètre :

<?php include_partial('cart', array('products' => $products)) ?>

Ce template ne doit pas utiliser le layout global, éditez donc le fichier view.yml dans sfdemo/app/modules/cart/config/ , et ecrivez-y:

addSuccess:
    has_layout:   off

all:
    has_layout:   on
    stylesheets:  [cart]

Essayez le: vous pouvez maintenant ajouter des articles au caddie juste en les glissant dedans.

Focus on usability

Vous pouvez arrêter maintenant, mais ce panier virtuel a un gros défaut: pendant que le caddie est mis a jour, rien ne change dans l'interface et cela peut désorienter l'utilisateur. C7est une chose récurrente dans le cadre de requêtes asynchrones: un indicateur doit être ajouter pour montrer que la demande est traitée. En plus, rien n'indique a l'utilisateur que l'article dépose est considère comme admis dans le caddie, donc un style de survol doit être défini aussi.

Pour cela, éditez le template indexSuccess.php et ajoutez y cela:

<div style="height:20px">
    <p id="indicator" style="display:none">
        <?php echo image_tag('indicator.gif') ?> updating cart...
    </p>
</div>

Enregistrez l'image 'indicator.gif' dans sfdemo/web/images/.

Maintenant, modifiez l'appel a la fonction dropreceivingelement() dans le même template pour afficher l'indicateur quand la requête est lancée et pour déclarer e style de survol:

<?php echo drop_receiving_element('cart', array(
    'update'     => 'items',
    'url'        => 'cart/add',
    'accept'     => 'products',
    'script'     => 'true',
    'hoverclass' => 'cart-active',
    'loading'    => "Element.show('indicator')",
    'complete'   => "Element.hide('indicator')"
)) ?>

Conclusion

La source complète de la demo peut être telechargée et est accéssible en ligne. Vous noterez quelques différences mineures avec le code décrit dans ce tutoriel (ajout d'une poubelle), mais les comportements principaux sont identiques.

Jusqu'à ce que la documentation complète des helpers Javascript soit disponible, vous pouvez trouver plus d'informations sur ceux-ci dans la documentation de script.aculo.us.