viernes 9 de noviembre de 2007

JSON, contenidos dinamicos en tu web

¿Has intentado utilizar AJAX pero te parece muy complicado o tal vez sus librerías las encuentras muy pesadas de cargar? JSON es su hermano pequeño, y aunque es anterior en el tiempo es más que suficiente para la mayoría de aplicaciones web y es mucho más sencillo de utilizar. Veamos un sencillo pero operativo ejemplo a continuación, que tú podrás cambiar a tu medida, y además por lo que he probado funciona perfectamente en IE (Internet Explorer 6) y en FF (FireFox 2).

No ha sido una tarea fácil conseguir que este código funcionara. Me he pasado horas y horas buscando documentación oficial de los objetos utilizados, he consultado en foros, etc... y por fin, después de copiar y pegar de aquí y de allá, parece que el esfuerzo se concretó en algo operativo y multiplataforma ;)

Nuestro ejemplo consta de 4 archivos:


  • index.htm. Es el documento HTML que verá el visitante en el navegador y el que irá haciendo las llamadas al servidor SIN NECESIDAD DE RECARGARSE LA PÁGINA.
  • json_1.php. Es el archivo PHP al que llamará index.htm cuando necesite nuevos datos.
  • funciones.php. Contiene dos funciones en PHP necesarias para preparar los datos que quiera enviar json_1.php a index.htm.
  • smile.gif. Es una imagen que utilizaremos de ejemplo, para comprobar que con JSON podemos trabajar dinámicamente en nuestras aplicaciones web con texto y con imágenes.
Antes de mostraros el código, deciros que como veréis, es muy claro qué debéis adaptar a vuestro caso, y que las posibilidades son ilimitadas utilizando estas pocas funciones. Lo que más problemas me dió fue -como sucede a menudo- que funcionase todo bien en IE y en FF. Cuando me iba en uno no me iba en el otro... en fin... parece que ahora ya sí. Bueno, al menos hasta que alguno de esos dos navegadores vuelva a cambiar ("mutar" ?).

Para hacer funcionar el ejemplo, debéis poner los 4 archivos en una misma carpeta de vuestro servidor y desde un navegador llamar al archivo index.htm. Así de sencillo. Ah, y bueno, para que lo tengáis más fácil, os dejo este enlace para que podáis descargaros un RAR con el ejemplo listo para probar ;)

También podéis ver el ejemplo funcionando. No os podéis quejar :)

index.htm

<html>
<head>
<title>.: JSON - ejemplo sencillo :.</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
</head>

<body>

<a href="javascript:remote_fill('json_1.php?color=rojo');">ROJO</a>
<a href="javascript:remote_fill('json_1.php?color=azul');">AZUL</a>
<br /><br /><br />
<span id='json_grafico'></span>
<span id='json_texto'></span>

<script>
// INTENTAR LA CREACION DE UNA CONEXION DIRECTA CON EL SERVIDOR MEDIANTE XMLHttpRequest

function createRequest() {
try {
request = new XMLHttpRequest();
} catch (trymicrosoft) {
try {
request = new ActiveXObject('Msxml2.XMLHTTP');
} catch (othermicrosoft) {
try {
request = new ActiveXObject('Microsoft.XMLHTTP');
} catch (failed) {
request = false;
}
}
}
if (!request)
alert('Su navegador no permite crear uns instancia de XMLHttpRequest, ni de Msxml2.XMLHTTP, ni de Microsoft.XMLHTTP. Esta característica es indispensable para seguir trabajando en esta aplicación web.');
}

var request = false;
createRequest();

// FUNCIONES DE TRABAJO CON EL SERVIDOR

function remote_fill(url_remote){
request = false;
createRequest();
if (!request){
alert('Su navegador no permite crear uns instancia de XMLHttpRequest, ni de Msxml2.XMLHTTP, ni de Microsoft.XMLHTTP. Esta característica es indispensable para seguir trabajando en esta aplicación web.');
return false;
}
request.onreadystatechange = handle_json;
request.open('GET', url_remote, true);
request.send(null);
}

function handle_json() {
if (request.readyState == 4) {
if (request.status == 200) {
var json_data = request.responseText;
var the_object = eval( '(' + json_data + ')' );
document.getElementById('json_grafico').innerHTML= the_object.grafico_pertinente;
document.getElementById('json_texto').innerHTML= the_object.texto_pertinente;
} else {
alert('Ha habido un problema con la URL ');
}
}
}

remote_fill('json_1.php?color=blanco');

</script>

</body>
</html>


json_1.php

<?php
if (!isset($_GET['color'])) return false;
include_once("funciones.php");

$ret = array();
switch ($_GET['color']){
case "rojo":
$ret['grafico_pertinente'] = "<img src='smile.gif' style='border:1px #ff0000 solid' />";
$ret['texto_pertinente'] = " borde rojo";
break;
case "azul":
$ret['grafico_pertinente'] = "<img src='smile.gif' style='border:1px #0000ff solid' />";
$ret['texto_pertinente'] = " borde azul";
break;
default:
$ret['grafico_pertinente'] = "<img src='smile.gif' style='border:0px #ff0000 solid' />";
$ret['texto_pertinente'] = " escoge un color para el borde, y el servidor devolverá la respuesta";
break;
}

echo php_json_encode($ret);



?>



funciones.php

<?php

// funciones JSON
function json_encode_string($in_str)
{
//$charset = "UTF-8";
$charset = "ISO-8859-1";
mb_internal_encoding($charset);
$convmap = array(0x80, 0xFFFF, 0, 0xFFFF);
$str = "";
for($i=mb_strlen($in_str)-1; $i>=0; $i--){
$mb_char = mb_substr($in_str, $i, 1);
if(mb_ereg("&#(\\d+);", mb_encode_numericentity($mb_char, $convmap, $charset), $match))
$str = sprintf("\\u%04x", $match[1]) . $str;
else
$str = $mb_char . $str;
}
return $str;
}

function php_json_encode($arr){
$json_str = "";
if(is_array($arr)){
$pure_array = true;
$array_length = count($arr);
for($i=0;$i<$array_length;$i++){
if(! isset($arr[$i])){
$pure_array = false;
break;
}
}
if($pure_array){
$json_str ="[";
$temp = array();
for($i=0;$i<$array_length;$i++)
$temp[] = sprintf("%s", php_json_encode($arr[$i]));
$json_str .= implode(",",$temp);
$json_str .="]";
}else{
$json_str ="{";
$temp = array();
foreach($arr as $key => $value)
$temp[] = sprintf("\"%s\":%s", $key, php_json_encode($value));
$json_str .= implode(",",$temp);
$json_str .="}";
}
}else{
if(is_string($arr)){
$json_str = "\"". json_encode_string($arr) . "\"";
}elseif(is_numeric($arr)){
$json_str = $arr;
}else{
$json_str = "\"". json_encode_string($arr) . "\"";
}
}
return $json_str;
}
?>