| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- <?xml version="1.0" encoding="utf-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect3 id="zend.controller.actionhelpers.autocomplete">
- <title>AutoComplete</title>
- <para>
- Beaucoup de librairies javascript <acronym>AJAX</acronym> propose une fonctionnalité dite
- d'auto-complétion. Une liste de résultats possibles est chargée au fur et à mesure que
- l'utilisateur saisit. L'aide <emphasis>AutoComplete</emphasis> est destinée à simplifier
- le retour de ces valeurs vers la librairie Javascript.
- </para>
- <para>
- Toutes les librairies JS n'implémentant pas l'auto-complétion de la même manière,
- l'aide <emphasis>AutoComplete</emphasis> propose une solution abstraite, ainsi que des
- implémentations concrètes pour certaines librairies. Les types de valeur de retour sont en
- général des tableaux de chaînes <acronym>JSON</acronym>, des tableaux de tableaux
- <acronym>JSON</acronym> (avec chaque membre étant un tableau associatif de métadonnées
- utilisées pour créer la liste de sélection), ou du <acronym>HTML</acronym>.
- </para>
- <para>L'utilisation basique ressemble à ceci :</para>
- <programlisting language="php"><![CDATA[
- class FooController extends Zend_Controller_Action
- {
- public function barAction()
- {
- // Ici du travail ....
- // Encode et envoie la réponse
- $this->_helper->autoCompleteDojo($data);
- // Ou :
- $response = $this->_helper
- ->autoCompleteDojo
- ->sendAutoCompletion($data);
- // Ou alors prépare simplement les données :
- $response = $this->_helper
- ->autoCompleteDojo
- ->prepareAutoCompletion($data);
- }
- }
- ]]></programlisting>
- <para>Par défaut, l'auto-complétion :</para>
- <itemizedlist>
- <listitem>
- <para>Désactive les layouts et le ViewRenderer.</para>
- </listitem>
- <listitem>
- <para>Affecte des en-têtes de réponse appropriés.</para>
- </listitem>
- <listitem>
- <para>
- Remplit le corps de la réponse avec les données d'auto-complétion
- encodées/formatées.
- </para>
- </listitem>
- <listitem>
- <para>Envoie la réponse.</para>
- </listitem>
- </itemizedlist>
- <para>Les méthodes disponibles sont :</para>
- <itemizedlist>
- <listitem>
- <para>
- <methodname>disableLayouts()</methodname> est utilisée pour désactiver les layouts
- et le ViewRenderer. Cette méthode est appelées par
- <methodname>prepareAutoCompletion()</methodname>.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>encodeJson($data, $keepLayouts = false)</methodname> va encoder les
- données en <acronym>JSON</acronym>. Cette méthode est appelées par
- <methodname>prepareAutoCompletion()</methodname>.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>prepareAutoCompletion($data, $keepLayouts = false)</methodname>
- prépare les données dans le format de réponse nécessaire à une implémentation
- concrète. La valeur de retour va changer en fonction de l'implémentation
- (de la librairie utilisée).
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>sendAutoCompletion($data, $keepLayouts = false)</methodname> Va appeler
- <methodname>prepareAutoCompletion()</methodname>, puis envoyer la réponse.
- </para>
- </listitem>
- <listitem>
- <para>
- <methodname>direct($data, $sendNow = true, $keepLayouts = false)</methodname> est
- une méthode utilisée par le gestionnaire d'aides (helper broker). La valeur de
- <varname>$sendNow</varname> va déterminer si c'est
- <methodname>sendAutoCompletion()</methodname> ou
- <methodname>prepareAutoCompletion()</methodname>, qui doit être appelée.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Actuellement, <emphasis>AutoComplete</emphasis> supporte les librairies
- <acronym>AJAX</acronym> Dojo et Scriptaculous.
- </para>
- <sect4 id="zend.controller.actionhelpers.autocomplete.dojo">
- <title>AutoCompletion avec Dojo</title>
- <para>
- Dojo n'a pas une fonctionnalité d'auto-complétion, mais deux :
- ComboBox et FilteringSelect. Dans les deux cas, elle demande
- une structure de données qui implémente QueryReadStore ; voyez la
- documentation de <ulink
- url="http://dojotoolkit.org/reference-guide/dojo/data.html">dojo.data</ulink>
- </para>
- <para>
- Dans Zend Framework, vous pouvez passer un simple tableau indexé à l'aide
- AutoCompleteDojo, elle retournera une réponse <acronym>JSON</acronym>
- compatible avec la structure de données Dojo :
- </para>
- <programlisting language="php"><![CDATA[
- // à l'intérieur d'une action de contrôleur :
- $this->_helper->autoCompleteDojo($data);
- ]]></programlisting>
- <example id="zend.controller.actionhelpers.autocomplete.dojo.example1">
- <title>AutoCompletion avec Dojo en utilisant MVC</title>
- <para>
- L'auto-complétion avec Dojo via <acronym>MVC</acronym> requière plusieurs choses :
- générer un objet formulaire sur le ComboBox sur lequel vous voulez de
- l'auto-complétion, un contrôleur avec une action pour servir les résultats, la
- création d'un QueryReadStore à connecter à l'action et la génération
- du javascript à utiliser pour initialiser l'auto-complétion coté serveur.
- </para>
- <para>
- Voyons le javascript nécessaire. Dojo est une librairie complète pour la création
- de javascript <acronym>OO</acronym>, un peu comme Zend Framework pour
- <acronym>PHP</acronym>. Il est possible de créer des pseudo-namespaces en utilisant
- l'arborescence des répertoires. Nous allons créer un répertoire "custom" au même
- niveau que le répertoire Dojo. A l'intérieur, nous allons créer un fichier
- javascript, <filename>TestNameReadStore.js</filename>, avec le contenu
- suivant :
- </para>
- <programlisting language="javascript"><![CDATA[
- dojo.provide("custom.TestNameReadStore");
- dojo.declare("custom.TestNameReadStore",
- dojox.data.QueryReadStore,
- {
- fetch:function (request) {
- request.serverQuery = { test:request.query.name };
- return this.inherited("fetch", arguments);
- }
- });
- ]]></programlisting>
- <para>
- Cette classe est une simple extension de QueryReadStore, qui est
- une classe abstraite. Nous définissons simplement une méthode de requête, et on lui
- assigne notre élément "test".
- </para>
- <para>
- Ensuite, créons le formulaire sur lequel nous souhaitons une auto-complétion :
- </para>
- <programlisting language="php"><![CDATA[
- class TestController extends Zend_Controller_Action
- {
- protected $_form;
- public function getForm()
- {
- if (null === $this->_form) {
- require_once 'Zend/Form.php';
- $this->_form = new Zend_Form();
- $this->_form->setMethod('get')
- ->setAction($this->getRequest()->getBaseUrl()
- . '/test/process')
- ->addElements(array(
- 'test' => array('type' => 'text', 'options' => array(
- 'filters' => array('StringTrim'),
- 'dojoType' => array('dijit.form.ComboBox'),
- 'store' => 'testStore',
- 'autoComplete' => 'false',
- 'hasDownArrow' => 'true',
- 'label' => 'Your input:',
- )),
- 'go' => array('type' => 'submit',
- 'options' => array('label' => 'Go!'))
- ));
- }
- return $this->_form;
- }
- }
- ]]></programlisting>
- <para>
- Ici, nous créons simplement un formulaire avec des méthodes "test" et "go".
- La méthode "test" ajoute plusieurs attributs Dojo spéciaux : dojoType,
- store, autoComplete, et hasDownArrow.
- dojoType est utilisé pour indiquer la création d'une
- ComboBox, et nous allons la relier au conteneur de données
- ("store") de "testStore". Mettre
- "autoComplete" à <constant>FALSE</constant> dit à Dojo de ne pas sélectionner
- automatiquement la première valeur, mais de plutôt montrer une liste de valeurs
- possibles. Enfin, "hasDownArrow" crée une flèche bas comme sur les
- select box.
- </para>
- <para>
- Ajoutons une méthode pour afficher le formulaire, et une entrée pour traiter
- l'auto-complétion :
- </para>
- <programlisting language="php"><![CDATA[
- class TestController extends Zend_Controller_Action
- {
- // ...
- /**
- * Landing page
- */
- public function indexAction()
- {
- $this->view->form = $this->getForm();
- }
- public function autocompleteAction()
- {
- if ('ajax' != $this->_getParam('format', false)) {
- return $this->_helper->redirector('index');
- }
- if ($this->getRequest()->isPost()) {
- return $this->_helper->redirector('index');
- }
- $match = trim($this->getRequest()->getQuery('test', ''));
- $matches = array();
- foreach ($this->getData() as $datum) {
- if (0 === strpos($datum, $match)) {
- $matches[] = $datum;
- }
- }
- $this->_helper->autoCompleteDojo($matches);
- }
- }
- ]]></programlisting>
- <para>
- Dans <methodname>autocompleteAction()</methodname>, nous vérifions que nous avons
- bien une requête post, et un paramètre "format" avec la valeur
- "ajax". Ensuite, nous vérifions la présence d'un paramètre
- "test", et le comparons avec nos données. (<methodname>getData()</methodname>
- retourne des données quelconques). Enfin, nous envoyons nos résultats à notre aide
- AutoCompletion.
- </para>
- <para>
- Voyons maintenant notre script de vue. Nous devons configurer notre entrepôt
- de données, puis rendre le formulaire, et s'assurer que les librairies Dojo
- appropriées sont bien chargées (ainsi que notre entrepôt). Voici le script de vue
- :
- </para>
- <programlisting language="php"><![CDATA[
- <?php // configuration de l'entrepôt de données : ?>
- <div dojoType="custom.TestNameReadStore" jsId="testStore"
- url="<?php echo $this->baseUrl() ?>/unit-test/autocomplete/format/ajax"
- requestMethod="get"></div>
- <?php // rendu du formulaire : ?>
- <?php echo $this->form ?>
- <?php // configuration des CSS de Dojo dans le head HTML : ?>
- <?php $this->headStyle()->captureStart() ?>
- @import "<?php echo $this->baseUrl()
- ?>/javascript/dijit/themes/tundra/tundra.css";
- @import "<?php echo $this->baseUrl() ?>/javascript/dojo/resources/dojo.css";
- <?php $this->headStyle()->captureEnd() ?>
- <?php // configuration de javascript pour charger
- // les librairies Dojo dans le head HTML : ?>
- <?php $this->headScript()
- ->setAllowArbitraryAttributes(true)
- ->appendFile($this->baseUrl() . '/javascript/dojo/dojo.js',
- 'text/javascript',
- array('djConfig' => 'parseOnLoad: true'))
- ->captureStart() ?>
- djConfig.usePlainJson=true;
- dojo.registerModulePath("custom","../custom");
- dojo.require("dojo.parser");
- dojo.require("dojox.data.QueryReadStore");
- dojo.require("dijit.form.ComboBox");
- dojo.require("custom.TestNameReadStore");
- <?php $this->headScript()->captureEnd() ?>
- ]]></programlisting>
- <para>
- Notez les appels aux aides de vue comme headStyle et headScript ; celles-ci
- sont des emplacements réservés, que nous pouvons ensuite utiliser pour effectuer
- le rendu dans la section "head" du <acronym>HTML</acronym> de votre script de
- layout.
- </para>
- <para>Nous pouvons dès lors faire fonctionner l'auto-complétion Dojo.</para>
- </example>
- </sect4>
- <sect4 id="zend.controller.actionhelpers.autocomplete.scriptaculous">
- <title>AutoCompletion avec Scriptaculous</title>
- <para>
- <ulink
- url="http://wiki.script.aculo.us/scriptaculous/show/Ajax.Autocompleter">Scriptaculous</ulink>
- attend une réponse <acronym>HTML</acronym> dans un format spécifique.
- </para>
- <para>
- Utilisez l'aide "AutoCompleteScriptaculous". Passez lui un tableau
- de données et l'aide créera une réponse <acronym>HTML</acronym> compatible avec
- "Ajax.Autocompleter".
- </para>
- </sect4>
- </sect3>
|