Zend_Controller-ActionHelpers-AutoComplete.xml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 15103 -->
  3. <!-- Reviewed: no -->
  4. <sect3 id="zend.controller.actionhelpers.autocomplete">
  5. <title>AutoComplete</title>
  6. <para>
  7. Muchas bibliotecas de Javascript con AJAX ofrecen funcionalidad para
  8. proporcionar autocompletado según la cual un selectlist de resultados
  9. potencialmente concordantes se visualiza a medida que el usuario tipea.
  10. El ayudante <methodname>AutoComplete</methodname> pretende simplificar el retorno
  11. de respuestas aceptables a esos métodos.
  12. </para>
  13. <para>
  14. Dado que no todas la bibliotecas JS implementan el autocompletado de
  15. la misma manera, el ayudante <methodname>AutoComplete</methodname> ofrece algunas
  16. funcionalidades abstractas de base necesarias para muchas bibliotecas,
  17. e implementaciones concretas para distintas bibliotecas.
  18. Los tipos de datos de retorno son generalmente o bien arrays de strings
  19. JSON, array de arrays JSON (donde cada miembro del array está en un array
  20. asociativo de metadatos utilizado para crear la selectlist), o HTML.
  21. </para>
  22. <para>
  23. El uso básico para cada aplicación es el mismo:
  24. </para>
  25. <programlisting language="php"><![CDATA[
  26. class FooController extends Zend_Controller_Action
  27. {
  28. public function barAction()
  29. {
  30. // Ejecutar alguna lógica...
  31. // Codificar y enviar la respuesta;
  32. $this->_helper->autoCompleteDojo($data);
  33. // O explicitamente:
  34. $response = $this->_helper->autoCompleteDojo
  35. ->sendAutoCompletion($data);
  36. // O prepare simplemente la respuesta de autocompletado:
  37. $response = $this->_helper->autoCompleteDojo
  38. ->prepareAutoCompletion($data);
  39. }
  40. }
  41. ]]></programlisting>
  42. <para>
  43. Por defecto, el autocompletado hace lo siguiente:
  44. </para>
  45. <itemizedlist>
  46. <listitem><para>
  47. Desactiva esquemas y a ViewRenderer.
  48. </para></listitem>
  49. <listitem><para>
  50. Establece las cabeceras apropiadas para la respuesta.
  51. </para></listitem>
  52. <listitem><para>
  53. Establece el cuerpo de la respuesta con datos
  54. codificados/formateados para autocompletar.
  55. </para></listitem>
  56. <listitem><para>
  57. Envía la respuesta.
  58. </para></listitem>
  59. </itemizedlist>
  60. <para>
  61. Los métodos disponibles para el ayudante incluyen:
  62. </para>
  63. <itemizedlist>
  64. <listitem><para>
  65. <methodname>disableLayouts()</methodname> puede ser utilizada para
  66. desactivar esquemas y a ViewRenderer. Típicamente, esto se
  67. llama dentro de <methodname>prepareAutoCompletion()</methodname>.
  68. </para></listitem>
  69. <listitem><para>
  70. <methodname>encodeJson($data, $keepLayouts = false)</methodname>
  71. codificará datos a JSON, y opcionalmente habilitando o
  72. deshabilitando esquemas. Típicamente, esto se llama dentro de
  73. <methodname>prepareAutoCompletion()</methodname>.
  74. </para></listitem>
  75. <listitem><para>
  76. <methodname>prepareAutoCompletion($data, $keepLayouts = false)</methodname>
  77. se utiliza para preparar datos en el formato necesario de la
  78. respuesta para la aplicación concreta, opcionalmente los
  79. esquemas pueden habilitarse o deshabilitarse.
  80. El valor de retorno variará dependiendo de la implementación.
  81. </para></listitem>
  82. <listitem><para>
  83. <methodname>sendAutoCompletion($data, $keepLayouts = false)</methodname>
  84. se utiliza para preparar datos en el formato necesario de la
  85. respuesta para la aplicación concreta. Esta llama a
  86. <methodname>prepareAutoCompletion()</methodname>, y entonces envía la
  87. respuesta.
  88. </para></listitem>
  89. <listitem><para>
  90. <methodname>direct($data, $sendNow = true, $keepLayouts =
  91. false)</methodname> se utiliza cuando se llama al ayudante como
  92. un método del ayudante intermediario. El flag
  93. <methodname>$sendNow</methodname> se utiliza para determinar si se debe
  94. llamar a <methodname>sendAutoCompletion()</methodname> o a
  95. <methodname>prepareAutoCompletion()</methodname>, respectivamente.
  96. </para></listitem>
  97. </itemizedlist>
  98. <para>
  99. Actualmente, <methodname>AutoComplete</methodname> soporta las bibliotecas AJAX de
  100. Dojo y Scriptaculous.
  101. </para>
  102. <sect4 id="zend.controller.actionhelpers.autocomplete.dojo">
  103. <title>AutoCompletado con Dojo</title>
  104. <para>
  105. Dojo no tiene un widget de autocompletado per se, pero tiene dos
  106. widgets que pueden ejecutar AutoCompletado: ComboBox y
  107. FilteringSelect. En ambos casos, necesitan de un almacén de datos
  108. que implemente QueryReadStore; para obtener más información sobre
  109. estos temas, ver la documentación en
  110. <ulink url="http://dojotoolkit.org/book/dojo-book-0-9/part-3-programmatic-dijit-and-dojo/data-retrieval-dojo-data-0">dojo.data</ulink>
  111. </para>
  112. <para>
  113. En Zend Framework, puede pasar un simple array indexado al ayudante
  114. AutoCompleteDojo, y este regresará una adecuada respuesta JSON
  115. para su uso como almacenamiento:
  116. </para>
  117. <programlisting language="php"><![CDATA[
  118. // dentro del controlador de acción:
  119. $this->_helper->autoCompleteDojo($data);
  120. ]]></programlisting>
  121. <example id="zend.controller.actionhelpers.autocomplete.dojo.example1">
  122. <title>AutoCompletion con Dojo Usando Zend MVC</title>
  123. <para>
  124. AutoCompletion con Dojo via Zend MVC requiere varias cosas:
  125. generar un objeto form para el ComboBox en el que usted quiere
  126. AutoCompletado, un controlador de acción para prestar servicio
  127. a los resultados de AutoCompletion, creando un QueryReadStore
  128. personalizado para conectar a la acción AutoCompletion,
  129. y la generación del Javascript a utilizar en la inicializción
  130. de AutoCompletion del lado del servidor.
  131. </para>
  132. <para>
  133. En primer lugar, veamos el Javascript necesario. Dojo ofrece
  134. un marco completo para crear Javascript OOP, tal como lo hace
  135. Zend Framework para PHP. Parte de eso es la capacidad de
  136. crear pseudo-namespaces utilizando la jerarquía de directorios.
  137. Crearemos un directorio 'custom' en el mismo nivel en el cual
  138. el directorio de Dojo forma parte de la distribución Dojo.
  139. Dentro del directorio, crearemos un archivo Javascript,
  140. TestNameReadStore.js, con el siguiente contenido:
  141. </para>
  142. <programlisting language="javascript"><![CDATA[
  143. dojo.provide("custom.TestNameReadStore");
  144. dojo.declare("custom.TestNameReadStore", dojox.data.QueryReadStore, {
  145. fetch:function (request) {
  146. request.serverQuery = { test:request.query.name };
  147. return this.inherited("fetch", arguments);
  148. }
  149. });
  150. ]]></programlisting>
  151. <para>
  152. Esta clase es simplemente una extensión del propio
  153. QueryReadStore de Dojo, que es de por sí misma una clase
  154. abstracta. Simplemente definimos un método por el cual
  155. realizamos la solicitud, y se le asigna al elemento 'test'.
  156. </para>
  157. <para>
  158. A continuación, vamos a crear el elemento form para el que
  159. queremos AutoCompletion:
  160. </para>
  161. <programlisting language="php"><![CDATA[
  162. class TestController extends Zend_Controller_Action
  163. {
  164. protected $_form;
  165. public function getForm()
  166. {
  167. if (null === $this->_form) {
  168. $this->_form = new Zend_Form();
  169. $this->_form->setMethod('get')
  170. ->setAction(
  171. $this->getRequest()->getBaseUrl() . '/test/process'
  172. )
  173. ->addElements(array(
  174. 'test' => array('type' => 'text', 'options' => array(
  175. 'filters' => array('StringTrim'),
  176. 'dojoType' => array('dijit.form.ComboBox'),
  177. 'store' => 'testStore',
  178. 'autoComplete' => 'false',
  179. 'hasDownArrow' => 'true',
  180. 'label' => 'Your input:',
  181. )),
  182. 'go' => array('type' => 'submit',
  183. 'options' => array('label' => 'Go!'))
  184. ));
  185. }
  186. return $this->_form;
  187. }
  188. }
  189. ]]></programlisting>
  190. <para>
  191. Aquí, estamos simplemente creando un formulario con los métodos
  192. 'test' y 'go'. El método 'test' agrega varios atributos
  193. especiales específicos de Dojo: dojoType, store, autoComplete
  194. y hasDownArrow. El dojoType es utilizado para indicar que
  195. estamos creando un ComboBox, y que vamos a vincularlo
  196. a un almacén de datos (clave 'store') de 'testStore'
  197. -- veremos más de esto más adelante.
  198. Especificando 'autoComplete' como falso se le dice a Dojo que
  199. no seleccione automáticamente el primer acierto, sino mostrar
  200. una lista de aciertos. Por último, 'hasDownArrow' crea una
  201. flecha abajo similar a un select box para que podamos
  202. mostrar y ocultar los aciertos o concordancias.
  203. </para>
  204. <para>
  205. Vamos a añadir un método para mostrar la forma, así como un
  206. punto final para el procesamiento de AutoCompletion:
  207. </para>
  208. <programlisting language="php"><![CDATA[
  209. class TestController extends Zend_Controller_Action
  210. {
  211. // ...
  212. /**
  213. * Página final
  214. */
  215. public function indexAction()
  216. {
  217. $this->view->form = $this->getForm();
  218. }
  219. public function autocompleteAction()
  220. {
  221. if ('ajax' != $this->_getParam('format', false)) {
  222. return $this->_helper->redirector('index');
  223. }
  224. if ($this->getRequest()->isPost()) {
  225. return $this->_helper->redirector('index');
  226. }
  227. $match = trim($this->getRequest()->getQuery('test', ''));
  228. $matches = array();
  229. foreach ($this->getData() as $datum) {
  230. if (0 === strpos($datum, $match)) {
  231. $matches[] = $datum;
  232. }
  233. }
  234. $this->_helper->autoCompleteDojo($matches);
  235. }
  236. }
  237. ]]></programlisting>
  238. <para>
  239. En nuestro <methodname>autocompleteAction()</methodname> hacemos una serie
  240. de cosas. En primer lugar, esperamos a asegurarnos de que
  241. tengamos una petición post, y que existe un parámetro 'form'
  242. establecido al valor 'ajax'; esto es simplemente para ayudar a
  243. reducir preguntas espúreas a la acción.
  244. A continuación, vamos a comprobar el parámetro 'test', y
  245. compararlo contra nuestros datos. (Yo deliberadamente dejé de
  246. lado la implementación de <methodname>getData()</methodname> aquí --
  247. podría ser cualquier tipo de fuente de datos). Por último,
  248. enviamos nuestros aciertos a nuestro ayudante AutoCompletion.
  249. </para>
  250. <para>
  251. Ahora que tenemos todas las piezas en el backend, veamos lo que
  252. necesitamos para entregar en nuestro script de vista para la
  253. página final.
  254. En primer lugar, necesitamos configurar nuestro data store,
  255. luego hacer nuestro formulario, y finalmente garantizar que
  256. las biblotecas Dojo apropiadas -- incluyendo que nuestro data
  257. store personalizado -- estén cargadas.
  258. Veamos el script de vista, el cual comenta los pasos:
  259. </para>
  260. <programlisting language="php"><![CDATA[
  261. <?php // establecemos nuestro data store: ?>
  262. <div dojoType="custom.TestNameReadStore" jsId="testStore"
  263. url="<?php echo $this->baseUrl() ?>/unit-test/autocomplete/format/ajax"
  264. requestMethod="get"></div>
  265. <?php // mostramos nuestro form: ?>
  266. <?php echo $this->form ?>
  267. <?php // establecemos CSS relacionado con Dojo a cargar en HTML head: ?>
  268. <?php $this->headStyle()->captureStart() ?>
  269. @import "<?php echo $this->baseUrl()
  270. ?>/javascript/dijit/themes/tundra/tundra.css";
  271. @import "<?php echo $this->baseUrl() ?>/javascript/dojo/resources/dojo.css";
  272. <?php $this->headStyle()->captureEnd() ?>
  273. <?php // setup de javascript para cargar en HTML head, incluyendo todas las
  274. // bibliotecas Dojo requeridas: ?>
  275. <?php $this->headScript()
  276. ->setAllowArbitraryAttributes(true)
  277. ->appendFile($this->baseUrl() . '/javascript/dojo/dojo.js',
  278. 'text/javascript',
  279. array('djConfig' => 'parseOnLoad: true'))
  280. ->captureStart() ?>
  281. djConfig.usePlainJson=true;
  282. dojo.registerModulePath("custom","../custom");
  283. dojo.require("dojo.parser");
  284. dojo.require("dojox.data.QueryReadStore");
  285. dojo.require("dijit.form.ComboBox");
  286. dojo.require("custom.TestNameReadStore");
  287. <?php $this->headScript()->captureEnd()
  288. ]]></programlisting>
  289. <para>
  290. Note que las llamadas a los ayudantes de vista como headStyle
  291. y headScript; son ubicadores, que podemos suministrar a la
  292. sección 'head' del HTML de nuestro script de vista.
  293. </para>
  294. <para>
  295. Ahora tenemos todas las piezas para que el AutoCompletion
  296. de Dojo pueda trabajar.
  297. </para>
  298. </example>
  299. </sect4>
  300. <sect4 id="zend.controller.actionhelpers.autocomplete.scriptaculous">
  301. <title>AutoCompletion con Scriptaculous</title>
  302. <para>
  303. <ulink url="http://wiki.script.aculo.us/scriptaculous/show/Ajax.Autocompleter">Scriptaculous</ulink>
  304. espera una respuesta HTML en un formato específico.
  305. </para>
  306. <para>
  307. El ayudante para utilizar con esta biblioteca es
  308. 'AutoCompleteScriptaculous'. Simplemente proporcionarle un array de
  309. datos, y el ayudante creará una respuesta HTML compatible con
  310. Ajax.Autocompleter.
  311. </para>
  312. </sect4>
  313. </sect3>
  314. <!--
  315. vim:se ts=4 sw=4 et:
  316. -->