Usando AJAX en componentes de Joomla!

Es recomendable tener conocimientos de AJAX para seguir.

Mucha gente se pregunta como se puede utilizar AJAX en Joomla. A primera vista parece complicado ya que cuando hacemos un componente este siempre aparece dentro de un template, y nosotros no queremos que aparezca ese template, ya que queremos enviar documentos XML o JSON, y el template nos molesta.

Para evitar que aparezca el template tenemos las vistas Raw, que son vista que se muestran sin la envoltura del template y también podemos enviar el resultado directamente desde el task del controlador AJAX. De esta forma podemos enviar JSON o XML sin problemas.

En mi opinión Joomla! es muy productivo , y con AJAX no es una excepción, ya que su patrón MVC nos permite disponer de un controlador solamente para las peticiones AJAX en nuestro componente, que será el que gestiones los eventos asíncronos.

Por otra parte, Joomla parece estar pensado para ser usado con JSON, ya que los métodos getList del modelo y loadObjectList del objeto JDatabase devuelven listas de objetos, que son ideales para ser impresas en formato JSON y procesadas con Javascript en el cliente.

Para esto utilizaremos la clase JSON que he se encuentra en PHPClases.

Por lo tanto simplemente tenemos que hacer una consulta a la base de datos e imprimir el resultado en un vista RAW o en el task del controlador mediante la clase JSON. En la vista que hagamos la petición AJAX tendremos que añadir el código Javascript necesario para procesar la respuesta del servidor.

En este caso voy a imprimir el código directamente desde el task, ya que no veo necesario crear una vista RAW para realizar una consulta simple a la Base de Datos.

Por lo tanto creamos nuestro punto de entrada y nuestro controlador principal, ver tutorial de componentes . En el punto de entrada se especifica que si existe un parámetro en la petición con nombre controller, se ha de instanciar el controlador indicado en la petición que será un objeto que extienda de JController y, en nuestro caso,se llamará NombreComponenteControllerAjax.

getModel('manejador');

		$query = 'SELECT name, username, email FROM `jos_users`' ;
                $datos = $modelo->_getList( $query );
                if(count($datos)){
        	        $json = new JSON;
			echo  $json->serialize( $datos );
                 }else{
        	        echo "null";
                 }

    }

}
?>

Como puedes observar, hemos creado un task que hace una consulta a la base de datos, obtiene los usuarios y los imprime usando la clase JSON.

Se hace un include al fichero donde se encuentra la clase JSON, que la he ubicado en el raíz del componente.

La clase JSON necesita como parámetro un array de objetos, que es justo lo que nos devuelve el metodo _getList del Modelo. Tiene que existir un objeto model con nombre manejador, lee el tutorial de componentes si no sabes como crearlo…

Como puedes ver, no necesitamos generar un documento XML, con las ventajas que esto tiene, como problemas de parseo.

La última comprobación que se hace antes de usar el método serialize de la clase JSON, la hago debido a que el método serialize no comprueba si el array contiene algún elemento, y en caso que la consulta no devuelva ningún valor, lo que estaremos enviando a Javascript será un mensaje de error de php, por lo tanto , yo compruebo que haya algún objeto en el array y si lo hay lo serializo, si no envió null para que el array resultante de Javascript sea null y no un string con un mensaje de error.

Creo que esto en la última versión de la clase JSON que se encuentra en phpClases se ha corregido, recomiendo que os bajéis la última version , leais la documentación y probéis que funciona.

Vamos a ver ahora el código necesario para hacer una llamada asíncrona con Javascript.

Yo he puesto el código a mano, pero es recomendable usar un framework como Jquery para usar javascript, ya que aumentara nuestra productividad y crearemos código mas seguro, corto y eficiente.


defined( '_JEXEC' ) or die( 'Restricted access' );

jimport( 'joomla.application.component.view');

class TuComponenteViewcontacto extends JView
{
    function display($tpl = null)
    {

        $document	= JFactory::getDocument();
		$script = "
		function leerDatos(){
  if (oXML.readyState  == 4) {
     //alert (oXML.responseText);
	 resultado = eval('(' + oXML.responseText + ')');
	 for(id in resultado) {
		var cont = document.getElementById('contenedor');
		cont.innerHTML = '';
		cont.innerHTML += 'Nombre :' + resultado[id].name + '--  Nombre de Usuario:' + resultado[id].username  + '  --  email :' +  resultado[id].email + ' ' ;

	}
  }
}
function AJAXCrearObjeto(){
  var obj;
  if(window.XMLHttpRequest) { // no es IE
    obj = new XMLHttpRequest();
  } else { // Es IE o no tiene el objeto
     try {
       obj = new ActiveXObject('Microsoft.XMLHTTP');
    }  catch (e) {
      alert('El navegador utilizado no está soportado');
    }
  }
  return obj;
}
function pruebaAjax(){
oXML = AJAXCrearObjeto();
oXML.open('GET', 'index.php?option=com_TuComponente&controller=Ajax&no_html=1&task=pruebaAjax');
oXML.onreadystatechange = leerDatos;
oXML.send(' ');
} ";
		$document-> addScriptDeclaration ($script); 

        parent::display($tpl); //Ha de ir el ultimo!!
    }
}
?>

En el fichero view.html.php he incluido un script simple de Javascript que hace la llamada asíncrona a la URL:
index.php?option=com_TuComponente&controller=Ajax&no_html=1&task=pruebaAjax , y con la función leerDatos manejo la respuesta. El parámetro no_htm se establece a 1 para indicar a Joomla que no imprima el template, solamente la respuesta del componente.

En la respuesta únicamente recorro el array JSON y voy almacenando en el div contenedor usuario tras usuario.

Esto se puede adornar mucho y aplicar estilos css, pero solamente es un ejemplo.

Te recomiendo leer algún tutorial de ajax básico si no entiendes el código Javascript.

<button onclick="pruebaAjax();" >Prueba AJAX  en JOOMLA!</button>
<div id="contenedor">

</div>


Finalmente, en el témplate de la vista, he incluido un botón que llama a la función pruebaAjax y que hace la llamada asíncrona y un div con id igual a contenedor y que será donde muestre los usuarios con javascript.

Ya esta, como puedes ver es sencillo, una vez te has creado el controlador AJAX, lo único que tendrás que hacer es añadir los tasks apropiados y serializar la respuesta con la clase JSON. Sencillo eficiente y ordenado.

Un Saludo.

Clase JSON de phpClases
(Bajarselo y renombrarlo a json.class.php)

Compartir:
Abrir chat
¿Tienes alguna duda que podamos aclarar?