2
0

Zend_Controller-ActionHelpers-AutoComplete.xml 14 KB

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