AutoComplete
Muchas bibliotecas de Javascript con AJAX ofrecen funcionalidad para
proporcionar autocompletado según la cual un selectlist de resultados
potencialmente concordantes se visualiza a medida que el usuario tipea.
El ayudante AutoComplete pretende simplificar el retorno
de respuestas aceptables a esos métodos.
Dado que no todas la bibliotecas JS implementan el autocompletado de
la misma manera, el ayudante AutoComplete ofrece algunas
funcionalidades abstractas de base necesarias para muchas bibliotecas,
e implementaciones concretas para distintas bibliotecas.
Los tipos de datos de retorno son generalmente o bien arrays de strings
JSON, array de arrays JSON (donde cada miembro del array está en un array
asociativo de metadatos utilizado para crear la selectlist), o HTML.
El uso básico para cada aplicación es el mismo:
_helper->autoCompleteDojo($data);
// O explicitamente:
$response = $this->_helper->autoCompleteDojo
->sendAutoCompletion($data);
// O prepare simplemente la respuesta de autocompletado:
$response = $this->_helper->autoCompleteDojo
->prepareAutoCompletion($data);
}
}
]]>
Por defecto, el autocompletado hace lo siguiente:
Desactiva esquemas y a ViewRenderer.
Establece las cabeceras apropiadas para la respuesta.
Establece el cuerpo de la respuesta con datos
codificados/formateados para autocompletar.
Envía la respuesta.
Los métodos disponibles para el ayudante incluyen:
disableLayouts() puede ser utilizada para
desactivar esquemas y a ViewRenderer. Típicamente, esto se
llama dentro de prepareAutoCompletion().
encodeJson($data, $keepLayouts = false)
codificará datos a JSON, y opcionalmente habilitando o
deshabilitando esquemas. Típicamente, esto se llama dentro de
prepareAutoCompletion().
prepareAutoCompletion($data, $keepLayouts = false)
se utiliza para preparar datos en el formato necesario de la
respuesta para la aplicación concreta, opcionalmente los
esquemas pueden habilitarse o deshabilitarse.
El valor de retorno variará dependiendo de la implementación.
sendAutoCompletion($data, $keepLayouts = false)
se utiliza para preparar datos en el formato necesario de la
respuesta para la aplicación concreta. Esta llama a
prepareAutoCompletion(), y entonces envía la
respuesta.
direct($data, $sendNow = true, $keepLayouts =
false) se utiliza cuando se llama al ayudante como
un método del ayudante intermediario. El flag
$sendNow se utiliza para determinar si se debe
llamar a sendAutoCompletion() o a
prepareAutoCompletion(), respectivamente.
Actualmente, AutoComplete soporta las bibliotecas AJAX de
Dojo y Scriptaculous.
AutoCompletado con Dojo
Dojo no tiene un widget de autocompletado per se, pero tiene dos
widgets que pueden ejecutar AutoCompletado: ComboBox y
FilteringSelect. En ambos casos, necesitan de un almacén de datos
que implemente QueryReadStore; para obtener más información sobre
estos temas, ver la documentación en
dojo.data
En Zend Framework, puede pasar un simple array indexado al ayudante
AutoCompleteDojo, y este regresará una adecuada respuesta JSON
para su uso como almacenamiento:
_helper->autoCompleteDojo($data);
]]>
AutoCompletion con Dojo Usando Zend MVC
AutoCompletion con Dojo via Zend MVC requiere varias cosas:
generar un objeto form para el ComboBox en el que usted quiere
AutoCompletado, un controlador de acción para prestar servicio
a los resultados de AutoCompletion, creando un QueryReadStore
personalizado para conectar a la acción AutoCompletion,
y la generación del Javascript a utilizar en la inicializción
de AutoCompletion del lado del servidor.
En primer lugar, veamos el Javascript necesario. Dojo ofrece
un marco completo para crear Javascript OOP, tal como lo hace
Zend Framework para PHP. Parte de eso es la capacidad de
crear pseudo-namespaces utilizando la jerarquía de directorios.
Crearemos un directorio 'custom' en el mismo nivel en el cual
el directorio de Dojo forma parte de la distribución Dojo.
Dentro del directorio, crearemos un archivo Javascript,
TestNameReadStore.js, con el siguiente contenido:
Esta clase es simplemente una extensión del propio
QueryReadStore de Dojo, que es de por sí misma una clase
abstracta. Simplemente definimos un método por el cual
realizamos la solicitud, y se le asigna al elemento 'test'.
A continuación, vamos a crear el elemento form para el que
queremos AutoCompletion:
_form) {
$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;
}
}
]]>
Aquí, estamos simplemente creando un formulario con los métodos
'test' y 'go'. El método 'test' agrega varios atributos
especiales específicos de Dojo: dojoType, store, autoComplete
y hasDownArrow. El dojoType es utilizado para indicar que
estamos creando un ComboBox, y que vamos a vincularlo
a un almacén de datos (clave 'store') de 'testStore'
-- veremos más de esto más adelante.
Especificando 'autoComplete' como falso se le dice a Dojo que
no seleccione automáticamente el primer acierto, sino mostrar
una lista de aciertos. Por último, 'hasDownArrow' crea una
flecha abajo similar a un select box para que podamos
mostrar y ocultar los aciertos o concordancias.
Vamos a añadir un método para mostrar la forma, así como un
punto final para el procesamiento de AutoCompletion:
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);
}
}
]]>
En nuestro autocompleteAction() hacemos una serie
de cosas. En primer lugar, esperamos a asegurarnos de que
tengamos una petición post, y que existe un parámetro 'form'
establecido al valor 'ajax'; esto es simplemente para ayudar a
reducir preguntas espúreas a la acción.
A continuación, vamos a comprobar el parámetro 'test', y
compararlo contra nuestros datos. (Yo deliberadamente dejé de
lado la implementación de getData() aquí --
podría ser cualquier tipo de fuente de datos). Por último,
enviamos nuestros aciertos a nuestro ayudante AutoCompletion.
Ahora que tenemos todas las piezas en el backend, veamos lo que
necesitamos para entregar en nuestro script de vista para la
página final.
En primer lugar, necesitamos configurar nuestro data store,
luego hacer nuestro formulario, y finalmente garantizar que
las biblotecas Dojo apropiadas -- incluyendo que nuestro data
store personalizado -- estén cargadas.
Veamos el script de vista, el cual comenta los pasos:
form ?>
headStyle()->captureStart() ?>
@import "baseUrl()
?>/javascript/dijit/themes/tundra/tundra.css";
@import "baseUrl() ?>/javascript/dojo/resources/dojo.css";
headStyle()->captureEnd() ?>
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");
headScript()->captureEnd()
]]>
Note que las llamadas a los ayudantes de vista como headStyle
y headScript; son ubicadores, que podemos suministrar a la
sección 'head' del HTML de nuestro script de vista.
Ahora tenemos todas las piezas para que el AutoCompletion
de Dojo pueda trabajar.
AutoCompletion con Scriptaculous
Scriptaculous
espera una respuesta HTML en un formato específico.
El ayudante para utilizar con esta biblioteca es
'AutoCompleteScriptaculous'. Simplemente proporcionarle un array de
datos, y el ayudante creará una respuesta HTML compatible con
Ajax.Autocompleter.