
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.
<?php defined( '_JEXEC' ) or die( 'Restricted access' ); jimport('joomla.application.component.controller'); class TuComponenteControllerAjax extends JController { function display() { parent::display(); } function pruebaAjax(){ $datos = null; include(JPATH_COMPONENT.DS."json.class.php"); $modelo = $this->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)
Me llamo David Noguera, tengo 23 años y soy Desarrollador/Administrador web.
Puedes encontrar algo más de información en la página
29 de abril del 2008 a las 7:43 am
Hola, interesante tu post!
Tengo unas dudas, yo estoy haciendo un reproductor de videos en joomla.
El problema es que mis videos son muy grandes y he obtado por dividirlos en partes mas pequeñas.
Queria hacerte la consulta de como podria aplicar ajax para poder cargar las diferentes partes segun la eleccion del usuario.
Yo presento la primera parte del video al cargar la plantilla, y ademas un select poniendo las partes del video pero eso carece de funcionalidad.
Espero por favor me puedas ayudar un poco.
Gracias.
18 de septiembre del 2008 a las 11:16 am
Está muy bien, de hecho están muy bien todas las notaciones que haces sobre Joomla, sirves de referencia para más de un programador ;)
Sin embargo me surge una duda… Si queremos pasar la información mediante un XML, ¿cómo hacemos para incluirle la cabecera y que JavaScript no malinterprete nuestro documento? Ya que he probado a hacerlo a “pelo”: echo … pero nada. También he probado con el $document->addCustomTag(), pero al ponerle el &no_html=1 ya no me deja usarlo.
En fin, muchas gracias de nuevo!!
4 de octubre del 2008 a las 8:17 am
Hola hidabe,
Si lo haces a “pelo” como dices, mediante echos, asegurate de poner la cabecera content-type= text/xml, ya que de lo contrario, el código javascript no interpreta el texto recibido como un documento XML.
Para hacerlo hay que poner al principio de todo la siguiente linea de código:
< ?php header('Content-Type: text/xml');?>
Espero que así te funcione.
Saludos!
14 de octubre del 2008 a las 3:17 pm
Epa muy buenas noches, epa man disculpa, pero supongo q seria mas comodo hacer una importacion de un archivo js q contiene todo el codigojavascript q escribirlo directamente… no se si se pueda pues aun no lo intento pero voy a ver y te comento.
25 de octubre del 2008 a las 6:48 pm
Hola Armando, la verdad es que si, pero lo puse todo junto para poder verlo de un vistazo, aunque a la hora de programar es más comodo importar el fichero js.
Saludos!
16 de diciembre del 2008 a las 12:49 am
Como nuestro amigo hidabe comenta en este post de joomlaspanish, a partir de la versión 1.6 de Joomla ya no se podrá usar el parametro no_html=1 y habrá que usar obligatoriamente format=raw , que por otra parte es más lógico.
Saludos
23 de diciembre del 2008 a las 9:56 am
Gracias por el aporte me funciono de maravilla, ojala y sigas compartiendo mas ejemplos, saludos que t encuentre bien = )
6 de marzo del 2009 a las 11:47 am
Hola que tal, le he estado haciendo seguimiento a tu blog con respecto a las secciones de componentes y me han parecido estupenda.
Pero me intereso mucho uno sobre los componentes con Ajax, al intentarlo cargar en mi proyecto me da un pequeño error en el archivo view.html.php, como sabrás allí se declaran las funciones “pruebaAjax()” y las demás necesarias para hacer posible el proceso asincronico.
El error que me ahorraja es de javascript y se relaciona con que no esta definida la funcion “pruebaAjax()” y supongo que mucho menos las demás.
Necesito tu ayuda para solventar este problema. Cabe mencionar que dichas funciones son agregadas al documento mediante la función” addScriptDeclaration()”.
Agradezco de antemano tu apoyo… Si es posible escríbeme al mi email
6 de marzo del 2009 a las 4:13 pm
Podrias incluir los ficheros que citas en la parte
class componenteViewcontacto extends JView
{
function display($tpl = null)
{
$document = JFactory::getDocument();
$document->addScript(JURI::base() . ‘componentes/com_componente/fichero.js’);
$document->addStyleSheet(JURI::base() . ‘componentes/com_componente/fichero.css’);
$script = ‘
var variable = “holaaaaaaaa”;’;
$estilo = “body{color:green;}”;
$document-> addScriptDeclaration ($script);
$document->addStyleDeclaration($estilo);
parent::display($tpl);
}
}
principalmente “componentes/com_componente/fichero.js” para que me sirve de ejemplo, esta muy bueno el tutorial y adelante….
6 de marzo del 2009 a las 5:30 pm
hice todo lo que pusiste y me sale esto, favor vean la pagina http://200.61.235.2/joomla1.5/index.php?option=com_prueba&view=prueba&Itemid=3 me imprime pero con el valor de undefined el name, username y email
6 de marzo del 2009 a las 5:33 pm
El codigo fuente esta en http://200.61.235.2/joomla1.5/com_prueba.tar.gz
9 de marzo del 2009 a las 12:47 pm
Uuuuufffff por fin pude dar con la solución :-). Bueno como dice el dicho el que persevera vence y una vez más he vencido jajajajaja. Gracias a dios…
27 de marzo del 2009 a las 1:15 pm
hola que tal david antes que nada quiero felicitarte por el tutorial fijate que probando tu ejemplo me sale este error Fatal error: Call to a member function _getList() on a non-object in C:\xampp\htdocs\joomla\components\com_ajax\controller.php on line 20
no se si me podrias ayudar
1 de abril del 2009 a las 7:40 am
Enhorabuena por el tutorial, me ha servido de ayuda, tan sólo un apunte, para que muestre todos los usuarios del ejemplo sería bueno quitar esta línea ya que sino sólo muestra uno:
cont.innerHTML = ”;
un saludo
14 de mayo del 2009 a las 9:47 am
Hola que tal me gustaria que me ayudaran? ya hice un componente con exito alñ igual que su modulo para mostrarlo en la pagina de joomla, pero necesito que me ayuden como hago para que el componente que se me muestra en mi pagina se refresque automaticamente a cierto tiempo, es decir a cada 5 segundo sin necesidad de refrescar toda la pagina. necesito que me ayuden es urgente he buscado la mil y una forma y no he podido hacerlo.
28 de mayo del 2009 a las 9:13 am
Hola a todos me gustaría saber si alguno de ustedes trabaja el tema de los SIG dentro de Joomla ….si no me gustaría saber si la versión de mysql de Joomla permite hacer consultas de datos espaciales y si es posible trabajar con capas (shp de Esri) dentro de Joomla
2 de julio del 2009 a las 1:42 pm
hola amigos.
quisiera pedirles el favor, si alguien ya tiene el ejercicio desarrollado que por favor me lo envíen al correo eldafe@hotmail.com. les agradecería.
15 de septiembre del 2009 a las 7:16 pm
Hola! espero incomodarlos, pero esto desarrollando un sitio para tiempos compartidos, y requiero hace un pequeño resevador con solo unos campos de captura, ejemplo# arrival day, adults, children, numero de noches y uan condicionate para noches adicionales, y que esos campos pasen a un formulario, el que pueda ayudarme se lo agradecere economicamente.
15 de septiembre del 2009 a las 11:47 pm
Hola, te felicito pero tengo una pregunta…
la función eval no trabaja con IE que puedo hacer?
16 de septiembre del 2009 a las 6:05 am
Usa Mootools o jQuery, estos frameworks son compatibles con todos los navegadores. Mootools es que el viene con Joomla por defecto, así que mejor usa ese. De todas formas el error debe de estar en otro lado, por que eval si que debería ser compatible con IE, si no me equivoco…
Un saludo!!
22 de septiembre del 2009 a las 12:34 am
Si es verdad el error es otro, lo mejor es usar una buena herramienta para verificar javascript.. ya q se hace difícil encontrar errores, recomiendo eclipse y su pluguin para js…
16 de octubre del 2009 a las 3:06 am
Buenas dias. Para empezar, muchas gracias por estos articulos donde estoy aprendiendo mucho sobre todo Joomla. Probando este en concreto, la cosa es que funciona, pero no se por que se me incluye en el resultado unos resultados que al final me dan undefined en el div. colocando un alert he visto que son unas funciones que no se de donde salen.
Por si alguien me puede ayudar y le sirve de ayuda para hacerlo, esta es la pagina donde se ejecuta http://www.indealcoy.com/index.php?option=com_indealcoy2&view=contacto&Itemid=101 Dejo puesto el alert para que lo podais ver
Gracias
23 de octubre del 2009 a las 7:50 pm
He descubierto que el fallo es del template. Al cambiarlo no hay problema. Es un conflicto con Mootools. ¿Alguna idea?
23 de octubre del 2009 a las 8:34 pm
Lo he solucionado, por si alguien usa ja_purity como template, y le sucede algo parecido a lo que yo sufria. Esta ha sido mi solucion.
for (i=0; i<resultado.length; i++) {alert(resultado[i]);
var cont = document.getElementById('contenedor');
cont.innerHTML += 'Nombre :' + resultado[i].name + '– Nombre de Usuario:' + resultado[i].username + ' — email :' + resultado[i].email + ' ' ;
en vez de
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 + ' ' ;
23 de octubre del 2009 a las 8:34 pm
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 + ‘ ‘ ;
23 de octubre del 2009 a las 8:35 pm
Cambiado por:
for (i=0; i<resultado.length; i++) {alert(resultado[i]);
var cont = document.getElementById('contenedor');
cont.innerHTML += 'Nombre :' + resultado[i].name + '– Nombre de Usuario:' + resultado[i].username + ' — email :' + resultado[i].email + ' ' ;
14 de diciembre del 2009 a las 7:35 pm
Una maravilla :)